X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.model.am2900%2Ftest%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fam2900%2FTestEnvironmentHelper.java;fp=net.mograsim.logic.model.am2900%2Ftest%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fam2900%2FTestEnvironmentHelper.java;h=0000000000000000000000000000000000000000;hb=6d28e5c93c9347784950ca66fb6d1b3a14461ece;hp=9ac40307f211bf75cb49426741824764a8b67346;hpb=9b34381259d5e6cb46bd3834712311cd60317506;p=Mograsim.git diff --git a/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/TestEnvironmentHelper.java b/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/TestEnvironmentHelper.java deleted file mode 100644 index 9ac40307..00000000 --- a/net.mograsim.logic.model.am2900/test/net/mograsim/logic/model/am2900/TestEnvironmentHelper.java +++ /dev/null @@ -1,257 +0,0 @@ -package net.mograsim.logic.model.am2900; - -import static org.junit.jupiter.api.Assertions.fail; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Objects; -import java.util.Queue; -import java.util.Set; -import java.util.TreeSet; - -import net.mograsim.logic.core.components.BitDisplay; -import net.mograsim.logic.core.components.ManualSwitch; -import net.mograsim.logic.core.timeline.Timeline; -import net.mograsim.logic.model.am2900.TestableCircuit.Result; -import net.mograsim.logic.model.model.ViewModel; -import net.mograsim.logic.model.model.ViewModelModifiable; -import net.mograsim.logic.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.atomic.GUIBitDisplay; -import net.mograsim.logic.model.model.components.atomic.GUIManualSwitch; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.model.wires.GUIWire; -import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.modeladapter.LogicModelParameters; -import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter; -import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; -import net.mograsim.logic.model.util.ModellingTool; - -public class TestEnvironmentHelper -{ - private final TestableCircuit testEnvInstance; - private final Class testEnvClass; - private final String modelId; - private Field componentField; - private Field timelineField; - - private GUIComponent component; - private Timeline timeline; - private ViewModelModifiable viewModel; - private ModellingTool modellingTool; - private HashMap idSwitchMap = new HashMap<>(); - private HashMap idDisplayMap = new HashMap<>(); - - private DebugState debug = DebugState.NO_DEBUG; - private Set wireDebugChangeSet; - private boolean debugWires = false; - public int debugEventThreshold = 10_000; - public int debugEventCount = 500; - private int eventCounter; - - public TestEnvironmentHelper(TestableCircuit testEnv, String modelId) - { - this.testEnvInstance = testEnv; - this.modelId = modelId; - this.testEnvClass = testEnvInstance.getClass(); - for (Field f : testEnvClass.getDeclaredFields()) - { - if (GUIComponent.class.isAssignableFrom(f.getType())) - { - componentField = f; - componentField.setAccessible(true); - } else if (Timeline.class.isAssignableFrom(f.getType())) - { - timelineField = f; - timelineField.setAccessible(true); - } - } - if (componentField == null || timelineField == null) - throw new IllegalStateException("No component or timeline field found!"); - } - - public void setup(DebugState debug) - { - this.debug = debug; - // Create view model - viewModel = new ViewModelModifiable(); - modellingTool = ModellingTool.createFor(viewModel); - component = IndirectGUIComponentCreator.createComponent(viewModel, modelId); - setField(componentField, component); - - component.getPins().values().forEach(this::extendModelPin); - - // Create logic model - LogicModelParameters params = new LogicModelParameters(); - params.gateProcessTime = 50; - params.wireTravelTime = 10; - timeline = ViewLogicModelAdapter.convert(viewModel, params); - setField(timelineField, timeline); - - // Bind switches/displays to this test class - component.getPins().values().forEach(this::bindModelPin); - - if (debug == DebugState.DEBUG_AT_PERFORMANCE_COST) - { - setupDebugging(); - } - timeline.addEventAddedListener(te -> eventCounter++); - } - - private void extendModelPin(Pin p) - { - String javaIdentId = idToJavaIdentifier(p.name); - try - { - Field f = testEnvClass.getDeclaredField(javaIdentId); - Class type = f.getType(); - if (ManualSwitch.class.isAssignableFrom(type)) - { - GUIManualSwitch gms = new GUIManualSwitch(viewModel, p.logicWidth); - modellingTool.connect(p, gms.getOutputPin()); - idSwitchMap.put(p.name, gms); - } else if (BitDisplay.class.isAssignableFrom(type)) - { - GUIBitDisplay gbd = new GUIBitDisplay(viewModel, p.logicWidth); - modellingTool.connect(p, gbd.getInputPin()); - idDisplayMap.put(p.name, gbd); - } else if (SwitchWithDisplay.class.isAssignableFrom(type)) - { - SwitchWithDisplay swd = new SwitchWithDisplay(viewModel, p); - setField(f, swd); - } else - { - fail("unkown field type " + type); - } - } - catch (NoSuchFieldException | SecurityException e) - { - fail(e); - } - } - - private void bindModelPin(Pin p) - { - String javaIdentId = idToJavaIdentifier(p.name); - if (idDisplayMap.containsKey(p.name)) - setField(javaIdentId, idDisplayMap.get(p.name).getBitDisplay()); - if (idSwitchMap.containsKey(p.name)) - setField(javaIdentId, idSwitchMap.get(p.name).getManualSwitch()); - } - - private void setupDebugging() - { - // Debug code - HashSet wiresIncludingSubmodels = new HashSet<>(); - Queue modelsToIterate = new LinkedList<>(); - modelsToIterate.add(viewModel); - while (modelsToIterate.size() > 0) - { - ViewModel model = modelsToIterate.poll(); - wiresIncludingSubmodels.addAll(model.getWiresByName().values()); - for (GUIComponent comp : model.getComponentsByName().values()) - if (comp instanceof SubmodelComponent) - modelsToIterate.offer(((SubmodelComponent) comp).submodel); - } - System.out.println(wiresIncludingSubmodels.size()); - viewModel.setRedrawHandler(() -> wiresIncludingSubmodels.forEach(w -> - { - if (debugWires) - { - wireDebugChangeSet.add(w.toString()); - } - })); - } - - public Result run() - { - // Normal execution until completion or eventLimit - int eventLimit = debugEventThreshold; - eventCounter = 0; - debugWires = false; - while (eventCounter < eventLimit) - { - timeline.executeNext(); - if (!timeline.hasNext()) - return Result.SUCCESS; - } - - // Start debugging if event limit is reached (if debug is active) - if (debug == DebugState.DEBUG_AT_PERFORMANCE_COST) - return debugThisRun(); - - return Result.OUT_OF_TIME; - } - - private Result debugThisRun() - { - int eventLimit = debugEventThreshold; - debugWires = true; - wireDebugChangeSet = new TreeSet<>(); - Set oldChangeSet; - // observe wire changes to detect, if we are really stuck in an endless loop - do - { - eventLimit += debugEventCount; - oldChangeSet = wireDebugChangeSet; - wireDebugChangeSet = new TreeSet<>(); - while (eventCounter < eventLimit) - { - timeline.executeNext(); - if (!timeline.hasNext()) - { - // no endless loop, but more events needed than expected - System.out.println("run() took longer than expected: " + eventCounter); - return Result.SUCCESS; - } - } - } while (!oldChangeSet.equals(wireDebugChangeSet)); - // if stuck, abort execution and print wires - System.err.print("Problematic Wire updates:"); - wireDebugChangeSet.forEach(System.out::println); - System.err.println("run() failed: " + eventCounter); - return Result.OUT_OF_TIME; - } - - private static String idToJavaIdentifier(String s) - { - StringBuilder sb = new StringBuilder(s.length()); - char c = s.charAt(0); - sb.append(Character.isJavaIdentifierStart(c) ? c : '_'); - for (int i = 1; i < s.length(); i++) - sb.append(Character.isJavaIdentifierPart(c = s.charAt(i)) ? c : '_'); - return sb.toString(); - } - - private void setField(Field f, S value) - { - try - { - f.set(testEnvInstance, Objects.requireNonNull(value)); - } - catch (Exception e) - { - fail(e); - } - } - - private void setField(String name, S value) - { - try - { - Field f = testEnvClass.getDeclaredField(name); - f.setAccessible(true); - f.set(testEnvInstance, Objects.requireNonNull(value)); - } - catch (Exception e) - { - fail(e); - } - } - - public enum DebugState - { - NO_DEBUG, DEBUG_AT_PERFORMANCE_COST; - } -}