persistable sclass G22NetworkElement > MetaWithChangeListeners { // network element belongs to settable G22Network network; // position in visual representation settable Rect bounds; // identifier in network (optional) settableWithVar S identifier; // script code to adapt element and to create instance settableWithVar S code; { onChange(-> { network?.change(); }); } class Port extends MetaWithChangeListeners { // position on element's border (0 to 1, 0 to 1) settableWithVar DoublePt position; // name of port within element settableWithVar S name; // cable attached to this port (optional) settableWithVar G22NetworkCable cable; // is it output or input? settableWithVar bool isOutput; // type of object sent through port settableWithVar Class dataType; G22NetworkElement element() { ret G22NetworkElement.this; } toString { ret renderVars("Port", +name, +isOutput); } Rect bounds() { int size = 10; Rect r = element().bounds; if (r == null) null; r = growRectTopAndLeft(r, size); ret rect(r.x+iround(position.x*r.w), r.y+iround(position.y*r.h), size, size); } } L ports = syncL(); LASCompileResult newCompileResult() { ret new LASCompileResult; } transient LASCompileResult compileResult; LASCompileResult compile(G22Utils g22utils) { S code = this.code; if (code == null) null; var cr = compileResult; if (cr != null && eq(cr.script, code)) ret cr; cr = newCompileResult(); var parser = g22utils.leftArrowParser(); configureParser(parser); cr.script(code).parser(parser).compile(); ret compileResult = cr; } void configureParser(GazelleV_LeftArrowScriptParser parser) { parser.addVar("blueprint"); } GazelleV_LeftArrowScript.Script compileScript(G22Utils g22utils) null on exception { var compiled = compile(g22utils); if (compiled == null) null; if (!compiled.runnable()) null; ret compiled!; } void configureBlueprint(G22Utils g22utils) { var script = compileScript(g22utils); if (script == null) null; new FlexibleVarContext ctx; var f = script.getFunction("configure"); if (f != null) f.get(ctx, this); } O makeInstance(G22Utils g22utils) null on exception { var script = compileScript(g22utils); if (script == null) null; new FlexibleVarContext ctx; ret script.get(ctx); } toString { ret or2(identifier(), "Unnamed element"); } Port getPort(S name) { ret firstThat(ports, p -> eq(p.name, name)); } void addPort aka addSlot(S name, DoublePt etc position) { printFunctionCall("addPort", +name, +position); Port p = getPort(name); if (p != null) ret; ports.add(new Port().name(name).position(position)); change(); } void addInputPort(S name, DoublePt etc position, Class type) { Port p = getPort(name); if (p != null) ret; ports.add(new Port().name(name).position(position) .isOutput(false).dataType(type)); change(); } void addOutputPort(S name, DoublePt etc position, Class type) { Port p = getPort(name); if (p != null) ret; p = new Port().name(name).position(position) .isOutput(true).dataType(type); ports.add(p); print("Made port " + p); change(); } void removePorts aka deletePorts aka removeSlots aka deleteSlots() { ports.clear(); change(); } L ports() { ret cloneList(ports); } }