diff --git a/src/nub.ts b/src/nub.ts index 721f0f85394cd42cfeb562009ba52ccbd0295a7b..b0877e6d0db88451380058c86861dcb55a78bf76 100644 --- a/src/nub.ts +++ b/src/nub.ts @@ -816,25 +816,35 @@ export abstract class Nub extends ComputeNode implements IObservable { * @returns the calculated parameter found, if any - used by child Nub to notify * its parent of the calculated parameter to set */ - public loadObjectRepresentation(obj: any): ParamDefinition { - let calculatedParam: ParamDefinition; + public loadObjectRepresentation(obj: any): { p: ParamDefinition, hasErrors: boolean } { + // return value + const ret: { p: ParamDefinition, hasErrors: boolean } = { + p: undefined, + hasErrors: false + }; // set parameter modes and values if (obj.parameters && Array.isArray(obj.parameters)) { for (const p of obj.parameters) { const param = this.getParameter(p.symbol); - if (! param) { - throw new Error(`session file : cannot find parameter ${p.symbol} in target Nub`); - } - // load parameter - const iscalculated = param.loadObjectRepresentation(p, false); - if (iscalculated) { - calculatedParam = param; + if (param) { + // load parameter + const pRet = param.loadObjectRepresentation(p, false); + if (pRet.calculated) { + ret.p = param; + } + // forward errors + if (pRet.hasErrors) { + ret.hasErrors = true; + } + } else { + console.error(`session file : cannot find parameter ${p.symbol} in target Nub`); + ret.hasErrors = true; } } // define calculated param at Nub level // @TODO except if we are a Section / Structure / PabCloisons ? - if (calculatedParam) { - this.calculatedParam = calculatedParam; + if (ret.p) { + this.calculatedParam = ret.p; } } @@ -847,24 +857,32 @@ export abstract class Nub extends ComputeNode implements IObservable { if (! Session.getInstance().uidAlreadyUsed(s.uid)) { subNub.setUid(s.uid); } - const childCalculatedParam = subNub.loadObjectRepresentation(s); + const childRet = subNub.loadObjectRepresentation(s); // add Structure to parent this.addChild(subNub); // set calculated parameter for child ? - if (childCalculatedParam) { - this.calculatedParam = childCalculatedParam; + if (childRet.p) { + this.calculatedParam = childRet.p; + } + // forward errors + if (childRet.hasErrors) { + ret.hasErrors = true; } } } - return calculatedParam; + return ret; } /** * Once session is loaded, run a second pass on all linked parameters to * reset their target if needed */ - public fixLinks(obj: any) { + public fixLinks(obj: any): { hasErrors: boolean } { + // return value + const ret = { + hasErrors: false + }; if (obj.parameters && Array.isArray(obj.parameters)) { for (const p of obj.parameters) { const mode: ParamValueMode = (ParamValueMode as any)[p.mode]; // get enum index for string value @@ -878,14 +896,18 @@ export abstract class Nub extends ComputeNode implements IObservable { } catch (err) { console.error(`fixLinks: defineReference error` + ` (${this.uid}.${param.symbol} => ${destNub.uid}.${p.targetParam})`); + // forward error + ret.hasErrors = true; } } else { - // quit console.error("fixLinks : cannot find target Nub"); + // forward error + ret.hasErrors = true; } } } } + return ret; } /** diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts index 16bfdb5c2e54e1961ccc3b9b520f1ba113afda33..263440ea7055b9fdf6fa0b76684abee7279a3def 100644 --- a/src/param/param-definition.ts +++ b/src/param/param-definition.ts @@ -802,8 +802,19 @@ export class ParamDefinition implements INamedIterableValues, IObservable { /** * Fills the current Parameter, provided an object representation * @param obj object representation of a Parameter state + * @returns object { + * calculated: boolean true if loaded parameter is in CALC mode + * hasErrors: boolean true if errors were encountered during loading + * } */ - public loadObjectRepresentation(obj: any, setCalcMode: boolean = true): boolean { + public loadObjectRepresentation(obj: any, setCalcMode: boolean = true) + : { calculated: boolean, hasErrors: boolean } { + + const ret = { + calculated: false, + hasErrors: false + }; + // set mode const mode: ParamValueMode = (ParamValueMode as any)[obj.mode]; // get enum index for string value @@ -813,13 +824,11 @@ export class ParamDefinition implements INamedIterableValues, IObservable { try { this.valueMode = mode; } catch (err) { + ret.hasErrors = true; console.error("loadObjectRepresentation: set valueMode error"); } } - // detect if this is the calculated param - used by Nub.loadObjectRepresentation() - let isCalculated = false; - // set value(s) switch (mode) { case ParamValueMode.SINGLE: @@ -839,7 +848,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable { case ParamValueMode.CALCUL: // although calculated param is set at Nub level (see below), // it is detected as "the only parameter in CALC mode" - isCalculated = true; + ret.calculated = true; break; case ParamValueMode.LINK: @@ -849,6 +858,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable { try { this.defineReference(destNub, obj.targetParam); } catch (err) { + ret.hasErrors = true; console.error("loadObjectRepresentation: defineReference error" + ` ${this.symbol} => ${destNub.uid}.${obj.targetParam})`); } @@ -859,7 +869,7 @@ export class ParamDefinition implements INamedIterableValues, IObservable { throw new Error(`session file : invalid value mode '${obj.valueMode}' in param object ${obj.symbol}`); } - return isCalculated; + return ret; } /** diff --git a/src/section/section_nub.ts b/src/section/section_nub.ts index 49ce255f26d4a3c61eacec72da8aeaac894d33e0..387aa638606292bc82b4e405e5ca05b6a6955b2b 100644 --- a/src/section/section_nub.ts +++ b/src/section/section_nub.ts @@ -63,7 +63,11 @@ export abstract class SectionNub extends Nub { * Once session is loaded, run a second pass on all linked parameters to * reset their target if needed */ - public fixLinks(obj: any) { + public fixLinks(obj: any): { hasErrors: boolean } { + // return value + const ret = { + hasErrors: false + }; // iterate over parameters super.fixLinks(obj); @@ -72,9 +76,14 @@ export abstract class SectionNub extends Nub { for (const s of obj.children) { // get the Nub const subNub = Session.getInstance().findNubByUid(s.uid); - subNub.fixLinks(s); + const res = subNub.fixLinks(s); + // forward errors + if (res.hasErrors) { + ret.hasErrors = true; + } } } + return ret; } /** diff --git a/src/session.ts b/src/session.ts index 8e9b40421bbd4332f890c2c3b6eecacfa1efa52d..94f230963220e7a43c0af3fc62c98fa0d96244e9 100644 --- a/src/session.ts +++ b/src/session.ts @@ -133,8 +133,12 @@ export class Session { * Loads (a part of) a session from a JSON representation * @param serialised JSON data */ - public unserialise(serialised: string, uids?: string[]) { - const newNubs: any[] = []; + public unserialise(serialised: string, uids?: string[]): { nubs: any[], hasErrors: boolean } { + // return value + const ret: { nubs: any[], hasErrors: boolean } = { + nubs: [], + hasErrors: false + } // unserialise to object const data = JSON.parse(serialised); if (data.session && Array.isArray(data.session)) { @@ -142,18 +146,26 @@ export class Session { data.session.forEach((e: any) => { if (! uids || uids.length === 0 || uids.includes(e.uid)) { const nubPointer = this.createNubFromObjectRepresentation(e); - newNubs.push(nubPointer); + ret.nubs.push(nubPointer); + // forward errors + if (nubPointer.hasErrors) { + ret.hasErrors = true; + } } }); } // second pass for links - this.fixLinks(serialised, uids); + const flRes = this.fixLinks(serialised, uids); + // forward errors + if (flRes.hasErrors) { + ret.hasErrors = true; + } // second pass for PABs this.fixPAB(serialised, uids); - return newNubs; + return ret; } /** @@ -562,16 +574,25 @@ export class Session { * a pointer to the Nub and its JSON metadata * @param obj object representation of a single Nub */ - private createNubFromObjectRepresentation(obj: any): { nub: Nub, meta: any } { - const nubPointer: any = {}; + private createNubFromObjectRepresentation(obj: any): { nub: Nub, meta: any, hasErrors: boolean } { + // return value; + const nubPointer: { nub: Nub, meta: any, hasErrors: boolean } = { + nub: undefined, + meta: undefined, + hasErrors: false + }; // create the Nub const newNub = this.createSessionNub(new Props(obj.props)); // try to keep the original ID if (! this.uidAlreadyUsed(obj.uid)) { newNub.setUid(obj.uid); } - newNub.loadObjectRepresentation(obj); + const res = newNub.loadObjectRepresentation(obj); nubPointer.nub = newNub; + // forward errors + if (res.hasErrors) { + nubPointer.hasErrors = true; + } // add metadata (used by GUI, for ex.) if (obj.meta) { nubPointer.meta = obj.meta; @@ -582,7 +603,11 @@ export class Session { /** * Asks all loaded Nubs to relink any parameter that has a wrong target */ - private fixLinks(serialised: string, uids?: string[]) { + private fixLinks(serialised: string, uids?: string[]): { hasErrors: boolean } { + // return value + const res = { + hasErrors: false + }; const data = JSON.parse(serialised); if (data.session && Array.isArray(data.session)) { // find each corresponding Nub in the session @@ -590,10 +615,15 @@ export class Session { if (! uids || uids.length === 0 || uids.includes(e.uid)) { const nub = this.findNubByUid(e.uid); // find linked parameters - nub.fixLinks(e); + const ret = nub.fixLinks(e); + // forwardErrors + if (ret.hasErrors) { + res.hasErrors = true; + } } }); } + return res; } /** diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts index 2f4f8e32a49a17ff2db8ed51f02d1c95173c2730..4b1d89243bfb67353b52cfd7f4a17b220491184f 100644 --- a/src/structure/parallel_structure.ts +++ b/src/structure/parallel_structure.ts @@ -138,7 +138,11 @@ export class ParallelStructure extends Nub { * Once session is loaded, run a second pass on all linked parameters to * reset their target if needed */ - public fixLinks(obj: any) { + public fixLinks(obj: any): { hasErrors: boolean } { + // return value + const ret = { + hasErrors: false + }; // iterate over parameters super.fixLinks(obj); @@ -147,9 +151,14 @@ export class ParallelStructure extends Nub { for (const s of obj.children) { // get the Nub const subNub = Session.getInstance().findNubByUid(s.uid); - subNub.fixLinks(s); + const res = subNub.fixLinks(s); + // forward errors + if (res.hasErrors) { + ret.hasErrors = true; + } } } + return ret; } /**