@@ -10,6 +10,9 @@ import { ContainerNode } from './VNodes/ContainerNode';
1010import { AtomicNode } from './VNodes/AtomicNode' ;
1111import { SeparatorNode } from './VNodes/SeparatorNode' ;
1212import { ModeIdentifier , ModeDefinition , Mode } from './Mode' ;
13+ import { Memory } from './Memory/Memory' ;
14+ import { makeVersionable } from './Memory/Versionable' ;
15+ import { VersionableArray } from './Memory/VersionableArray' ;
1316
1417export enum EditorStage {
1518 CONFIGURATION = 'configuration' ,
@@ -68,6 +71,9 @@ export class JWEditor {
6871 plugins : [ ] ,
6972 loadables : { } ,
7073 } ;
74+ memory : Memory ;
75+ memoryID = 0 ;
76+ memoryInfo : { commandNames : string [ ] } ;
7177 selection = new VSelection ( this ) ;
7278 loaders : Record < string , Loader > = { } ;
7379 private mutex = Promise . resolve ( ) ;
@@ -130,9 +136,18 @@ export class JWEditor {
130136 this . setMode ( this . configuration . mode ) ;
131137 }
132138
139+ // create memory
140+ this . memoryInfo = makeVersionable ( { commandNames : [ ] } ) ;
141+ this . memory = new Memory ( ) ;
142+ this . memory . linkToMemory ( this . memoryInfo ) ;
143+
133144 for ( const plugin of this . plugins . values ( ) ) {
134145 await plugin . start ( ) ;
135146 }
147+
148+ // create the next memory slice (and freeze the current memory)
149+ this . memoryID ++ ;
150+ this . memory . create ( this . memoryID . toString ( ) ) ;
136151 }
137152
138153 //--------------------------------------------------------------------------
@@ -303,11 +318,16 @@ export class JWEditor {
303318 }
304319 }
305320
306- async execBatch ( callback : ( ) => Promise < void > ) : Promise < void > {
307- this . preventRenders . add ( callback ) ;
308- await callback ( ) ;
309- this . preventRenders . delete ( callback ) ;
310- await this . dispatcher . dispatchHooks ( '@batch' ) ;
321+ /**
322+ * Execute arbitrary code in `callback`, then dispatch the commit event.
323+ *
324+ * @param callback
325+ */
326+ async execBatch ( callback : ( ) => Promise < void > | void ) : Promise < void > {
327+ return this . _execBatchInMemory ( ( ) => {
328+ this . memoryInfo . commandNames . push ( '@batch' ) ;
329+ return callback ( ) ;
330+ } ) ;
311331 }
312332
313333 /**
@@ -320,23 +340,49 @@ export class JWEditor {
320340 commandName : C ,
321341 params ?: CommandParams < P , C > ,
322342 ) : Promise < void > {
323- return await this . dispatcher . dispatch ( commandName , params ) ;
343+ await this . _execBatchInMemory ( ( ) => {
344+ this . memoryInfo . commandNames . push ( commandName ) ;
345+ return this . dispatcher . dispatch ( commandName , params ) ;
346+ } ) ;
324347 }
325348
326349 /**
327- * Execute arbitrary code in `callback`, then dispatch the event.
350+ * Execute arbitrary code in `callback` in a free memory slice.
351+ * Return true if we open a memory slice.
352+ *
353+ * TODO: create memory for each plugin who use the command then use
354+ * squashInto(winnerSliceKey, winnerSliceKey, newMasterSliceKey)
355+ *
356+ * @param callback
328357 */
329- async execCustomCommand < P extends JWPlugin , C extends Commands < P > = Commands < P > > (
330- callback : ( ) => Promise < void > ,
331- ) : Promise < void > {
358+ private async _execBatchInMemory ( callback : ( ) => Promise < void > | void ) : Promise < void > {
359+ const isFrozen = ! this . memoryID || this . memory . isFrozen ( ) ;
360+ if ( isFrozen ) {
361+ // Switch to the next memory slice (unfreeze the memory).
362+ this . memory . switchTo ( this . memoryID . toString ( ) ) ;
363+ this . memoryInfo . commandNames = new VersionableArray ( ) ;
364+ }
332365 await callback ( ) ;
333- await this . dispatcher . dispatchHooks ( '@custom' ) ;
366+ if ( isFrozen ) {
367+ // Check if it's frozen for calling execCommand inside a call of
368+ // execCommand Create the next memory slice (and freeze the
369+ // current memory).
370+ this . memoryID ++ ;
371+ this . memory . create ( this . memoryID . toString ( ) ) ;
372+ await this . dispatcher . commit ( ) ;
373+ }
334374 }
335375
336376 /**
337377 * Stop this editor instance.
338378 */
339379 async stop ( ) : Promise < void > {
380+ if ( this . memory ) {
381+ // Unfreeze the memory.
382+ this . memory . create ( 'stop' ) ;
383+ this . memory . switchTo ( 'stop' ) ;
384+ this . memory = null ;
385+ }
340386 for ( const plugin of this . plugins . values ( ) ) {
341387 await plugin . stop ( ) ;
342388 }
0 commit comments