home *** CD-ROM | disk | FTP | other *** search
- XB._base.NodeBase = Base.extend({
- constructor: function NodeBase_constructor(baseUID) {
- if (!baseUID)
- throw new Error(XB._base.consts.ERR_UID_REQUIRED);
- this._baseUID = baseUID;
- },
-
- getBaseID: function NodeBase_getBaseID() {
- return this._baseUID;
- },
-
- _baseUID: undefined,
- _storedValue: undefined
- });
-
- XB._base.ConstNodeProto = XB._base.NodeBase.extend({
- constructor: function ConstNodeProto_constructor(baseUID, initVal) {
- this.base(baseUID);
- this._storedValue = initVal;
- },
-
- createInstance: function ConstNodeProto_createInstance(widgetInstance) {
- var nodeInst = new XB._base.ConstNode(this._baseUID, widgetInstance, this._storedValue);
- return nodeInst;
- }
- });
-
- XB._base.VarNodeProto = XB._base.ConstNodeProto.extend({
- createInstance: function VarNodeProto_createInstance(widgetInstance) {
- var nodeInst = new XB._base.VarNode(this._baseUID, widgetInstance, this._storedValue);
- return nodeInst;
- }
- });
-
- XB._base.FuncNodeProto = XB._base.NodeBase.extend({
- constructor: function FuncNodeProto_constructor(baseUID, instanceClass) {
- if ( typeof instanceClass != "function")
- throw new TypeError(this._consts.ERR_NODE_CONSTRUCTOR_EXPECTED);
- this.base(baseUID);
- this._instanceClass = instanceClass;
- this._argsMap = {};
- },
-
- proposeArgName: function FuncNodeProto_proposeArgName() {
- for each (let argName in this._instanceClass.prototype.expectedArgNames) {
- if (!this._argsMap[argName])
- return argName;
- }
- return "param" + this._argsCount;
- },
-
- attachArgument: function FuncNodeProto_attachArgument(argName, argProto) {
- if ( !(argProto instanceof XB._base.NodeBase) || (typeof argProto.createInstance != "function") )
- throw new TypeError(this._consts.ERR_FNODE_PROTO_EXPECTED);
- this._argsMap[argName] = argProto;
- this._argsCount++;
- },
-
- createInstance: function FuncNodeProto_createInstance(widgetInstance) {
- var nodeInst = new this._instanceClass(this._baseUID, widgetInstance, this._argsMap);
- return nodeInst;
- },
-
- _consts: {
- ERR_FNODE_PROTO_EXPECTED: "Function node prototype object expected",
- ERR_NODE_CONSTRUCTOR_EXPECTED: "Widget node constructor expected"
- },
- _argsMap: null,
- _argsCount: 0,
- _instanceClass: null
- });
-
- XB._base.BoundNode = XB._base.NodeBase.extend({
- constructor: function BoundNode_constructor(baseUID, widget) {
- if ( !(widget instanceof XB.WidgetLibrary.WidgetPrototype ||
- widget instanceof XB.WidgetLibrary.WidgetInstance) )
- throw new TypeError(XB._base.consts.ERR_WINST_REQUIRED);
- this.base(baseUID);
- this._parentWidget = widget;
- },
-
- getEffectiveID: function BoundNode_getEffectiveID() {
- var idParts = [this._parentWidget.getID(), this._baseUID];
- if (this._parentWidget instanceof XB.WidgetLibrary.WidgetInstance)
- idParts.unshift(this._parentWidget.getWindowEngine().id);
- return idParts.join("_");
- },
-
- getParentWidget: function BoundNode_getParentWidget() {
- return this._parentWidget;
- },
-
- finalize: function BoundNode_finalize() {
- this._setNewVal(XB.types.empty);
- },
-
- _parentWidget: null,
-
- _formatRuntimeError: function BoundNode_formatRuntimeError(e) {
- return XB._base.consts.ERR_RUNTIME_ERROR + " in node " + this._getHumanReadableID() + ". " + XB._base.formatException(e);
- },
-
- _hasSubscribers: function DynNode_hasSubscribers() {
- return false;
- },
-
- _getHumanReadableID: function FuncNode_getHumanReadableID() {
- var name = "";
- var nameMatch = null;
- if (this._calculate)
- nameMatch = this._calculate.name.match(/F(.+)_calculate/);
- else
- if (this._proc)
- nameMatch = this._proc.name.match(/F(.+)_proc/);
- if (nameMatch)
- name = nameMatch[1];
- return name + "(" + this.getEffectiveID() + ")";
- }
- });
-
- XB._base.ConstNode = XB._base.BoundNode.extend({
- constructor: function ConstNode_constructor(baseUID, widget, initVal) {
- this.base(baseUID, widget);
- this._storedValue = initVal;
- },
-
- getValue: function ConstNode_getValue() {
- return this._storedValue;
- },
-
- unsubscribe: function ConstNode_unsubscribe() {
- },
-
- freeze: function ConstNode_freeze() {
- throw new Error(XB._base.ConstNode.ERR_UNSUPPORTED_ACTION);
- },
-
- melt: function ConstNode_usedNodeChange() {
- throw new Error(XB._base.ConstNode.ERR_UNSUPPORTED_ACTION);
- }
- }, {
- ERR_UNSUPPORTED_ACTION: "ConstNode does not support this method"
- });
-
- XB._base.DynNode = XB._base.ConstNode.extend({
- constructor: function DynNode_constructor(baseUID, widget, initVal) {
- this.base.apply(this, arguments);
- this._dependants = {};
- },
-
- getValue: function DynNode_getValue(subscriber) {
- if (subscriber)
- this._subscribe(subscriber);
- return this.base();
- },
-
- unsubscribe: function DynNode_unsubscribe(subscriber) {
- var subscriberID = subscriber.getEffectiveID();
- if ( !(subscriberID in this._dependants) ) return;
-
- delete this._dependants[subscriberID];
-
- if (!this._hasSubscribers()) {
- XB._base.logger.debug("Node " + this._getHumanReadableID() + " lost all subscribers");
- try {
- if (XB._base.runtime.isXML(this._storedValue))
- this._storedValue.dispose();
-
- this._storedValue = undefined;
- this._notNeeded();
- }
- finally {
- this._argManager.freeAll();
- }
- }
- },
-
- finalize: function DynNode_finalize() {
- try {
- try {
- this._dependants = {};
- this._notNeeded();
- }
- finally {
- this._argManager.freeAll();
- }
- }
- finally {
- this.base();
- }
- },
-
- _setNewVal: function DynNode_setNewVal(newVal) {
- var valuesDiffer = XB._base.runtime.compareValues(newVal, this._storedValue, true) != 0;
-
- if (XB._base.logger.level <= 10) {
- XB._base.logger.trace("Node " + this._getHumanReadableID() +
- " _setNewVal from " + XB._base.runtime.describeValue(this._storedValue) +
- " to " + XB._base.runtime.describeValue(newVal) +
- ", differ: " + valuesDiffer);
- }
-
- if (valuesDiffer) {
- if (XB._base.runtime.isXML(this._storedValue))
- this._storedValue.dispose();
- this._storedValue = newVal;
- }
- else {
- if ( XB._base.runtime.isXML(newVal) && (newVal !== this._storedValue) )
- newVal.dispose();
- }
- return valuesDiffer;
- },
-
- _subscribe: function DynNode_subscribe(subscriber) {
- this._dependants[subscriber.getEffectiveID()] = subscriber;
- },
-
- _notifyDeps: function DynNode_notifyDeps() {
- XB._base.logger.trace("FuncNode " + this._getHumanReadableID() + " notifies dependants");
- try {
- this._freezeDeps();
- }
- finally {
- this._meltDeps(true);
- }
- },
-
- _freezeDeps: function DynNode_freezeDeps() {
- for each(let dependant in this._dependants)
- dependant.freeze();
- },
-
- _meltDeps: function DynNode_meltDeps(iChanged) {
- for each(let dependant in this._dependants) {
- try {
- dependant.melt(iChanged? this: null);
- }
- catch (e) {
- XB._base.logger.error("Failed melting dependant node " + dependant._getHumanReadableID() + ". " +
- XB._base.formatException(e));
- XB._base.logger.trace(e.stack);
- }
- }
- },
-
- _hasSubscribers: function DynNode_hasSubscribers() {
- return !sysutils.isEmptyObject(this._dependants);
- },
-
- _notNeeded: function DynNode_notNeeded() {
- },
-
- _dependants: null
- });
-
- XB._base.IVariable = {
- setValue: function IVariable_setValue(newValue) {
- if (this._setNewVal(newValue))
- this._notifyDeps();
- }
- };
-
- XB._base.VarNode = XB._base.DynNode.extend(XB._base.IVariable);
-
- XB._base.IHasArguments = {
- constructor: function HasArgs_constructor(baseUID, widget, argsMap) {
- this.base(baseUID, widget);
- this._argManager = new XB._base.FuncNode.ArgManager(this);
-
- for (let argName in argsMap) {
- var argProto = argsMap[argName];
- this._argManager.attachArgument(argName, argProto.createInstance(widget));
- }
- },
-
- _argManager: null
- };
-
- XB._base.ProcNodeBase = XB._base.ConstNode.extend(XB._base.IHasArguments);
-
- XB._base.ProcNode = XB._base.ProcNodeBase.extend({
- perform: function ProcNode_perform() {
- this._proc();
- },
-
- getValue: function ProcNode_getValue() {
- return this._proc();
- }
- });
-
- XB._base.FuncNodeBase = XB._base.DynNode.extend(XB._base.IHasArguments);
-
- XB._base.FuncNode = XB._base.FuncNodeBase.extend({
- constructor: function FuncNode_constructor() {
- this.base.apply(this, arguments);
- this._changedArgs = [];
- },
-
- freeze: function FuncNode_freeze() {
- this._freezeLevel++;
- XB._base.logger.trace("Freezing node " + this._getHumanReadableID() + " " + this._freezeLevel);
- this._freezeDeps();
- },
-
- melt: function FuncNode_melt(changedArgNode) {
- XB._base.logger.trace("Melting node " + this._getHumanReadableID() + " " + this._freezeLevel);
- this._freezeLevel = Math.max(0, this._freezeLevel - 1);
- if (changedArgNode)
- this._changedArgs.push(changedArgNode);
-
- var iChanged = false;
- try {
- if (this._freezeLevel == 0 && this._changedArgs.length > 0) {
- XB._base.logger.trace("Node " + this._getHumanReadableID() + " recalculates");
- var newVal = this._calculateSafely();
- iChanged = this._setNewVal(newVal);
- }
- }
- finally {
- this._meltDeps(iChanged);
- }
- },
-
- getValue: function FuncNode_getValue(subscriber) {
- var prevValue = this.base(subscriber);
- if (prevValue === undefined) {
- var newVal = this._calculateSafely();
- if (this._hasSubscribers())
- this._setNewVal(newVal);
- return newVal;
- }
- return prevValue || XB.types.empty;
- },
-
- _freezeLevel: 0,
- _changedArgs: null,
-
- _calculateSafely: function FuncNode_calculateSafely() {
- var val;
- this._argManager.resetUseStat();
- try {
- val = this._calculate(this._changedArgs);
- }
- catch (e) {
- if (e instanceof XB.types.Exception)
- val = e;
- else {
- val = XB._base.runtime.createXBExceptionFromRTError(this.getEffectiveID(), e);
- XB._base.logger.error(this._formatRuntimeError(e));
- if (e.stack)
- XB._base.logger.debug(e.stack);
- }
- }
- finally {
- this._changedArgs = [];
- this._argManager.freeUnused();
- }
- return val;
- }
- });
-
- XB._base.FuncNode.ArgManager = function FNArgManager_constructor(managedNode) {
- if ( !(managedNode instanceof XB._base.FuncNode || managedNode instanceof XB._base.ProcNode) )
- throw new TypeError(this._consts.ERR_FP_NODE_EXPECTED);
- this._managedNode = managedNode;
- this._namedArgs = {};
- this._orderedArgs = [];
- };
-
- XB._base.FuncNode.ArgManager.prototype = {
- constructor: XB._base.FuncNode.ArgManager,
-
- attachArgument: function ArgMan_AttachArgument(argName, argNode) {
- if (argName == "")
- throw new Error(ERR_NAME_REQUIRED);
- if ( !(argNode instanceof XB._base.BoundNode) )
- throw new TypeError(XB._base.consts.ERR_FUNC_NODE_EXPECTED);
-
- var argInfo = {
- node: argNode,
- used: false
- };
- this._argsCount = this._orderedArgs.push(argInfo);
- this._namedArgs[argName] = argInfo;
- },
-
- detachArgument: function ArgMan_DetachArgument(argName) {
- var argInfo = this._namedArgs[argName];
- if (!argInfo)
- throw new Error(this._consts.ERR_NO_ARG);
-
- argInfo.used = false;
- argInfo.node.unsubscribe(this._managedNode);
- delete this._namedArgs[argName];
- },
-
- resetUseStat: function ArgMan_ResetUseStat() {
- for each (let argInfo in this._namedArgs)
- argInfo.used = false;
- },
-
- freeUnused: function ArgMan_FreeUnused() {
- for each (let argInfo in this._namedArgs) {
- if (!argInfo.used)
- argInfo.node.unsubscribe(this._managedNode);
- }
- },
-
- freeAll: function ArgMan_FreeAll() {
- for each (let argInfo in this._namedArgs) {
- argInfo.used = false;
- argInfo.node.unsubscribe(this._managedNode);
- }
- },
-
- argExists: function ArgMan_ArgExists(argName) {
- return (this._namedArgs[argName] instanceof Object);
- },
-
- getArgsNames: function ArgMan_GetArgsNames() {
- var names = [];
- for (let name in this._namedArgs)
- names.push(name);
- return names;
- },
-
- getValByName: function ArgMan_GetValByName(argName, preferedType) {
- return this._processArgInfo(this._namedArgs[argName], preferedType);
- },
-
- getValByIndex: function ArgMan_GetValByIndex(argIndex, preferedType) {
- return this._processArgInfo(this._orderedArgs[argIndex], preferedType);
- },
-
- getValByNameDef: function ArgMan_GetValByNameDef(argName, preferedType, defaultValue) {
- if ( !(argName in this._namedArgs) )
- return defaultValue;
- try {
- return this._processArgInfo(this._namedArgs[argName], preferedType);
- }
- catch (e) {
- return defaultValue;
- }
- },
-
- getValByIndexDef: function ArgMan_GetValByIndexDef(argIndex, preferedType, defaultValue) {
- if ( !(argIndex in this._orderedArgs) )
- return defaultValue;
- try {
- return this._processArgInfo(this._orderedArgs[argIndex], preferedType);
- }
- catch (e) {
- return defaultValue;
- }
- },
-
- findNodeByName: function ArgMan_GetNodeByName(argName) {
- var argInfo = this._namedArgs[argName];
- if (argInfo) {
- argInfo.used = true;
- return argInfo.node;
- }
- return null;
- },
-
- findNodeByIndex: function ArgMan_GetNodeByIndex(argIndex) {
- var argInfo = this._orderedArgs[argIndex];
- if (argInfo) {
- argInfo.used = true;
- return argInfo.node;
- }
- return null;
- },
-
- get argsCount() {
- return this._argsCount;
- },
-
- argInArray: function (argName, array) {
- if (!(array instanceof Array))
- throw new TypeError("Array expected");
- var argNode = this.findNodeByName(argName);
- if (!argNode)
- return false;
-
- for each(let item in array) {
- if (item === argNode)
- return true;
- }
- return false;
- },
-
- _consts: {
- ERR_FP_NODE_EXPECTED: "FuncNode or ProcNode instance expected",
- ERR_NO_ARG: "No such argument"
- },
- _managedNode: null,
- _namedArgs: null,
- _orderedArgs: null,
- _argsCount: 0,
-
- _processArgInfo: function ArgMan_processArgInfo(argInfo, preferedType) {
- if (argInfo == undefined)
- throw new Error(this._consts.ERR_NO_ARG);
- argInfo.used = true;
- var argVal = argInfo.node.getValue(this._managedNode._hasSubscribers()? this._managedNode: null);
- if (argVal instanceof XB.types.Exception)
- throw argVal;
- switch(preferedType) {
- case "Number":
- return XB._base.runtime.xToNumber(argVal);
- case "String":
- return XB._base.runtime.xToString(argVal);
- case "Bool":
- return XB._base.runtime.xToBool(argVal);
- case "XML":
- return XB._base.runtime.xToXML(argVal);
- case "RequestData":
- return XB._base.runtime.xToRequestData(argVal);
- default:
- return argVal;
- }
- }
- };
-
-