diff options
Diffstat (limited to 'src/controllers/DocumentController.ts')
-rw-r--r-- | src/controllers/DocumentController.ts | 68 |
1 files changed, 53 insertions, 15 deletions
diff --git a/src/controllers/DocumentController.ts b/src/controllers/DocumentController.ts index 0c53a9c43..02ef66417 100644 --- a/src/controllers/DocumentController.ts +++ b/src/controllers/DocumentController.ts @@ -1,21 +1,38 @@ -import { FieldController } from "./FieldController" -import { KeyController } from "./KeyController" +import { FieldController, Cast, Opt } from "./FieldController" +import { KeyController, KeyStore } from "./KeyController" import { TypedEvent, Listener, Disposable } from "../util/TypedEvent"; import { DocumentUpdatedArgs, FieldUpdatedAction } from "./FieldUpdatedArgs"; export class DocumentController extends FieldController { private fields: { [key: string]: { key: KeyController, field: FieldController, disposer: Disposable } } = {}; - private fieldUpdateHandlers: { [key: string]: TypedEvent<DocumentUpdatedArgs> } + private fieldUpdateHandlers: { [key: string]: TypedEvent<DocumentUpdatedArgs> } = {}; - GetField(key: KeyController): FieldController { - if (key.Id in this.fields) { - return this.fields[key.Id].field; + GetField(key: KeyController, ignoreProto?: boolean): Opt<FieldController> { + let field: Opt<FieldController>; + if (ignoreProto) { + if (key.Id in this.fields) { + field = this.fields[key.Id].field; + } + } else { + let doc: Opt<DocumentController> = this; + while (doc && !(key.Id in doc.fields)) { + doc = doc.GetPrototype(); + } + + if (doc) { + field = doc.fields[key.Id].field; + } } - return null; + + return field; + } + + GetFieldT<T extends FieldController = FieldController>(key: KeyController, ctor: { new(): T }, ignoreProto?: boolean): Opt<T> { + return Cast(this.GetField(key, ignoreProto), ctor); } - SetField(key: KeyController, field: FieldController): void { - let oldField: FieldController = null; + SetField(key: KeyController, field: Opt<FieldController>): void { + let oldField: Opt<FieldController>; if (key.Id in this.fields) { let old = this.fields[key.Id]; oldField = old.field; @@ -26,7 +43,7 @@ export class DocumentController extends FieldController { return; } - if (field === null) { + if (field == null) { delete this.fields[key.Id]; } else { this.fields[key.Id] = { @@ -34,7 +51,7 @@ export class DocumentController extends FieldController { field: field, disposer: field.FieldUpdated.on((args) => this.DocumentFieldUpdated({ action: FieldUpdatedAction.Update, - oldValue: null, + oldValue: undefined, newValue: field, field: this, fieldArgs: args, @@ -52,18 +69,17 @@ export class DocumentController extends FieldController { key: key, oldValue: oldField, newValue: field, - fieldArgs: null, action: action }) } - SetFieldValue<T extends FieldController>(key:KeyController, value:any, ctor: {new():T}) : boolean { + SetFieldValue<T extends FieldController>(key: KeyController, value: any, ctor: { new(): T }): boolean { let field = this.GetField(key); - if(field !== null) { + if (field != null) { return field.TrySetValue(value); } else { field = new ctor(); - if(field.TrySetValue(value)) { + if (field.TrySetValue(value)) { this.SetField(key, field); return true; } else { @@ -72,6 +88,28 @@ export class DocumentController extends FieldController { } } + GetPrototype(): Opt<DocumentController> { + return this.GetFieldT(KeyStore.Prototype, DocumentController, true); + } + + GetAllPrototypes(): DocumentController[] { + let protos: DocumentController[] = []; + let doc: Opt<DocumentController> = this; + while (doc != null) { + protos.push(doc); + doc = doc.GetPrototype(); + } + return protos; + } + + MakeDelegate(): DocumentController { + let delegate = new DocumentController(); + + delegate.SetField(KeyStore.Prototype, this); + + return delegate; + } + private DocumentFieldUpdated(args: DocumentUpdatedArgs) { if (args.key.Id in this.fieldUpdateHandlers) { this.fieldUpdateHandlers[args.key.Id].emit(args); |