22
33const path = require ( 'node:path' ) ;
44const { inspect, inherits } = require ( 'node:util' ) ;
5- const Emitter = require ( 'events' ) ;
5+ const Emitter = require ( 'node: events' ) ;
66
77const { View } = require ( '../core' ) ;
88
99
10- let inited = false ;
10+ function ReEmitter ( ) { }
11+ ReEmitter . prototype = {
12+ emit ( type , data ) {
13+ if ( this . __interceptor ) {
14+ this . __interceptor ( type , data ) ;
15+ }
16+ return super . emit ( type , data ) ;
17+ }
18+ } ;
1119
12- let nextIndex = 0 ;
13- const takeIndex = ( ) => ( ++ nextIndex ) ;
20+ inherits ( ReEmitter , Emitter ) ;
21+ inherits ( View , ReEmitter ) ;
1422
23+
24+ let inited = false ;
25+ let nextIndex = 0 ;
1526const globalLibs = [ ] ;
1627const viewInstances = { } ;
17-
28+ let queueLoading = [ ] ;
29+ let emptyFunction = ( ) => null ;
1830let qmlCwd = process . cwd ( ) . replace ( / \\ / g, '/' ) ;
1931
32+ const takeIndex = ( ) => ( ++ nextIndex ) ;
33+
2034const parseJsonSafe = ( json ) => {
2135 try {
2236 return JSON . parse ( json ) [ 0 ] ;
@@ -26,47 +40,104 @@ const parseJsonSafe = (json) => {
2640 }
2741} ;
2842
29- inherits ( View , Emitter ) ;
30-
31- class JsView extends View {
43+ class JsView extends Emitter {
3244 constructor ( opts = { } ) {
3345 if ( ! inited ) {
3446 throw new Error ( 'Not inited. Call View.init(...) first.' ) ;
3547 }
3648
37- const width = opts . width || 512 ;
38- const height = opts . height || 512 ;
49+ super ( ) ;
3950
40- super ( width , height ) ;
51+ this . _index = takeIndex ( ) ;
52+ viewInstances [ this . _index ] = this ;
53+ this . _timeout = null ;
4154
42- this . _unload ( ) ;
55+ this . _opts = {
56+ ...opts ,
57+ width : opts . width || 512 ,
58+ height : opts . height || 512 ,
59+ silent : ! ! opts . silent ,
60+ } ;
4361
62+ this . _isLoaded = false ;
63+ this . _isFile = null ;
64+ this . _source = null ;
65+ this . _finalSource = null ;
66+ this . _width = this . _opts . width ;
67+ this . _height = this . _opts . height ;
4468 this . _textureId = null ;
69+ this . _isConstructed = false ;
4570
46- this . _width = width ;
47- this . _height = height ;
71+ // This is fake temporary plug to receive event calls before `new View` is ready
72+ this . _view = {
73+ _libs : emptyFunction ,
74+ _resize : emptyFunction ,
75+ _mouse : emptyFunction ,
76+ _keyboard : emptyFunction ,
77+ _destroy : emptyFunction ,
78+ _invoke : emptyFunction ,
79+ _set : emptyFunction ,
80+ _get : emptyFunction ,
81+ } ;
4882
49- globalLibs . forEach ( ( l ) => this . _libs ( l ) ) ;
83+ JsView . _enqueueLoad ( this ) ;
84+ }
85+
86+
87+ static _enqueueLoad ( view ) {
88+ queueLoading = [ ...queueLoading , view ] ;
89+ if ( queueLoading . length === 1 ) {
90+ view . _createView ( ) ;
91+ }
92+ }
93+
94+ static _finishLoad ( view ) {
95+ if ( view . _timeout ) {
96+ clearTimeout ( view . _timeout ) ;
97+ view . _timeout = null ;
98+ }
99+ view . _isLoading = false ;
50100
51- this . _index = takeIndex ( ) ;
52- viewInstances [ this . _index ] = this ;
101+ queueLoading = queueLoading . filter ( ( item ) => ( item !== view ) ) ;
102+ const [ next ] = queueLoading ;
103+ if ( next ) {
104+ next . _createView ( ) ;
105+ }
106+ }
107+
108+ _createView ( ) {
109+ this . _timeout = setTimeout (
110+ ( ) => {
111+ this . _timeout = null ;
112+ JsView . _finishLoad ( this ) ;
113+ } ,
114+ 5000 ,
115+ ) ;
116+
117+ this . _view = new View ( this . _width , this . _height ) ;
118+ this . _view . __interceptor = ( type , data ) => {
119+ if ( ! type . startsWith ( '_qml_' ) ) {
120+ this . emit ( type , data ) ;
121+ }
122+ } ;
123+
124+ globalLibs . forEach ( ( l ) => this . _view . _libs ( l ) ) ;
125+ this . _isConstructed = true ;
53126
54- this . _silent = ! ! opts . silent ;
55- this . on ( '_qml_error' , ( data ) => setImmediate ( ( ) => {
56- if ( ! this . _silent ) {
127+ this . _view . on ( '_qml_error' , ( data ) => setImmediate ( ( ) => {
128+ if ( ! this . _opts . silent ) {
57129 console . error ( `Qml Error: (${ data . type } )` , data . message ) ;
58130 }
59131 this . emit ( 'error' , new Error ( `${ data . type } : ${ data . message } ` ) ) ;
60132 } ) ) ;
61133
62134 // Expect FBO texture
63- this . on ( '_qml_fbo' , ( data ) => setImmediate ( ( ) => {
135+ this . _view . on ( '_qml_fbo' , ( data ) => setImmediate ( ( ) => {
64136 this . _textureId = data . texture ;
65137 this . emit ( 'reset' , this . _textureId ) ;
66138 } ) ) ;
67139
68-
69- this . on ( '_qml_load' , ( e ) => setImmediate ( ( ) => {
140+ this . _view . on ( '_qml_load' , ( e ) => setImmediate ( ( ) => {
70141 if ( e . source !== this . _finalSource ) {
71142 return ;
72143 }
@@ -76,19 +147,22 @@ class JsView extends View {
76147 }
77148
78149 if ( e . status !== 'success' ) {
150+ JsView . _finishLoad ( this ) ;
79151 return console . error ( 'Qml Error. Could not load:' , this . _source ) ;
80152 }
81153
82154 this . _isLoaded = true ;
83-
155+ JsView . _finishLoad ( this ) ;
84156 this . emit ( 'load' ) ;
85157 } ) ) ;
86158
87- this . on ( '_qml_mouse' , ( e ) => setImmediate ( ( ) => this . emit ( e . type , e ) ) ) ;
88- this . on ( '_qml_key' , ( e ) => setImmediate ( ( ) => this . emit ( e . type , e ) ) ) ;
159+ this . _view . on ( '_qml_mouse' , ( e ) => setImmediate ( ( ) => this . emit ( e . type , e ) ) ) ;
160+ this . _view . on ( '_qml_key' , ( e ) => setImmediate ( ( ) => this . emit ( e . type , e ) ) ) ;
89161
90- if ( opts . file || opts . source ) {
91- this . load ( opts ) ;
162+ if ( this . _opts . file || this . _opts . source ) {
163+ this . load ( ) ;
164+ } else {
165+ setImmediate ( ( ) => JsView . _finishLoad ( this ) ) ;
92166 }
93167 }
94168
@@ -102,14 +176,14 @@ class JsView extends View {
102176 return ;
103177 }
104178 this . _width = v ;
105- this . resize ( this . _width , this . _height ) ;
179+ this . _view . _resize ( this . _width , this . _height ) ;
106180 }
107181 set height ( v ) {
108182 if ( this . _height === v ) {
109183 return ;
110184 }
111185 this . _height = v ;
112- this . resize ( this . _width , this . _height ) ;
186+ this . _view . _resize ( this . _width , this . _height ) ;
113187 }
114188
115189 get w ( ) { return this . width ; }
@@ -129,7 +203,7 @@ class JsView extends View {
129203 }
130204 this . _width = width ;
131205 this . _height = height ;
132- this . _resize ( this . _width , this . _height ) ;
206+ this . _view . _resize ( this . _width , this . _height ) ;
133207 }
134208
135209 get textureId ( ) {
@@ -147,47 +221,60 @@ class JsView extends View {
147221 }
148222
149223 mousedown ( e ) {
150- this . _mouse ( 1 , e . button , e . buttons , e . x , e . y ) ;
224+ this . _view . _mouse ( 1 , e . button , e . buttons , e . x , e . y ) ;
151225 }
152226
153227 mouseup ( e ) {
154- this . _mouse ( 2 , e . button , e . buttons , e . x , e . y ) ;
228+ this . _view . _mouse ( 2 , e . button , e . buttons , e . x , e . y ) ;
155229 }
156230
157231
158232 mousemove ( e ) {
159- this . _mouse ( 0 , 0 , e . buttons , e . x , e . y ) ;
233+ this . _view . _mouse ( 0 , 0 , e . buttons , e . x , e . y ) ;
160234 }
161235
162236 wheel ( e ) {
163- this . _mouse ( 3 , e . wheelDelta , e . buttons , e . x , e . y ) ;
237+ this . _view . _mouse ( 3 , e . wheelDelta , e . buttons , e . x , e . y ) ;
164238 }
165239
166240 keydown ( e ) {
167- this . _keyboard ( 1 , e . which , e . charCode ) ;
241+ this . _view . _keyboard ( 1 , e . which , e . charCode ) ;
168242 }
169243
170244 keyup ( e ) {
171- this . _keyboard ( 0 , e . which , e . charCode ) ;
245+ this . _view . _keyboard ( 0 , e . which , e . charCode ) ;
172246 }
173247
174- load ( opts ) {
175- this . _unload ( ) ;
248+ load ( opts = { } ) {
249+ this . _opts = { ...this . _opts , ...opts } ;
250+
251+ // If not constructed yet, just let it cook
252+ if ( ! this . _isConstructed ) {
253+ return ;
254+ }
255+
256+ // If already loading something - ignore
257+ if ( this . _isLoading ) {
258+ return ;
259+ }
176260
177- if ( opts . file ) {
261+ this . _isLoading = true ;
262+ this . _isLoaded = false ;
263+ this . _isFile = null ;
264+ this . _source = null ;
265+ this . _finalSource = null ;
266+ this . _textureId = null ;
267+
268+ if ( this . _opts . file ) {
178269 this . _isFile = true ;
179- this . _source = opts . file ;
180- } else if ( opts . source ) {
270+ this . _source = this . _opts . file ;
271+ } else if ( this . _opts . source ) {
181272 this . _isFile = false ;
182- this . _source = opts . source ;
273+ this . _source = this . _opts . source ;
183274 } else {
184275 throw new Error ( 'To load QML, specify opts.file or opts.source.' ) ;
185276 }
186277
187- this . _loadWhenReady ( ) ;
188- }
189-
190- _loadWhenReady ( ) {
191278 if ( this . _isLoaded || this . _index === - 1 ) {
192279 return ;
193280 }
@@ -197,43 +284,39 @@ class JsView extends View {
197284 ? this . _source
198285 : `${ qmlCwd } /${ this . _source } ` ;
199286
200- this . _load ( true , this . _finalSource ) ;
287+ this . _view . _load ( true , this . _finalSource ) ;
201288 } else {
202289 this . _finalSource = this . _source ;
203- this . _load ( false , this . _source ) ;
290+ this . _view . _load ( false , this . _source ) ;
204291 }
205292 }
206293
207- _unload ( ) {
294+ destroy ( ) {
295+ this . _isLoading = false ;
208296 this . _isLoaded = false ;
209297 this . _isFile = null ;
210298 this . _source = null ;
211299 this . _finalSource = null ;
212- }
213-
214- destroy ( ) {
215- this . _unload ( ) ;
216-
217300 this . _textureId = null ;
218301
219302 if ( viewInstances [ this . _index ] ) {
220303 delete viewInstances [ this . _index ] ;
221- this . _destroy ( ) ;
304+ this . _view . _destroy ( ) ;
222305 }
223306
224307 this . _index = - 1 ;
225308 }
226309
227310 invoke ( name , key , args ) {
228- return parseJsonSafe ( this . _invoke ( name , key , JSON . stringify ( args ) ) ) ;
311+ return parseJsonSafe ( this . _view . _invoke ( name , key , JSON . stringify ( args ) ) ) ;
229312 }
230313
231314 set ( name , key , value ) {
232- this . _set ( name , key , `[${ JSON . stringify ( value ) } ]` ) ;
315+ this . _view . _set ( name , key , `[${ JSON . stringify ( value ) } ]` ) ;
233316 }
234317
235318 get ( name , key ) {
236- return parseJsonSafe ( this . _get ( name , key ) ) ;
319+ return parseJsonSafe ( this . _view . _get ( name , key ) ) ;
237320 }
238321
239322 static init ( cwd , wnd , ctx , device = 0 ) {
@@ -268,6 +351,10 @@ class JsView extends View {
268351
269352 View . _style ( name , def ) ;
270353 }
354+
355+ static update ( ) {
356+ View . update ( ) ;
357+ }
271358}
272359
273360module . exports = JsView ;
0 commit comments