@@ -9,6 +9,9 @@ import { ModeError } from '../../utils/src/errors';
99import { ContainerNode } from './VNodes/ContainerNode' ;
1010import { AtomicNode } from './VNodes/AtomicNode' ;
1111import { SeparatorNode } from './VNodes/SeparatorNode' ;
12+ import { Memory } from './Memory/Memory' ;
13+ import { makeVersionable } from './Memory/Versionable' ;
14+ import { VersionableArray } from './Memory/VersionableArray' ;
1215
1316export enum Mode {
1417 CONFIGURATION = 'configuration' ,
@@ -57,13 +60,12 @@ export class JWEditor {
5760 plugins : [ ] ,
5861 loadables : { } ,
5962 } ;
63+ memory : Memory ;
64+ memoryID = 0 ;
65+ private memoryInfo : { commandNames : string [ ] } ;
6066 selection = new VSelection ( ) ;
6167 loaders : Record < string , Loader > = { } ;
6268 private mutex = Promise . resolve ( ) ;
63- // Use a set so that when asynchronous functions are called we ensure that
64- // each command batch is waited for.
65- preventRenders : Set < Function > = new Set ( ) ;
66- enableRender = true ;
6769
6870 constructor ( ) {
6971 this . dispatcher = new Dispatcher ( this ) ;
@@ -98,9 +100,18 @@ export class JWEditor {
98100 }
99101 }
100102
103+ // create memory
104+ this . memoryInfo = makeVersionable ( { commandNames : [ ] } ) ;
105+ this . memory = new Memory ( ) ;
106+ this . memory . linkToMemory ( this . memoryInfo ) ;
107+
101108 for ( const plugin of this . plugins . values ( ) ) {
102109 await plugin . start ( ) ;
103110 }
111+
112+ // create the next memory slice (and freeze the current memory)
113+ this . memoryID ++ ;
114+ this . memory . create ( this . memoryID . toString ( ) ) ;
104115 }
105116
106117 //--------------------------------------------------------------------------
@@ -271,11 +282,16 @@ export class JWEditor {
271282 }
272283 }
273284
285+ /**
286+ * Execute arbitrary code in `callback`, then dispatch the commit event.
287+ *
288+ * @param callback
289+ */
274290 async execBatch ( callback : ( ) => Promise < void > ) : Promise < void > {
275- this . preventRenders . add ( callback ) ;
276- await callback ( ) ;
277- this . preventRenders . delete ( callback ) ;
278- await this . dispatcher . dispatchHooks ( '@batch' ) ;
291+ return this . _execBatchInMemory ( ( ) => {
292+ this . memoryInfo . commandNames . push ( '@batch' ) ;
293+ return callback ( ) ;
294+ } ) ;
279295 }
280296
281297 /**
@@ -288,23 +304,49 @@ export class JWEditor {
288304 commandName : C ,
289305 params ?: CommandParams < P , C > ,
290306 ) : Promise < void > {
291- return await this . dispatcher . dispatch ( commandName , params ) ;
307+ await this . _execBatchInMemory ( ( ) => {
308+ this . memoryInfo . commandNames . push ( commandName ) ;
309+ return this . dispatcher . dispatch ( commandName , params ) ;
310+ } ) ;
292311 }
293312
294313 /**
295- * Execute arbitrary code in `callback`, then dispatch the event.
314+ * Execute arbitrary code in `callback` in a free memory slice.
315+ * Return true if we open a memory slice.
316+ *
317+ * TODO: create memory for each plugin who use the command then use
318+ * squashInto(winnerSliceKey, winnerSliceKey, newMasterSliceKey)
319+ *
320+ * @param callback
296321 */
297- async execCustomCommand < P extends JWPlugin , C extends Commands < P > = Commands < P > > (
298- callback : ( ) => Promise < void > ,
299- ) : Promise < void > {
322+ private async _execBatchInMemory ( callback : ( ) => Promise < void > ) : Promise < void > {
323+ const isFrozen = ! this . memoryID || this . memory . isFrozen ( ) ;
324+ if ( isFrozen ) {
325+ // Switch to the next memory slice (unfreeze the memory).
326+ this . memory . switchTo ( this . memoryID . toString ( ) ) ;
327+ this . memoryInfo . commandNames = new VersionableArray < string > ( ) ;
328+ }
300329 await callback ( ) ;
301- await this . dispatcher . dispatchHooks ( '@custom' ) ;
330+ if ( isFrozen ) {
331+ // Check if it's frozen for calling execCommand inside a call of
332+ // execCommand Create the next memory slice (and freeze the
333+ // current memory).
334+ this . memoryID ++ ;
335+ this . memory . create ( this . memoryID . toString ( ) ) ;
336+ await this . dispatcher . commit ( ) ;
337+ }
302338 }
303339
304340 /**
305341 * Stop this editor instance.
306342 */
307343 async stop ( ) : Promise < void > {
344+ if ( this . memory ) {
345+ // Unfreeze the memory.
346+ this . memory . create ( 'stop' ) ;
347+ this . memory . switchTo ( 'stop' ) ;
348+ this . memory = null ;
349+ }
308350 for ( const plugin of this . plugins . values ( ) ) {
309351 await plugin . stop ( ) ;
310352 }
0 commit comments