cables_dev/cables/src/core/core_link.js
- import { CONSTANTS } from "./constants.js";
- import { EventTarget } from "./eventtarget.js";
-
- /**
- * @namespace external:CABLES#Link
- * @param {Object} scene The patch object
- * @description a link is a connection between two ops/ports -> one input and one output port
- * @hideconstructor
- * @class
- */
- const Link = function (scene)
- {
- EventTarget.apply(this);
-
- this.id = CABLES.simpleId();
- this.portIn = null;
- this.portOut = null;
- this.scene = scene; // todo: make private and rename to patch
- this.activityCounter = 0;
- this.ignoreInSerialize = false;
- };
-
- Link.prototype.setValue = function (v)
- {
- if (v === undefined) this._setValue();
- else this.portIn.set(v);
- };
-
- Link.prototype.activity = function ()
- {
- this.activityCounter++;
- // if(Date.now()-this.lastTime>100)
- // {
- // // this.lastTime=Date.now();
- // // this.changesPerSecond=this.changesCounter*10;
- // this.changesCounter=0;
- // }
- };
-
- Link.prototype._setValue = function ()
- {
- if (!this.portOut)
- {
- this.remove();
- return;
- }
- const v = this.portOut.get();
-
- if (v == v) // NaN is the only JavaScript value that is treated as unequal to itself
- {
- if (this.portIn.type != CONSTANTS.OP.OP_PORT_TYPE_FUNCTION) this.activity();
-
- if (this.portIn.get() !== v)
- {
- this.portIn.set(v);
- }
- else
- {
- if (this.portIn.changeAlways) this.portIn.set(v);
- if (this.portOut.forceRefChange) this.portIn.forceChange();
- }
- }
- };
-
- /**
- * @function getOtherPort
- * @memberof Link
- * @instance
- * @param {Port} p port
- * @description returns the port of the link, which is not port
- */
- Link.prototype.getOtherPort = function (p)
- {
- if (p == this.portIn) return this.portOut;
- return this.portIn;
- };
-
- /**
- * @function remove
- * @memberof Link
- * @instance
- * @description unlink/remove this link from all ports
- */
- Link.prototype.remove = function ()
- {
- if (this.portIn) this.portIn.removeLink(this);
- if (this.portOut) this.portOut.removeLink(this);
- if (this.scene)
- {
- this.scene.emitEvent("onUnLink", this.portIn, this.portOut, this);
- }
-
- if (this.portIn && (this.portIn.type == CONSTANTS.OP.OP_PORT_TYPE_OBJECT || this.portIn.type == CONSTANTS.OP.OP_PORT_TYPE_ARRAY))
- {
- this.portIn.set(null);
- if (this.portIn.links.length > 0) this.portIn.set(this.portIn.links[0].getOtherPort(this.portIn).get());
- }
-
- if (this.portIn) this.portIn.op._checkLinksNeededToWork();
- if (this.portOut) this.portOut.op._checkLinksNeededToWork();
-
- this.portIn = null;
- this.portOut = null;
- this.scene = null;
- };
-
- /**
- * @function link
- * @memberof Link
- * @instance
- * @description link those two ports
- * @param {Port} p1 port1
- * @param {Port} p2 port2
- */
- Link.prototype.link = function (p1, p2)
- {
- if (!Link.canLink(p1, p2))
- {
- console.warn("[core_link] cannot link ports!", p1, p2);
- return false;
- }
-
- if (p1.direction == CONSTANTS.PORT.PORT_DIR_IN)
- {
- this.portIn = p1;
- this.portOut = p2;
- }
- else
- {
- this.portIn = p2;
- this.portOut = p1;
- }
-
- p1.addLink(this);
- p2.addLink(this);
-
- this.setValue();
-
- if (p1.onLink) p1.onLink(this);
- if (p2.onLink) p2.onLink(this);
-
- p1.op._checkLinksNeededToWork();
- p2.op._checkLinksNeededToWork();
- };
-
- Link.prototype.getSerialized = function ()
- {
- const obj = {};
-
- obj.portIn = this.portIn.getName();
- obj.portOut = this.portOut.getName();
- obj.objIn = this.portIn.op.id;
- obj.objOut = this.portOut.op.id;
-
- return obj;
- };
-
- // --------------------------------------------
-
- /**
- * @function canLinkText
- * @memberof Link
- * @instance
- * @description return a text message with human readable reason if ports can not be linked, or can be
- * @param {Port} p1 port1
- * @param {Port} p2 port2
- */
- Link.canLinkText = function (p1, p2)
- {
- if (p1.direction == p2.direction)
- {
- let txt = "(out)";
- if (p2.direction == CONSTANTS.PORT.PORT_DIR_IN) txt = "(in)";
- return "can not link: same direction " + txt;
- }
- if (p1.op == p2.op) return "can not link: same op";
- if (p1.type != CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC && p2.type != CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC)
- {
- if (p1.type != p2.type) return "can not link: different type";
- }
-
- if (CABLES.UI && p1.type == CONSTANTS.OP.OP_PORT_TYPE_OBJECT && p2.type == CONSTANTS.OP.OP_PORT_TYPE_OBJECT)
- {
- if (p1.uiAttribs.objType && p2.uiAttribs.objType)
- if (p1.uiAttribs.objType != p2.uiAttribs.objType)
- return "incompatible objects";
- }
-
-
- if (!p1) return "can not link: port 1 invalid";
- if (!p2) return "can not link: port 2 invalid";
-
- if (p1.direction == CONSTANTS.PORT.PORT_DIR_IN && p1.isAnimated()) return "can not link: is animated";
- if (p2.direction == CONSTANTS.PORT.PORT_DIR_IN && p2.isAnimated()) return "can not link: is animated";
-
- // if(p1.direction==CABLES.CONSTANTS.PORT.PORT_DIR_IN && p1.links.length>0)return 'input port already busy';
- // if(p2.direction==CABLES.CONSTANTS.PORT.PORT_DIR_IN && p2.links.length>0)return 'input port already busy';
- if (p1.isLinkedTo(p2)) return "ports already linked";
-
- if ((p1.canLink && !p1.canLink(p2)) || (p2.canLink && !p2.canLink(p1))) return "Incompatible";
-
- return "can link";
- };
-
- /**
- * @function canLink
- * @memberof Link
- * @instance
- * @description return true if ports can be linked
- * @param {Port} p1 port1
- * @param {Port} p2 port2
- * @returns {Boolean}
- */
- Link.canLink = function (p1, p2)
- {
- if (!p1) return false;
- if (!p2) return false;
- if (p1.direction == CONSTANTS.PORT.PORT_DIR_IN && p1.isAnimated()) return false;
- if (p2.direction == CONSTANTS.PORT.PORT_DIR_IN && p2.isAnimated()) return false;
-
- if (p1.isHidden() || p2.isHidden()) return false;
-
- if (p1.isLinkedTo(p2)) return false;
-
- if (p1.direction == p2.direction) return false;
-
- if (CABLES.UI && p1.type == CONSTANTS.OP.OP_PORT_TYPE_OBJECT && p2.type == CONSTANTS.OP.OP_PORT_TYPE_OBJECT)
- {
- if (p1.uiAttribs.objType && p2.uiAttribs.objType)
- {
- if (p1.uiAttribs.objType.indexOf("sg_") == 0 && p2.uiAttribs.objType.indexOf("sg_") == 0) return true;
- if (p1.uiAttribs.objType != p2.uiAttribs.objType)
- return false;
- }
- }
-
- if (p1.type != p2.type && (p1.type != CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC && p2.type != CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC)) return false;
- if (p1.type == CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC || p2.type == CONSTANTS.OP.OP_PORT_TYPE_DYNAMIC) return true;
-
- if (p1.op == p2.op) return false;
-
- if (p1.canLink && !p1.canLink(p2)) return false;
- if (p2.canLink && !p2.canLink(p1)) return false;
-
- return true;
- };
-
- export { Link };