102 lines
3.1 KiB
JavaScript
102 lines
3.1 KiB
JavaScript
|
|
/**
|
||
|
|
* A specialized subclass of the ClientDocumentMixin which is used for document types that are intended to be
|
||
|
|
* represented upon the game Canvas.
|
||
|
|
* @category - Mixins
|
||
|
|
* @param {typeof abstract.Document} Base The base document class mixed with client and canvas features
|
||
|
|
* @returns {typeof CanvasDocument} The mixed CanvasDocument class definition
|
||
|
|
*/
|
||
|
|
function CanvasDocumentMixin(Base) {
|
||
|
|
return class CanvasDocument extends ClientDocumentMixin(Base) {
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
/* Properties */
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A lazily constructed PlaceableObject instance which can represent this Document on the game canvas.
|
||
|
|
* @type {PlaceableObject|null}
|
||
|
|
*/
|
||
|
|
get object() {
|
||
|
|
if ( this._object || this._destroyed ) return this._object;
|
||
|
|
if ( !this.parent?.isView || !this.layer ) return null;
|
||
|
|
return this._object = this.layer.createObject(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @type {PlaceableObject|null}
|
||
|
|
* @private
|
||
|
|
*/
|
||
|
|
_object = this._object ?? null;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Has this object been deliberately destroyed as part of the deletion workflow?
|
||
|
|
* @type {boolean}
|
||
|
|
* @private
|
||
|
|
*/
|
||
|
|
_destroyed = false;
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A reference to the CanvasLayer which contains Document objects of this type.
|
||
|
|
* @type {PlaceablesLayer}
|
||
|
|
*/
|
||
|
|
get layer() {
|
||
|
|
return canvas.getLayerByEmbeddedName(this.documentName);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* An indicator for whether this document is currently rendered on the game canvas.
|
||
|
|
* @type {boolean}
|
||
|
|
*/
|
||
|
|
get rendered() {
|
||
|
|
return this._object && !this._object.destroyed;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
/* Event Handlers */
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @inheritdoc */
|
||
|
|
async _preCreate(data, options, user) {
|
||
|
|
const allowed = await super._preCreate(data, options, user);
|
||
|
|
if ( allowed === false ) return false;
|
||
|
|
if ( !this.schema.has("sort") || ("sort" in data) ) return;
|
||
|
|
let sort = 0;
|
||
|
|
for ( const document of this.collection ) sort = Math.max(sort, document.sort + 1);
|
||
|
|
this.updateSource({sort});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @inheritDoc */
|
||
|
|
_onCreate(data, options, userId) {
|
||
|
|
super._onCreate(data, options, userId);
|
||
|
|
const object = this.object;
|
||
|
|
if ( !object ) return;
|
||
|
|
this.layer.objects.addChild(object);
|
||
|
|
object.draw().then(() => {
|
||
|
|
object?._onCreate(data, options, userId);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @inheritDoc */
|
||
|
|
_onUpdate(changed, options, userId) {
|
||
|
|
super._onUpdate(changed, options, userId);
|
||
|
|
this._object?._onUpdate(changed, options, userId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/** @inheritDoc */
|
||
|
|
_onDelete(options, userId) {
|
||
|
|
super._onDelete(options, userId);
|
||
|
|
this._object?._onDelete(options, userId);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|