UNPKG

tav-media

Version:

Cross platform media editing framework

203 lines (202 loc) 6.86 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /* eslint-disable prefer-rest-params */ import { tav } from '../tav'; export class TAVObject { constructor(id = uuid()) { this.prepared = false; this.type = 'TAVObject'; this.nativeInvalidated = false; this.id = id; } static parse(source) { const it = parseTAVObject(source, this.classes, this.instances); return it; } static declareType(name, class_) { this.classes[name] = class_; } static getType(name) { return this.classes[name]; } prepare() { return __awaiter(this, void 0, void 0, function* () { yield this.doPrepare(); this.prepared = true; }); } release() { } doPrepare() { return __awaiter(this, void 0, void 0, function* () { }); } invalidated() { this.nativeInvalidated = true; } } TAVObject.classes = {}; TAVObject.instances = {}; export function isTAVObject(source, classes) { if (!source || typeof source !== 'object') { return false; } if ('id' in source && Object.keys(source).length === 1) { return true; } if ('type' in source) { if (source.type in classes) { return true; } console.error(`[ isTAVObject ] type not declared: ${source.type}`); return false; } return false; } export class ObjectPlaceholder extends TAVObject { constructor() { super(...arguments); this.refs = []; } resolve(realValue) { this.refs.forEach((ref) => { // eslint-disable-next-line no-param-reassign ref.target[ref.prop] = realValue; }); this.refs.length = 0; } } export function parseTAVObject(source, classes, instances) { if (!isTAVObject(source, classes)) return undefined; if (source.id && Object.keys(source).length === 1) { if (instances[source.id]) { return instances[source.id]; } const placeholder = new ObjectPlaceholder(source.id); // eslint-disable-next-line no-param-reassign instances[source.id] = placeholder; return placeholder; } // eslint-disable-next-line @typescript-eslint/naming-convention const TargetClass = classes[source.type]; // tav object 被多次引用的时,可能被多次 parse 的情况 const existingInstance = instances[source.id]; if (existingInstance instanceof TargetClass) { return existingInstance; } const target = new TargetClass(); target.id = source.id || target.id; // 解决对象初始化之前的引用 const existing = instances[target.id]; if (existing) { if (existing instanceof ObjectPlaceholder) { existing.resolve(target); } else { throw new Error(`[ Parse error ] id 重复: ${JSON.stringify(source)}`); } } // eslint-disable-next-line no-param-reassign instances[target.id] = target; assignProperties(source, target, classes, instances); return target; } function assignProperty(source, context, key, classes, instances) { var _a; const val = source[key]; if (typeof val !== 'object' && typeof val !== 'function') { context[key] = val; return; } if (val instanceof Array) { context[key] = (_a = context[key]) !== null && _a !== void 0 ? _a : []; val.forEach((_, index) => { assignProperty(val, context[key], index, classes, instances); }); return; } if (isTAVObject(val, classes)) { const tavObject = parseTAVObject(val, classes, instances); if (tavObject instanceof ObjectPlaceholder) { tavObject.refs.push({ target: context, prop: key }); } context[key] = tavObject; return; } context[key] = {}; assignProperties(val, context[key], classes, instances); } function assignProperties(source, context, classes, instances) { const keys = Object.keys(source); keys.forEach((key) => { assignProperty(source, context, key, classes, instances); }); } export function uuid(len = 16) { const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); const uuid = []; let i; const localRadix = chars.length; for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * localRadix]; return uuid.join(''); } export function updateNative(_target, name, descriptor) { const func = descriptor.set; // eslint-disable-next-line no-param-reassign descriptor.set = function (val) { if (this[name] !== val) { this.invalidated(); ; } return func.apply(this, [val]); }; } export function updateNativeIfEffect(_target, name, descriptor) { const func = descriptor.value; // eslint-disable-next-line no-param-reassign descriptor.value = function () { this.invalidated(); ; return func.apply(this, arguments); }; } export function allowCallNativeAnytime(_target, name, descriptor) { ['value', 'set', 'get'].forEach((method) => { const func = descriptor[method]; if (!func) return; // eslint-disable-next-line no-param-reassign descriptor[method] = function () { if (tav.Asyncify.currData !== null) { const { currData } = tav.Asyncify; tav.Asyncify.currData = null; const ret = func.apply(this, arguments); tav.Asyncify.currData = currData; return ret; } return func.apply(this, arguments); }; }); } export function updateNativeOrMakeInvalidate(_target, name, descriptor) { ['value', 'set', 'get'].forEach((method) => { const func = descriptor[method]; if (!func) return; // eslint-disable-next-line no-param-reassign descriptor[method] = function () { if (!this._nativeObject) { this.invalidated(); return; } return func.apply(this, arguments); }; }); }