File size: 4,142 Bytes
8a37e0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { Logger } from 'roarr';
import type { JsonObject } from 'type-fest';
/**
* Base class for all canvas modules.
*/
export abstract class CanvasModuleBase {
/**
* The type of the module.
*/
abstract readonly type: string;
/**
* The unique identifier of the module.
*
* If the module is associated with an entity, this should be the entity's id. Otherwise, the id should be based on
* the module's type. The `getPrefixedId` utility should be used for generating ids.
*
* @example
* ```ts
* this.id = getPrefixedId(this.type);
* // this.id -> "raster_layer:aS2NREsrlz"
* ```
*/
abstract readonly id: string;
/**
* The path of the module in the canvas module tree.
*
* Modules should use the manager's `buildPath` method to set this value.
*
* @example
* ```ts
* this.path = this.manager.buildPath(this);
* // this.path -> ["manager:3PWJWmHbou", "raster_layer:aS2NREsrlz", "entity_renderer:sfLO4j1B0n", "brush_line:Zrsu8gpZMd"]
* ```
*/
abstract readonly path: string[];
/**
* The parent module. This may be the canvas manager or another module.
*/
abstract readonly parent: CanvasModuleBase;
/**
* The canvas manager.
*/
abstract readonly manager: CanvasManager;
/**
* The logger for the module. The logger must be a `ROARR` logger.
*
* Modules should use the manager's `buildLogger` method to set this value.
*
* @example
* ```ts
* this.log = this.manager.buildLogger(this);
* ```
*/
abstract readonly log: Logger;
/**
* An optional method that initializes the module. This method is called after all modules have been created.
*
* Use this method to perform any setup that requires all modules to be created. For example, setting some initial
* state or doing an initial render.
*/
initialize?: () => void = undefined;
/**
* Returns a logging context object that includes relevant information about the module.
* Canvas modules may override this method to include additional information in the logging context, but should
* always include the parent's logging context.
*
* The default implementation includes the parent context and the module's path as a string.
*
* @example
* ```ts
* getLoggingContext = () => {
* return {
* ...this.parent.getLoggingContext(),
* path: this.path.join(' > '),
* someImportantValue: this.someImportantValue,
* };
* };
* ```
*/
getLoggingContext: () => JsonObject = () => {
return {
...this.parent.getLoggingContext(),
path: this.path.join(' > '),
};
};
/**
* Cleans up the module when it is disposed.
*
* Canvas modules may override this method to clean up any loose ends. For example:
* - Destroy Konva nodes
* - Unsubscribe from any subscriptions
* - Abort async operations
* - Close websockets
* - Terminate workers
*
* This method is called when the module is disposed. For example:
* - When an entity is deleted and its module is destroyed
* - When the canvas manager is destroyed
*
* The default implementation only logs a message.
*
* @example
* ```ts
* destroy = () => {
* this.log('Destroying module');
* this.subscriptions.forEach((unsubscribe) => unsubscribe());
* this.subscriptions.clear();
* this.konva.group.destroy();
* };
* ```
*/
destroy: () => void = () => {
this.log('Destroying module');
};
/**
* Returns a serializable representation of the module.
* Canvas modules may override this method to include additional information in the representation.
* The default implementation includes id, type, and path.
*
* @example
* ```ts
* repr = () => {
* return {
* id: this.id,
* type: this.type,
* path: this.path,
* state: deepClone(this.state),
* };
* };
* ```
*/
repr: () => JsonObject = () => {
return {
id: this.id,
type: this.type,
path: this.path,
};
};
}
|