import { HistoryController } from "./history"; import {BehaviorSubject} from "rxjs"; import { reactive, toRaw } from "vue"; export class ValueSnap { Id:string; Value: any; OldValue: any; Rx: BehaviorSubject; constructor(id:string, value:any, oldValue:any, rx: BehaviorSubject) { this.Id = id; this.Value = value; this.OldValue = oldValue; this.Rx = rx } redo() { this.Rx.next({value: this.Value, _hstry:false}); } undo() { this.Rx.next({value: this.OldValue, _hstry:false}); } clone() { return new ValueSnap(this.Id, this.Value,this.OldValue, this.Rx); } } export type RxValueType = { value: T, _hstry?: boolean } function createRxValue(value: T, histry:boolean) { return new BehaviorSubject< RxValueType >({value:value, _hstry: histry}) } let _valueIndex = 0; export function createValueSnap(value:any, oldValue:any, rx:BehaviorSubject) { let i = _valueIndex + 1; _valueIndex +=1; return new ValueSnap(i+"", value, oldValue, rx); } class RxValue { static create(_fields:T, histroy?: HistoryController ) { let obj = {} as any; obj._historySnap = {} as any; obj._historySub = {} as any; obj._rxs = {} as any; obj._fields = _fields; obj._history = histroy; obj._refs = {} as any; const names = Object.keys(_fields); names.forEach(name=>{ const currName = name; const initValue = _fields[currName] const f = createRxValue(initValue, !!histroy); obj._rxs[name] = f; const snap = createValueSnap(initValue, initValue, f); obj._historySnap[name] = snap; const rxc = reactive({value: initValue}); Object.defineProperty(obj, currName, { get: function(){ return rxc.value; }, set: function(v) { f.next({value: v}); }, configurable: true, enumerable: true }) const CamName = currName.slice(0,1).toUpperCase() +currName.slice(1); obj["set"+CamName] = function(value:T, nohistory = false){ f.next({value, _hstry: !nohistory}); } obj["on"+CamName + "Changed"] = function(subscribe: (value:T, oldValue:T)=>void){ return f.subscribe((v:any)=>{ if (CamName == "Transform") console.log("history 2222222222222222222222222222") subscribe(v.value, snap.OldValue) } ) } obj._historySub[name] = f.subscribe((v)=>{ if (CamName == "Transform") console.log("history 11111111111111111111111111") snap.OldValue = rxc.value; rxc.value = v.value; if (obj._history && obj._history.enable) { if (!v._hstry) return; const s = snap.clone(); s.Value = v.value; obj._history.record(s); } }) }); obj["setHistory"] = function(h: HistoryController){ obj._history = h; } obj["toJson"] = function() { const out:any = {}; const names = Object.keys(_fields); names.forEach(name=>{ out[name] = obj._rxs[name].getValue().value; }) return out; } obj["fromJson"] = function(json:any) { const out:any = {}; const names = Object.keys(_fields); names.forEach(name=>{ obj._rxs[name].next({value: json[name], _hstry: false}) }) return out; } return obj as typeof _fields & { [K in keyof typeof _fields as `set${Capitalize}`]: (value: typeof _fields[K], nohistory?:boolean) => void; } & { [K in keyof typeof _fields as `on${Capitalize}Changed`]: (subscribe: (value: typeof _fields[K], oldValue:typeof _fields[K])=>void) => void; } & // { // [K in keyof typeof _fields as `ref${Capitalize}`]: () => typeof _fields[K]; // } & { setHistory: (history: HistoryController)=>void toJson:()=>typeof _fields fromJson:(json:typeof _fields)=>void } } } export {RxValue};