aboutsummaryrefslogtreecommitdiff
path: root/src/controllers/DocumentController.ts
blob: 0c53a9c4361a3de57965f6150cd0333a90598dfd (plain)
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
import { FieldController } from "./FieldController"
import { KeyController } 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> }

    GetField(key: KeyController): FieldController {
        if (key.Id in this.fields) {
            return this.fields[key.Id].field;
        }
        return null;
    }

    SetField(key: KeyController, field: FieldController): void {
        let oldField: FieldController = null;
        if (key.Id in this.fields) {
            let old = this.fields[key.Id];
            oldField = old.field;
            old.disposer.dispose();
        }

        if (oldField === field) {
            return;
        }

        if (field === null) {
            delete this.fields[key.Id];
        } else {
            this.fields[key.Id] = {
                key: key,
                field: field,
                disposer: field.FieldUpdated.on((args) => this.DocumentFieldUpdated({
                    action: FieldUpdatedAction.Update,
                    oldValue: null,
                    newValue: field,
                    field: this,
                    fieldArgs: args,
                    key: key
                }))
            }
        }

        let action = oldField === null ? FieldUpdatedAction.Add :
            (field === null ? FieldUpdatedAction.Remove :
                FieldUpdatedAction.Replace);

        this.DocumentFieldUpdated({
            field: this,
            key: key,
            oldValue: oldField,
            newValue: field,
            fieldArgs: null,
            action: action
        })
    }

    SetFieldValue<T extends FieldController>(key:KeyController, value:any, ctor: {new():T}) : boolean {
        let field = this.GetField(key);
        if(field !== null) {
            return field.TrySetValue(value);
        } else {
            field = new ctor();
            if(field.TrySetValue(value)) {
                this.SetField(key, field);
                return true;
            } else {
                return false;
            }
        }
    }

    private DocumentFieldUpdated(args: DocumentUpdatedArgs) {
        if (args.key.Id in this.fieldUpdateHandlers) {
            this.fieldUpdateHandlers[args.key.Id].emit(args);
        }
        this.FieldUpdated.emit(args);
    }

    AddFieldUpdatedHandler(key: KeyController, listener: Listener<DocumentUpdatedArgs>): Disposable {
        if (!(key.Id in this.fieldUpdateHandlers)) {
            this.fieldUpdateHandlers[key.Id] = new TypedEvent<DocumentUpdatedArgs>();
        }

        return this.fieldUpdateHandlers[key.Id].on(listener);
    }

    RemoveFieldUpdatedHandler(key: KeyController, listener: Listener<DocumentUpdatedArgs>) {
        if (key.Id in this.fieldUpdateHandlers) {
            this.fieldUpdateHandlers[key.Id].off(listener);
        }
    }

    TrySetValue(value: any): boolean {
        throw new Error("Method not implemented.");
    }
    GetValue() {
        throw new Error("Method not implemented.");
    }
    Copy(): FieldController {
        throw new Error("Method not implemented.");
    }


}