Libraryless. Click here for Pure Java version (27227L/191K).
sinterface IBEAReactor { BEAObject uniqResult(Class<? extends BEAObject> c, O... params); } extend BEAObject { bool canReactWith(BEAObject o) { ret isInstanceOfAny(o, (Cl) reactableWithClasses()); } Cl<Class<? extends BEAObject>> reactableWithClasses() { ret (Cl) collectFirstMethodArguments(findMethodsNamed_nonSynthetic(this, "reactWith")); } } beaConcept BReactor {} concept Reactable { BEAObject a, b; } asclass DynBEAReactor > DynCRUD_v2<BEAObject> { S input, output; switchable int maxObjects = 1000; transient new BEAUtils beaUtils; transient new Concepts reactableConcepts; transient ReliableSingleThread rstUpdateReactables = dm_rstWithDelay(this, 100, r updateReactables); transient JTabbedPane bottomTabs; { tableFontSize = 15; } start { ensureConceptClassIsIndexed(BEAObject); crud.humanizeFieldNames = false; crud.showBackRefs = true; crud.specialFieldsForItem = a -> { MapSO map = litorderedmap(crud.hID, str(a.id)); S j = crud.javaClassDescForItem(a); mapPut(map, "Class/Type", joinUniqueNemptiesCI("/", j, a.type())); ret map; }; crud.itemToMap_inner = a -> { MapSO map = crud.itemToMap_inner_base(a); map.remove("type"); ret map; }; onConceptChangesAndNow(rstUpdateReactables); thread { createInitialObjects(); } } void createInitialObjects {} visualize { JConceptsTable<Reactable> tblReactables = new(reactableConcepts, Reactable); JComponent c = jvsplit(0.75, 100, jCenteredSection("Objects", super.visualize()), bottomTabs = jtabs("Reactables", withRightAlignedButtons( tblReactables, "React all", rThreadEnter reactAll, "React until output", rThreadEnter reactUntilOutput, jPopDownButton_noText("Update reactables", rstUpdateReactables)))); tablePopupMenuFirst(tblReactables.table(), (menu, row) -> { Reactable r = tblReactables.getItem(row); printVars_str(+row, +r); ret if r == null; addMenuItem(menu, "React", rThreadEnter { BEAReactor reactor = new("Manually triggered reaction"); reactor.react(r.a, r.b); }); }); tablePopupMenuFirst(table(), (menu, row) -> { BEAObject o = getItem(row); print("Item: " + o); if (o == null) ret; pcall { L<BEAObject> partners = filter(list(BEAObject), partner -> o.canReactWith(partner)); if (nempty(partners)) addScrollingSubMenu(menu, "React with", menu2 -> { for (BEAObject p : partners) addMenuItem(menu2, str(p), rThread { new BEAReactor("User reacts " + o + " with " + p).react(o, p); }); }); } }); addButton("Delete reactors", rThreadEnter deleteReactors); addButton(jPopDownButton_noText(popDownButtonEntries())); ret c; } // end of visualize O[] popDownButtonEntries() { ret litobjectarray( "Export all objects", rThreadEnter exportAllObjects, "Import objects [TODO]", rThread importObjects, ); } void exportAllObjects { S text = indentStructureString(dm_mainConceptsStructWithExplicitMarkers()); //dm_showExtraFrame("Export all objects", withCenteredButtons(jTextArea_wordWrap(text))); dm_showTextInCodeEditor(text); } void importObjects { dm_showExtraFrame("Import objects", withCenteredButtons(jTextArea_wordWrap())); } class BEAReactor { BReactor reactorConcept; *(S purpose) { reactorConcept = cnew BReactor(+purpose); } void react(BEAObject a, BEAObject b) { call(a, 'reactWith, b, new IBEAReactor { public BEAObject uniqResult(Class<? extends BEAObject> c, O... params) { BEAObject product = cnew(c, paramsPlus(params, _fromReaction := ll(a, b), _reactor := reactorConcept)); product = beaUtils.autoMigrate(product); BEAObject existing = findExisting(product); print("Existing for " + product + ": " + existing); if (existing != null) { cdelete(product); ret existing; } else { onReactionProduct(product); ret product; } } }); } } // find an existing reactor-made object with the same values BEAObject findExisting(BEAObject o) { MapSO map = allConceptFieldsAsMap(o); removeAll(map, "_reactor", "globalID"); //print(+map); ret firstThat(conceptsWhere(o.getClass(), mapToParams(map)), a -> a.getClass() == o.getClass() && a != o && cget _reactor(a) != null); } void onReactionProduct(BEAObject a) pcall { if (a.typeIs("output")) setField(output := getStringOpt text(a)); } void deleteReactors { deleteConcepts(BEAObject, o -> cget _reactor(o) != null || o.typeIs("reactor")); } void updateReactables { deleteConcepts(reactableConcepts); L<BEAObject> objects = list(BEAObject); for (BEAObject a : objects) for (BEAObject b : filter(objects, b -> a.canReactWith(b))) cnew(reactableConcepts, Reactable, +a, +b); } BEAReactor reactAll() { Cl<Reactable> l = list(reactableConcepts, Reactable); if (empty(l)) null; BEAReactor reactor = new("User clicked \"react all\""); for (Reactable r : l) pcall { reactor.react(r.a, r.b); } ret reactor; } bool hasOutput() { false; } void reactUntilOutput { while (!hasOutput() && countConcepts(BEAObject) < maxObjects) { rstUpdateReactables.waitUntilDone(); int count = countConcepts(BEAObject); BEAReactor reactor = reactAll(); if (countConcepts(BEAObject) <= count+oneIf(reactor != null)) break; // +1 because of reactor } } }
Began life as a copy of #1030774
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030775 |
Snippet name: | DynBEAReactor |
Eternal ID of this version: | #1030775/22 |
Text MD5: | 6264c8c98c4a951ccf6f9a07e2bcd2bd |
Transpilation MD5: | d6b251f5a3f0541e2dd1fdff40ac5558 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-03-31 15:04:25 |
Source code size: | 6079 bytes / 199 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 251 / 513 |
Version history: | 21 change(s) |
Referenced in: | [show references] |