diff options
Diffstat (limited to 'src/fields')
| -rw-r--r-- | src/fields/BasicField.ts | 12 | ||||
| -rw-r--r-- | src/fields/Document.ts | 37 | ||||
| -rw-r--r-- | src/fields/DocumentReference.ts | 4 | ||||
| -rw-r--r-- | src/fields/Field.ts | 14 | ||||
| -rw-r--r-- | src/fields/ImageField.ts | 4 | ||||
| -rw-r--r-- | src/fields/Key.ts | 10 | ||||
| -rw-r--r-- | src/fields/ListField.ts | 65 | ||||
| -rw-r--r-- | src/fields/NumberField.ts | 4 | ||||
| -rw-r--r-- | src/fields/RichTextField.ts | 4 | ||||
| -rw-r--r-- | src/fields/TextField.ts | 4 |
10 files changed, 119 insertions, 39 deletions
diff --git a/src/fields/BasicField.ts b/src/fields/BasicField.ts index 4b68ba01f..95f737dea 100644 --- a/src/fields/BasicField.ts +++ b/src/fields/BasicField.ts @@ -3,11 +3,19 @@ import { observable, computed, action } from "mobx"; import { Server } from "../client/Server"; export abstract class BasicField<T> extends Field { - constructor(data: T, id: FIELD_ID = undefined) { + constructor(data: T, save: boolean, id: FIELD_ID = undefined) { super(id); this.data = data; - Server.UpdateField(this) + if (save) { + Server.UpdateField(this) + } + } + + UpdateFromServer(data: any) { + if (this.data !== data) { + this.data = data; + } } @observable diff --git a/src/fields/Document.ts b/src/fields/Document.ts index cb4f6f25c..4bab1299d 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -10,13 +10,22 @@ import { Types } from "../server/Message"; import { ObjectID } from "bson"; export class Document extends Field { - public fields: ObservableMap<Key, Opt<Field>> = new ObservableMap(); + public fields: ObservableMap<string, { key: Key, field: Opt<Field> }> = new ObservableMap(); public _proxies: ObservableMap<string, FIELD_ID> = new ObservableMap(); - constructor(id?: string) { + constructor(id?: string, save: boolean = true) { super(id) - Server.UpdateField(this) + if (save) { + Server.UpdateField(this) + } + } + + UpdateFromServer(data: [string, string][]) { + for (const key in data) { + const element = data[key]; + this._proxies.set(element[0], element[1]); + } } @computed @@ -27,25 +36,25 @@ export class Document extends Field { Get(key: Key, ignoreProto: boolean = false): FieldValue<Field> { let field: FieldValue<Field>; if (ignoreProto) { - if (this.fields.has(key)) { - field = this.fields.get(key); + if (this.fields.has(key.Id)) { + field = this.fields.get(key.Id)!.field; } else if (this._proxies.has(key.Id)) { field = Server.GetDocumentField(this, key); } } else { let doc: FieldValue<Document> = this; while (doc && doc != FieldWaiting && field != FieldWaiting) { - if (!doc.fields.has(key)) { + if (!doc.fields.has(key.Id)) { if (doc._proxies.has(key.Id)) { field = Server.GetDocumentField(doc, key); break; } - if ((doc.fields.has(KeyStore.Prototype) || doc._proxies.has(KeyStore.Prototype.Id))) { + if ((doc.fields.has(KeyStore.Prototype.Id) || doc._proxies.has(KeyStore.Prototype.Id))) { doc = doc.GetPrototype(); } else break; } else { - field = doc.fields.get(key); + field = doc.fields.get(key.Id)!.field; break; } } @@ -93,11 +102,11 @@ export class Document extends Field { @action Set(key: Key, field: Field | undefined): void { if (field) { - this.fields.set(key, field); + this.fields.set(key.Id, { key, field }); this._proxies.set(key.Id, field.Id) // Server.AddDocumentField(this, key, field); } else { - this.fields.delete(key); + this.fields.delete(key.Id); this._proxies.delete(key.Id) // Server.DeleteDocumentField(this, key); } @@ -144,8 +153,8 @@ export class Document extends Field { return protos; } - MakeDelegate(): Document { - let delegate = new Document(); + MakeDelegate(id?: string): Document { + let delegate = new Document(id); delegate.Set(KeyStore.Prototype, this); @@ -167,14 +176,14 @@ export class Document extends Field { } ToJson(): { type: Types, data: [string, string][], _id: string } { - console.log(this.fields) + // console.log(this.fields) let fields: [string, string][] = [] this._proxies.forEach((field, key) => { if (field) { fields.push([key, field as string]) } }); - console.log(fields) + // console.log(fields) return { type: Types.Document, diff --git a/src/fields/DocumentReference.ts b/src/fields/DocumentReference.ts index b1edd1dff..4096cbb92 100644 --- a/src/fields/DocumentReference.ts +++ b/src/fields/DocumentReference.ts @@ -17,6 +17,10 @@ export class DocumentReference extends Field { super(); } + UpdateFromServer() { + + } + Dereference(): FieldValue<Field> { return this.document.Get(this.key); } diff --git a/src/fields/Field.ts b/src/fields/Field.ts index 5a65e35b9..853fb9327 100644 --- a/src/fields/Field.ts +++ b/src/fields/Field.ts @@ -1,14 +1,6 @@ import { Utils } from "../Utils"; import { Types } from "../server/Message"; -import { NumberField } from "./NumberField"; -import { TextField } from "./TextField"; -import { RichTextField } from "./RichTextField"; -import { KeyStore, Key } from "./Key"; -import { ImageField } from "./ImageField"; -import { ListField } from "./ListField"; -import { Document } from "./Document"; -import { Server } from "../client/Server"; export function Cast<T extends Field>(field: FieldValue<Field>, ctor: { new(): T }): Opt<T> { if (field) { @@ -28,6 +20,10 @@ export type FieldValue<T> = Opt<T> | FIELD_WAITING; export abstract class Field { //FieldUpdated: TypedEvent<Opt<FieldUpdatedArgs>> = new TypedEvent<Opt<FieldUpdatedArgs>>(); + init(callback: (res: Field) => any) { + callback(this); + } + private id: string; get Id(): string { return this.id; @@ -56,6 +52,8 @@ export abstract class Field { return this.id === other.id; } + abstract UpdateFromServer(serverData: any): void; + abstract ToScriptString(): string; abstract TrySetValue(value: any): boolean; diff --git a/src/fields/ImageField.ts b/src/fields/ImageField.ts index 12503b2ec..aba011199 100644 --- a/src/fields/ImageField.ts +++ b/src/fields/ImageField.ts @@ -4,8 +4,8 @@ import { Types } from "../server/Message"; import { ObjectID } from "bson"; export class ImageField extends BasicField<URL> { - constructor(data: URL | undefined = undefined, id: FIELD_ID = undefined) { - super(data == undefined ? new URL("http://cs.brown.edu/~bcz/bob_fettucine.jpg") : data, id); + constructor(data: URL | undefined = undefined, id: FIELD_ID = undefined, save: boolean = true) { + super(data == undefined ? new URL("http://cs.brown.edu/~bcz/bob_fettucine.jpg") : data, save, id); } toString(): string { diff --git a/src/fields/Key.ts b/src/fields/Key.ts index 1e878a361..51d8e093c 100644 --- a/src/fields/Key.ts +++ b/src/fields/Key.ts @@ -12,11 +12,17 @@ export class Key extends Field { return this.name; } - constructor(name: string, id?: string) { + constructor(name: string, id?: string, save: boolean = true) { super(id || Utils.GenerateDeterministicGuid(name)); this.name = name; - Server.UpdateField(this) + if (save) { + Server.UpdateField(this) + } + } + + UpdateFromServer(data: string) { + this.name = data; } TrySetValue(value: any): boolean { diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts index cf8a1ba8b..1585746df 100644 --- a/src/fields/ListField.ts +++ b/src/fields/ListField.ts @@ -1,10 +1,59 @@ -import { Field, FIELD_ID } from "./Field"; +import { Field, FIELD_ID, FieldValue, Opt } from "./Field"; import { BasicField } from "./BasicField"; import { Types } from "../server/Message"; +import { observe, action } from "mobx"; +import { Server } from "../client/Server"; +import { ServerUtils } from "../server/ServerUtil"; export class ListField<T extends Field> extends BasicField<T[]> { - constructor(data: T[] = [], id: FIELD_ID = undefined) { - super(data.slice(), id); + private _proxies: string[] = [] + constructor(data: T[] = [], id: FIELD_ID = undefined, save: boolean = true) { + super(data, save, id); + this.updateProxies(); + if (save) { + Server.UpdateField(this); + } + observe(this.Data, () => { + this.updateProxies() + Server.UpdateField(this); + }) + } + + private updateProxies() { + this._proxies = this.Data.map(field => field.Id); + } + + UpdateFromServer(fields: string[]) { + this._proxies = fields; + } + private arraysEqual(a: any[], b: any[]) { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length != b.length) return false; + + // If you don't care about the order of the elements inside + // the array, you should sort both arrays here. + // Please note that calling sort on an array will modify that array. + // you might want to clone your array first. + + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + return true; + } + + init(callback: (field: Field) => any) { + Server.GetFields(this._proxies, action((fields: { [index: string]: Field }) => { + if (!this.arraysEqual(this._proxies, this.Data.map(field => field.Id))) { + + this.Data = this._proxies.map(id => fields[id] as T) + observe(this.Data, () => { + this.updateProxies() + Server.UpdateField(this); + }) + } + callback(this); + })) } ToScriptString(): string { @@ -15,11 +64,17 @@ export class ListField<T extends Field> extends BasicField<T[]> { return new ListField<T>(this.Data); } - ToJson(): { type: Types, data: T[], _id: string } { + ToJson(): { type: Types, data: string[], _id: string } { return { type: Types.List, - data: this.Data, + data: this._proxies, _id: this.Id } } + + static FromJson(id: string, ids: string[]): ListField<Field> { + let list = new ListField([], id, false); + list._proxies = ids; + return list + } }
\ No newline at end of file diff --git a/src/fields/NumberField.ts b/src/fields/NumberField.ts index 7fa9ec2e4..29e285201 100644 --- a/src/fields/NumberField.ts +++ b/src/fields/NumberField.ts @@ -3,8 +3,8 @@ import { Types } from "../server/Message"; import { FIELD_ID } from "./Field"; export class NumberField extends BasicField<number> { - constructor(data: number = 0, id: FIELD_ID = undefined) { - super(data, id); + constructor(data: number = 0, id: FIELD_ID = undefined, save: boolean = true) { + super(data, save, id); } ToScriptString(): string { diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts index 3c6151009..9783107e3 100644 --- a/src/fields/RichTextField.ts +++ b/src/fields/RichTextField.ts @@ -3,8 +3,8 @@ import { Types } from "../server/Message"; import { FIELD_ID } from "./Field"; export class RichTextField extends BasicField<string> { - constructor(data: string = "", id: FIELD_ID = undefined) { - super(data, id); + constructor(data: string = "", id: FIELD_ID = undefined, save: boolean = true) { + super(data, save, id); } ToScriptString(): string { diff --git a/src/fields/TextField.ts b/src/fields/TextField.ts index f2b277298..efb3c035f 100644 --- a/src/fields/TextField.ts +++ b/src/fields/TextField.ts @@ -3,8 +3,8 @@ import { FIELD_ID } from "./Field"; import { Types } from "../server/Message"; export class TextField extends BasicField<string> { - constructor(data: string = "", id: FIELD_ID = undefined) { - super(data, id); + constructor(data: string = "", id: FIELD_ID = undefined, save: boolean = true) { + super(data, save, id); } ToScriptString(): string { |
