home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 March / Chip_2011.03_CD.iso / Tools / yabar.msi / fil992F0B355CFFC8433DA8134B0637E137 < prev    next >
Encoding:
Text File  |  2010-04-16  |  16.6 KB  |  527 lines

  1. XB._base.NodeBase = Base.extend({
  2.     constructor: function NodeBase_constructor(baseUID) {
  3.         if (!baseUID)
  4.             throw new Error(XB._base.consts.ERR_UID_REQUIRED);
  5.         this._baseUID = baseUID;
  6.     },
  7.     
  8.     getBaseID: function NodeBase_getBaseID() {
  9.         return this._baseUID;
  10.     },
  11.     
  12.     _baseUID: undefined,
  13.     _storedValue: undefined
  14. });
  15.  
  16. XB._base.ConstNodeProto = XB._base.NodeBase.extend({
  17.     constructor: function ConstNodeProto_constructor(baseUID, initVal) {
  18.         this.base(baseUID);
  19.         this._storedValue = initVal;
  20.     },
  21.     
  22.     createInstance: function ConstNodeProto_createInstance(widgetInstance) {
  23.         var nodeInst = new XB._base.ConstNode(this._baseUID, widgetInstance, this._storedValue);
  24.         return nodeInst;
  25.     }
  26. });
  27.  
  28. XB._base.VarNodeProto = XB._base.ConstNodeProto.extend({
  29.     createInstance: function VarNodeProto_createInstance(widgetInstance) {
  30.         var nodeInst = new XB._base.VarNode(this._baseUID, widgetInstance, this._storedValue);
  31.         return nodeInst;
  32.     }
  33. });
  34.  
  35. XB._base.FuncNodeProto = XB._base.NodeBase.extend({
  36.     constructor: function FuncNodeProto_constructor(baseUID, instanceClass) {
  37.         if ( typeof instanceClass != "function")
  38.             throw new TypeError(this._consts.ERR_NODE_CONSTRUCTOR_EXPECTED);
  39.         this.base(baseUID);
  40.         this._instanceClass = instanceClass;
  41.         this._argsMap = {};
  42.     },
  43.     
  44.     proposeArgName: function FuncNodeProto_proposeArgName() {
  45.         for each (let argName in this._instanceClass.prototype.expectedArgNames) {
  46.             if (!this._argsMap[argName])
  47.                 return argName;
  48.         }
  49.         return "param" + this._argsCount;
  50.     },
  51.     
  52.     attachArgument: function FuncNodeProto_attachArgument(argName, argProto) {
  53.         if ( !(argProto instanceof XB._base.NodeBase) || (typeof argProto.createInstance != "function") )
  54.             throw new TypeError(this._consts.ERR_FNODE_PROTO_EXPECTED);
  55.         this._argsMap[argName] = argProto;
  56.         this._argsCount++;
  57.     },
  58.     
  59.     createInstance: function FuncNodeProto_createInstance(widgetInstance) {
  60.         var nodeInst = new this._instanceClass(this._baseUID, widgetInstance, this._argsMap);
  61.         return nodeInst;
  62.     },
  63.     
  64.     _consts: {
  65.         ERR_FNODE_PROTO_EXPECTED: "Function node prototype object expected",
  66.         ERR_NODE_CONSTRUCTOR_EXPECTED: "Widget node constructor expected"
  67.     },
  68.     _argsMap: null,
  69.     _argsCount: 0,
  70.     _instanceClass: null
  71. });
  72.  
  73. XB._base.BoundNode = XB._base.NodeBase.extend({
  74.     constructor: function BoundNode_constructor(baseUID, widget) {
  75.         if ( !(widget instanceof XB.WidgetLibrary.WidgetPrototype ||
  76.                widget instanceof XB.WidgetLibrary.WidgetInstance) )
  77.             throw new TypeError(XB._base.consts.ERR_WINST_REQUIRED);
  78.         this.base(baseUID);
  79.         this._parentWidget = widget;
  80.     },
  81.     
  82.     getEffectiveID: function BoundNode_getEffectiveID() {
  83.         var idParts = [this._parentWidget.getID(), this._baseUID];
  84.         if (this._parentWidget instanceof XB.WidgetLibrary.WidgetInstance)
  85.             idParts.unshift(this._parentWidget.getWindowEngine().id);
  86.         return idParts.join("_");
  87.     },
  88.     
  89.     getParentWidget: function BoundNode_getParentWidget() {
  90.         return this._parentWidget;
  91.     },
  92.     
  93.     finalize: function BoundNode_finalize() {
  94.         this._setNewVal(XB.types.empty);
  95.     },
  96.     
  97.     _parentWidget: null,
  98.     
  99.     _formatRuntimeError: function BoundNode_formatRuntimeError(e) {
  100.         return XB._base.consts.ERR_RUNTIME_ERROR + " in node " + this._getHumanReadableID() + ". " + XB._base.formatException(e);
  101.     },
  102.     
  103.     _hasSubscribers: function DynNode_hasSubscribers() {
  104.         return false;
  105.     },
  106.     
  107.     _getHumanReadableID: function FuncNode_getHumanReadableID() {
  108.         var name = "";
  109.         var nameMatch = null;
  110.         if (this._calculate)
  111.             nameMatch = this._calculate.name.match(/F(.+)_calculate/);
  112.         else
  113.             if (this._proc)
  114.                 nameMatch = this._proc.name.match(/F(.+)_proc/);
  115.         if (nameMatch)
  116.             name = nameMatch[1];
  117.         return name + "(" + this.getEffectiveID() + ")";
  118.     }
  119. });
  120.  
  121. XB._base.ConstNode = XB._base.BoundNode.extend({
  122.     constructor: function ConstNode_constructor(baseUID, widget, initVal) {
  123.         this.base(baseUID, widget);
  124.         this._storedValue = initVal;
  125.     },
  126.     
  127.     getValue: function ConstNode_getValue() {
  128.         return this._storedValue;
  129.     },
  130.     
  131.     unsubscribe: function ConstNode_unsubscribe() {
  132.     },
  133.     
  134.     freeze: function ConstNode_freeze() {
  135.         throw new Error(XB._base.ConstNode.ERR_UNSUPPORTED_ACTION);
  136.     },
  137.     
  138.     melt: function ConstNode_usedNodeChange() {
  139.         throw new Error(XB._base.ConstNode.ERR_UNSUPPORTED_ACTION);
  140.     }
  141. }, {
  142.     ERR_UNSUPPORTED_ACTION: "ConstNode does not support this method"
  143. });
  144.  
  145. XB._base.DynNode = XB._base.ConstNode.extend({
  146.     constructor: function DynNode_constructor(baseUID, widget, initVal) {
  147.         this.base.apply(this, arguments);
  148.         this._dependants = {};
  149.     },
  150.     
  151.     getValue: function DynNode_getValue(subscriber) {
  152.         if (subscriber)
  153.             this._subscribe(subscriber);
  154.         return this.base();
  155.     },
  156.     
  157.     unsubscribe: function DynNode_unsubscribe(subscriber) {
  158.         var subscriberID = subscriber.getEffectiveID();
  159.         if ( !(subscriberID in this._dependants) ) return;
  160.         
  161.         delete this._dependants[subscriberID];
  162.         
  163.         if (!this._hasSubscribers()) {
  164.             XB._base.logger.debug("Node " + this._getHumanReadableID() + " lost all subscribers");
  165.             try {
  166.                 if (XB._base.runtime.isXML(this._storedValue))
  167.                     this._storedValue.dispose();
  168.                 
  169.                 this._storedValue = undefined;
  170.                 this._notNeeded();
  171.             }
  172.             finally {
  173.                 this._argManager.freeAll();
  174.             }
  175.         }
  176.     },
  177.     
  178.     finalize: function DynNode_finalize() {
  179.         try {
  180.             try {
  181.                 this._dependants = {};
  182.                 this._notNeeded();
  183.             }
  184.             finally {
  185.                 this._argManager.freeAll();
  186.             }
  187.         }
  188.         finally {
  189.             this.base();
  190.         }
  191.     },
  192.     
  193.     _setNewVal: function DynNode_setNewVal(newVal) {
  194.         var valuesDiffer = XB._base.runtime.compareValues(newVal, this._storedValue, true) != 0;
  195.         
  196.         if (XB._base.logger.level <= 10) {
  197.             XB._base.logger.trace("Node " + this._getHumanReadableID() +
  198.                                   " _setNewVal from " + XB._base.runtime.describeValue(this._storedValue) +
  199.                                   " to " + XB._base.runtime.describeValue(newVal) +
  200.                                   ", differ: " + valuesDiffer);
  201.         }
  202.         
  203.         if (valuesDiffer) {
  204.             if (XB._base.runtime.isXML(this._storedValue))
  205.                 this._storedValue.dispose();
  206.             this._storedValue = newVal;
  207.         }
  208.         else {
  209.             if ( XB._base.runtime.isXML(newVal) && (newVal !== this._storedValue) )
  210.                 newVal.dispose();
  211.         }
  212.         return valuesDiffer;
  213.     },
  214.     
  215.     _subscribe: function DynNode_subscribe(subscriber) {
  216.         this._dependants[subscriber.getEffectiveID()] = subscriber;
  217.     },
  218.     
  219.     _notifyDeps: function DynNode_notifyDeps() {
  220.         XB._base.logger.trace("FuncNode " + this._getHumanReadableID() + " notifies dependants");
  221.         try {
  222.             this._freezeDeps();
  223.         }
  224.         finally {
  225.             this._meltDeps(true);
  226.         }
  227.     },
  228.     
  229.     _freezeDeps: function DynNode_freezeDeps() {
  230.         for each(let dependant in this._dependants)
  231.             dependant.freeze();
  232.     },
  233.     
  234.     _meltDeps: function DynNode_meltDeps(iChanged) {
  235.         for each(let dependant in this._dependants) {
  236.             try {
  237.                 dependant.melt(iChanged? this: null);
  238.             }
  239.             catch (e) {
  240.                 XB._base.logger.error("Failed melting dependant node " + dependant._getHumanReadableID() + ". " +
  241.                                       XB._base.formatException(e));
  242.                 XB._base.logger.trace(e.stack);
  243.             }
  244.         }
  245.     },
  246.     
  247.     _hasSubscribers: function DynNode_hasSubscribers() {
  248.         return !sysutils.isEmptyObject(this._dependants);
  249.     },
  250.     
  251.     _notNeeded: function DynNode_notNeeded() {
  252.     },
  253.     
  254.     _dependants: null
  255. });
  256.  
  257. XB._base.IVariable = {
  258.     setValue: function IVariable_setValue(newValue) {
  259.         if (this._setNewVal(newValue))
  260.             this._notifyDeps();
  261.     }
  262. };
  263.  
  264. XB._base.VarNode = XB._base.DynNode.extend(XB._base.IVariable);
  265.  
  266. XB._base.IHasArguments = {
  267.     constructor: function HasArgs_constructor(baseUID, widget, argsMap) {
  268.         this.base(baseUID, widget);
  269.         this._argManager = new XB._base.FuncNode.ArgManager(this);
  270.         
  271.         for (let argName in argsMap) {
  272.             var argProto = argsMap[argName];
  273.             this._argManager.attachArgument(argName, argProto.createInstance(widget));
  274.         }
  275.     },
  276.     
  277.     _argManager: null
  278. };
  279.  
  280. XB._base.ProcNodeBase = XB._base.ConstNode.extend(XB._base.IHasArguments);
  281.  
  282. XB._base.ProcNode = XB._base.ProcNodeBase.extend({
  283.     perform: function ProcNode_perform() {
  284.         this._proc();
  285.     },
  286.     
  287.     getValue: function ProcNode_getValue() {
  288.         return this._proc();
  289.     }
  290. });
  291.  
  292. XB._base.FuncNodeBase = XB._base.DynNode.extend(XB._base.IHasArguments);
  293.  
  294. XB._base.FuncNode = XB._base.FuncNodeBase.extend({
  295.     constructor: function FuncNode_constructor() {
  296.         this.base.apply(this, arguments);
  297.         this._changedArgs = [];
  298.     },
  299.     
  300.     freeze: function FuncNode_freeze() {
  301.         this._freezeLevel++;
  302.         XB._base.logger.trace("Freezing node " + this._getHumanReadableID() + " " + this._freezeLevel);
  303.         this._freezeDeps();
  304.     },
  305.     
  306.     melt: function FuncNode_melt(changedArgNode) {
  307.         XB._base.logger.trace("Melting node " + this._getHumanReadableID() + " " + this._freezeLevel);
  308.         this._freezeLevel = Math.max(0, this._freezeLevel - 1);
  309.         if (changedArgNode)
  310.             this._changedArgs.push(changedArgNode);
  311.         
  312.         var iChanged = false;
  313.         try {
  314.             if (this._freezeLevel == 0 && this._changedArgs.length > 0) {
  315.                 XB._base.logger.trace("Node " + this._getHumanReadableID() + " recalculates");
  316.                 var newVal = this._calculateSafely();
  317.                 iChanged = this._setNewVal(newVal);
  318.             }
  319.         }
  320.         finally {
  321.             this._meltDeps(iChanged);
  322.         }
  323.     },
  324.     
  325.     getValue: function FuncNode_getValue(subscriber) {
  326.         var prevValue = this.base(subscriber);
  327.         if (prevValue === undefined) {
  328.             var newVal = this._calculateSafely();
  329.             if (this._hasSubscribers())
  330.                 this._setNewVal(newVal);
  331.             return newVal;
  332.         }
  333.         return prevValue || XB.types.empty;
  334.     },
  335.     
  336.     _freezeLevel: 0,
  337.     _changedArgs: null,
  338.     
  339.     _calculateSafely: function FuncNode_calculateSafely() {
  340.         var val;
  341.         this._argManager.resetUseStat();
  342.         try {
  343.             val = this._calculate(this._changedArgs);
  344.         }
  345.         catch (e) {
  346.             if (e instanceof XB.types.Exception)
  347.                 val = e;
  348.             else {
  349.                 val = XB._base.runtime.createXBExceptionFromRTError(this.getEffectiveID(), e);
  350.                 XB._base.logger.error(this._formatRuntimeError(e));
  351.                 if (e.stack)
  352.                     XB._base.logger.debug(e.stack);
  353.             }
  354.         }
  355.         finally {
  356.             this._changedArgs = [];
  357.             this._argManager.freeUnused();
  358.         }
  359.         return val;
  360.     }
  361. });
  362.  
  363. XB._base.FuncNode.ArgManager = function FNArgManager_constructor(managedNode) {
  364.     if ( !(managedNode instanceof XB._base.FuncNode || managedNode instanceof XB._base.ProcNode) )
  365.         throw new TypeError(this._consts.ERR_FP_NODE_EXPECTED);
  366.     this._managedNode = managedNode;
  367.     this._namedArgs = {};
  368.     this._orderedArgs = [];
  369. };
  370.  
  371. XB._base.FuncNode.ArgManager.prototype = {
  372.     constructor: XB._base.FuncNode.ArgManager,
  373.     
  374.     attachArgument: function ArgMan_AttachArgument(argName, argNode) {
  375.         if (argName == "")
  376.             throw new Error(ERR_NAME_REQUIRED);
  377.         if ( !(argNode instanceof XB._base.BoundNode) )
  378.             throw new TypeError(XB._base.consts.ERR_FUNC_NODE_EXPECTED);
  379.         
  380.         var argInfo = {
  381.             node: argNode,
  382.             used: false
  383.         };
  384.         this._argsCount = this._orderedArgs.push(argInfo);
  385.         this._namedArgs[argName] = argInfo;
  386.     },
  387.     
  388.     detachArgument: function ArgMan_DetachArgument(argName) {
  389.         var argInfo = this._namedArgs[argName];
  390.         if (!argInfo)
  391.             throw new Error(this._consts.ERR_NO_ARG);
  392.         
  393.         argInfo.used = false;
  394.         argInfo.node.unsubscribe(this._managedNode);
  395.         delete this._namedArgs[argName];
  396.     },
  397.     
  398.     resetUseStat: function ArgMan_ResetUseStat() {
  399.         for each (let argInfo in this._namedArgs)
  400.             argInfo.used = false;
  401.     },
  402.     
  403.     freeUnused: function ArgMan_FreeUnused() {
  404.         for each (let argInfo in this._namedArgs) {
  405.             if (!argInfo.used)
  406.                 argInfo.node.unsubscribe(this._managedNode);
  407.         }
  408.     },
  409.     
  410.     freeAll: function ArgMan_FreeAll() {
  411.         for each (let argInfo in this._namedArgs) {
  412.             argInfo.used = false;
  413.             argInfo.node.unsubscribe(this._managedNode);
  414.         }
  415.     },
  416.     
  417.     argExists: function ArgMan_ArgExists(argName) {
  418.         return (this._namedArgs[argName] instanceof Object);
  419.     },
  420.     
  421.     getArgsNames: function ArgMan_GetArgsNames() {
  422.         var names = [];
  423.         for (let name in this._namedArgs)
  424.             names.push(name);
  425.         return names;
  426.     },
  427.     
  428.     getValByName: function ArgMan_GetValByName(argName, preferedType) {
  429.         return this._processArgInfo(this._namedArgs[argName], preferedType);
  430.     },
  431.     
  432.     getValByIndex: function ArgMan_GetValByIndex(argIndex, preferedType) {
  433.         return this._processArgInfo(this._orderedArgs[argIndex], preferedType);
  434.     },
  435.     
  436.     getValByNameDef: function ArgMan_GetValByNameDef(argName, preferedType, defaultValue) {
  437.         if ( !(argName in this._namedArgs) )
  438.             return defaultValue;
  439.         try {
  440.             return this._processArgInfo(this._namedArgs[argName], preferedType);
  441.         }
  442.         catch (e) {
  443.             return defaultValue;
  444.         }
  445.     },
  446.     
  447.     getValByIndexDef: function ArgMan_GetValByIndexDef(argIndex, preferedType, defaultValue) {
  448.         if ( !(argIndex in this._orderedArgs) )
  449.             return defaultValue;
  450.         try {
  451.             return this._processArgInfo(this._orderedArgs[argIndex], preferedType);
  452.         }
  453.         catch (e) {
  454.             return defaultValue;
  455.         }
  456.     },
  457.     
  458.     findNodeByName: function ArgMan_GetNodeByName(argName) {
  459.         var argInfo = this._namedArgs[argName];
  460.         if (argInfo) {
  461.             argInfo.used = true;
  462.             return argInfo.node;
  463.         }
  464.         return null;
  465.     },
  466.     
  467.     findNodeByIndex: function ArgMan_GetNodeByIndex(argIndex) {
  468.         var argInfo = this._orderedArgs[argIndex];
  469.         if (argInfo) {
  470.             argInfo.used = true;
  471.             return argInfo.node;
  472.         }
  473.         return null;
  474.     },
  475.     
  476.     get argsCount() {
  477.         return this._argsCount;
  478.     },
  479.     
  480.     argInArray: function (argName, array) {
  481.         if (!(array instanceof Array))
  482.             throw new TypeError("Array expected");
  483.         var argNode = this.findNodeByName(argName);
  484.         if (!argNode)
  485.             return false;
  486.         
  487.         for each(let item in array) {
  488.             if (item === argNode)
  489.                 return true;
  490.         }
  491.         return false;
  492.     },
  493.     
  494.     _consts: {
  495.         ERR_FP_NODE_EXPECTED: "FuncNode or ProcNode instance expected",
  496.         ERR_NO_ARG: "No such argument"
  497.     },
  498.     _managedNode: null,
  499.     _namedArgs: null,
  500.     _orderedArgs: null,
  501.     _argsCount: 0,
  502.     
  503.     _processArgInfo: function ArgMan_processArgInfo(argInfo, preferedType) {
  504.         if (argInfo == undefined)
  505.             throw new Error(this._consts.ERR_NO_ARG);
  506.         argInfo.used = true;
  507.         var argVal = argInfo.node.getValue(this._managedNode._hasSubscribers()? this._managedNode: null);
  508.         if (argVal instanceof XB.types.Exception)
  509.             throw argVal;
  510.         switch(preferedType) {
  511.             case "Number":
  512.                 return XB._base.runtime.xToNumber(argVal);
  513.             case "String":
  514.                 return XB._base.runtime.xToString(argVal);
  515.             case "Bool":
  516.                 return XB._base.runtime.xToBool(argVal);
  517.             case "XML":
  518.                 return XB._base.runtime.xToXML(argVal);
  519.             case "RequestData":
  520.                 return XB._base.runtime.xToRequestData(argVal);
  521.             default:
  522.                 return argVal;
  523.         }
  524.     }
  525. };
  526.  
  527.