aboutsummaryrefslogtreecommitdiff
path: root/src/controllers
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-01-10 23:52:54 -0500
committerTyler Schicke <tyler_schicke@brown.edu>2019-01-10 23:52:54 -0500
commitee068ab30c43125efd2b0ab853531df9777f544f (patch)
tree9560b014b4de30c3a8f1e3d77ae70db27558fe58 /src/controllers
parent861d61970afc9e67afbafa64e8c1347a18335077 (diff)
Started adding various controllers
Diffstat (limited to 'src/controllers')
-rw-r--r--src/controllers/BasicFieldController.ts36
-rw-r--r--src/controllers/DocumentController.ts107
-rw-r--r--src/controllers/DocumentReferenceController.ts36
-rw-r--r--src/controllers/FieldController.ts45
-rw-r--r--src/controllers/FieldUpdatedArgs.ts27
-rw-r--r--src/controllers/KeyController.ts25
-rw-r--r--src/controllers/NumberController.ts14
-rw-r--r--src/controllers/TextController.ts14
8 files changed, 304 insertions, 0 deletions
diff --git a/src/controllers/BasicFieldController.ts b/src/controllers/BasicFieldController.ts
new file mode 100644
index 000000000..ff88f8781
--- /dev/null
+++ b/src/controllers/BasicFieldController.ts
@@ -0,0 +1,36 @@
+import { FieldController } from "./FieldController"
+import { FieldUpdatedAction } from "./FieldUpdatedArgs";
+
+export abstract class BasicFieldController<T> extends FieldController {
+ get Data(): T {
+ return this.data;
+ }
+
+ set Data(value: T) {
+ if(this.data === value) {
+ return;
+ }
+ this.data = value;
+
+ this.FieldUpdated.emit({
+ field: this,
+ action: FieldUpdatedAction.Update
+ });
+ }
+
+ constructor(private data: T) {
+ super();
+ }
+
+ TrySetValue(value: any): boolean {
+ if (typeof value == typeof this.data) {
+ this.Data = value;
+ return true;
+ }
+ return false;
+ }
+
+ GetValue(): any {
+ return this.Data;
+ }
+}
diff --git a/src/controllers/DocumentController.ts b/src/controllers/DocumentController.ts
new file mode 100644
index 000000000..0c53a9c43
--- /dev/null
+++ b/src/controllers/DocumentController.ts
@@ -0,0 +1,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.");
+ }
+
+
+} \ No newline at end of file
diff --git a/src/controllers/DocumentReferenceController.ts b/src/controllers/DocumentReferenceController.ts
new file mode 100644
index 000000000..9d5bb7af2
--- /dev/null
+++ b/src/controllers/DocumentReferenceController.ts
@@ -0,0 +1,36 @@
+import { FieldController } from "./FieldController";
+import { DocumentController } from "./DocumentController";
+import { KeyController } from "./KeyController";
+import { DocumentUpdatedArgs } from "./FieldUpdatedArgs";
+
+export class DocumentReferenceController extends FieldController {
+ get Key(): KeyController{
+ return this.key;
+ }
+
+ get Document(): DocumentController {
+ return this.document;
+ }
+
+ constructor(private document: DocumentController, private key: KeyController) {
+ super();
+
+ document.AddFieldUpdatedHandler(key, this.DocFieldUpdated);
+ }
+
+ private DocFieldUpdated(args: DocumentUpdatedArgs):void{
+ this.FieldUpdated.emit(args.fieldArgs);
+ }
+
+ 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.");
+ }
+
+
+} \ No newline at end of file
diff --git a/src/controllers/FieldController.ts b/src/controllers/FieldController.ts
new file mode 100644
index 000000000..19205014a
--- /dev/null
+++ b/src/controllers/FieldController.ts
@@ -0,0 +1,45 @@
+import { TypedEvent } from "../util/TypedEvent";
+import { FieldUpdatedArgs } from "./FieldUpdatedArgs";
+import { DocumentReferenceController } from "./DocumentReferenceController";
+
+export abstract class FieldController {
+ Id: string;
+
+ FieldUpdated: TypedEvent<FieldUpdatedArgs>;
+
+ protected DereferenceImpl(): FieldController {
+ return this;
+ }
+ protected DereferenceToRootImpl(): FieldController {
+ let field = this;
+ while(field instanceof DocumentReferenceController) {
+ field = field.Dereference();
+ }
+ return field;
+ }
+
+ Dereference<T extends FieldController = FieldController>(ctor?: { new(): T }): T {
+ let field = this.DereferenceImpl();
+ if (ctor && field instanceof ctor) {
+ return field;
+ } else {
+ return null;
+ }
+ }
+
+ DereferenceToRoot<T extends FieldController = FieldController>(ctor?: { new(): T }): T {
+ let field = this.DereferenceToRootImpl();
+ if (ctor && field instanceof ctor) {
+ return field;
+ } else {
+ return null;
+ }
+ }
+
+ abstract TrySetValue(value: any): boolean;
+
+ abstract GetValue(): any;
+
+ abstract Copy(): FieldController;
+
+} \ No newline at end of file
diff --git a/src/controllers/FieldUpdatedArgs.ts b/src/controllers/FieldUpdatedArgs.ts
new file mode 100644
index 000000000..786a44aa4
--- /dev/null
+++ b/src/controllers/FieldUpdatedArgs.ts
@@ -0,0 +1,27 @@
+import { FieldController } from "./FieldController";
+import { DocumentController } from "./DocumentController";
+import { KeyController } from "./KeyController";
+
+export enum FieldUpdatedAction {
+ Add,
+ Remove,
+ Replace,
+ Update
+}
+
+export interface FieldUpdatedArgs {
+ field: FieldController;
+ action: FieldUpdatedAction;
+}
+
+export interface DocumentUpdatedArgs {
+ field: DocumentController;
+ key: KeyController;
+
+ oldValue: FieldController;
+ newValue: FieldController;
+
+ fieldArgs: FieldUpdatedArgs;
+
+ action: FieldUpdatedAction;
+}
diff --git a/src/controllers/KeyController.ts b/src/controllers/KeyController.ts
new file mode 100644
index 000000000..96e41eded
--- /dev/null
+++ b/src/controllers/KeyController.ts
@@ -0,0 +1,25 @@
+import { FieldController } from "./FieldController"
+
+export class KeyController extends FieldController {
+ get Name():string {
+ return this.name;
+ }
+
+ constructor(private name:string){
+ super();
+ }
+
+ TrySetValue(value: any): boolean {
+ throw new Error("Method not implemented.");
+ }
+
+ GetValue() {
+ return this.Name;
+ }
+
+ Copy(): FieldController {
+ return this;
+ }
+
+
+}
diff --git a/src/controllers/NumberController.ts b/src/controllers/NumberController.ts
new file mode 100644
index 000000000..aeedf025b
--- /dev/null
+++ b/src/controllers/NumberController.ts
@@ -0,0 +1,14 @@
+import { BasicFieldController } from "./BasicFieldController"
+import { FieldUpdatedAction } from "./FieldUpdatedArgs";
+
+export class NumberController extends BasicFieldController<number> {
+ constructor(data: number = 0) {
+ super(data);
+ }
+
+ Copy() {
+ return new NumberController(this.Data);
+ }
+
+
+} \ No newline at end of file
diff --git a/src/controllers/TextController.ts b/src/controllers/TextController.ts
new file mode 100644
index 000000000..5d4b43170
--- /dev/null
+++ b/src/controllers/TextController.ts
@@ -0,0 +1,14 @@
+import { BasicFieldController } from "./BasicFieldController"
+import { FieldUpdatedAction } from "./FieldUpdatedArgs";
+
+export class TextController extends BasicFieldController<string> {
+ constructor(data: string = "") {
+ super(data);
+ }
+
+ Copy() {
+ return new TextController(this.Data);
+ }
+
+
+}