package net.mograsim.logic.ui.examples;
import java.io.IOException;
-import java.util.HashMap;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonNull;
import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUI_rsLatch;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIfulladder;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIhalfadder;
import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
{
public static void main(String[] args)
{
- SimpleLogicUIStandalone.executeVisualisation(JsonExample::mappingTest);
+ SimpleLogicUIStandalone.executeVisualisation(JsonExample::basicTest);
}
public static void mappingTest(ViewModelModifiable model)
{
- IndirectGUIComponentCreator.create(model, "GUIAm2901", new HashMap<String, Object>());
+ IndirectGUIComponentCreator.createComponent(model, "Am2901", JsonNull.INSTANCE);
}
private static class TestComponent extends SimpleRectangularSubmodelComponent
}
}
+ @SuppressWarnings("unused") // GUIWires being created
+ private static void basicTest(ViewModelModifiable viewModel)
+ {
+ GUI_rsLatch comp = new GUI_rsLatch(viewModel);
+ comp.moveTo(30, 0);
+ SubmodelComponentParams params = comp.calculateParams();
+ String jsonString = new GsonBuilder().setPrettyPrinting().create().toJson(params);
+ System.out.println(jsonString);
+ SubmodelComponent deserialized = SubmodelComponentDeserializer.create(viewModel,
+ new Gson().fromJson(jsonString, SubmodelComponentParams.class));
+ deserialized.moveTo(30, 50);
+ double h = 0;
+ for (String s : comp.getInputPinNames())
+ {
+ GUIManualSwitch sw = new GUIManualSwitch(viewModel);
+ sw.moveTo(0, h);
+ new GUIWire(viewModel, sw.getOutputPin(), comp.getPin(s));
+ sw = new GUIManualSwitch(viewModel);
+ sw.moveTo(0, h + 50);
+ new GUIWire(viewModel, sw.getOutputPin(), deserialized.getPin(s));
+ h += 20;
+ }
+ h = 0;
+ for (String s : comp.getOutputPinNames())
+ {
+ GUIBitDisplay bd = new GUIBitDisplay(viewModel);
+ bd.moveTo(80, h);
+ new GUIWire(viewModel, bd.getInputPin(), comp.getPin(s));
+ bd = new GUIBitDisplay(viewModel);
+ bd.moveTo(80, h + 50);
+ new GUIWire(viewModel, bd.getInputPin(), deserialized.getPin(s));
+ h += 20;
+ }
+ }
+
// Execute only after HalfAdder.json has been created
public static void refJsonFromJsonTest(ViewModelModifiable model)
{
+++ /dev/null
-mograsim version: 0.1.2
-{
- "GUIAm2901": "file:components/am2901/GUIAm2901.json",
- "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
- "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
- "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
- "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
- "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
- "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
- "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
- "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
- "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
- "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
- "GUI_rsLatch": "file:components/GUI_rsLatch.json",
- "GUIand": "file:components/GUIand.json",
- "GUIand41": "file:components/GUIand41.json",
- "GUIandor414": "file:components/GUIandor414.json",
- "GUIdemux2": "file:components/GUIdemux2.json",
- "GUIdff": "file:components/GUIdff.json",
- "GUIdlatch": "file:components/GUIdlatch.json",
- "GUIdlatch4": "file:components/GUIdlatch4.json",
- "GUIfulladder": "file:components/GUIfulladder.json",
- "GUIhalfadder": "file:components/GUIhalfadder.json",
- "GUImux1": "file:components/GUImux1.json",
- "GUImux1_4": "file:components/GUImux1_4.json",
- "GUInand3": "file:components/GUInand3.json",
- "GUInot4": "file:components/GUInot4.json",
- "GUIor4": "file:components/GUIor4.json",
- "GUIor_4": "file:components/GUIor_4.json",
- "GUIram2": "file:components/GUIram2.json",
- "GUIram4": "file:components/GUIram4.json",
- "GUIsel2_4": "file:components/GUIsel2_4.json",
- "GUIsel3_4": "file:components/GUIsel3_4.json",
- "GUIxor": "file:components/GUIxor.json",
- "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
-}
\ No newline at end of file
for (GUIComponent c : model.getComponents())
if (!(c instanceof WireCrossPoint || c instanceof SubmodelInterface))
{
- String item = base + c.getIdentifier();
+ String item = base + c.getClass().getSimpleName();
componentsByItemIndex.add(c);
componentSelector.add(item);
if (c instanceof SubmodelComponent)
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import java.util.function.Consumer;
-import java.util.function.Supplier;
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
/**
* The base class for all GUI components.<br>
private final List<Runnable> redrawListeners;
private final Runnable redrawListenerForSubcomponents;
- // Defines how the GUIComponent is referenced in SubmodelComponentParams
- protected Supplier<String> identifierDelegate = () -> getClass().getSimpleName();
// creation and destruction
*/
public abstract void render(GeneralGC gc, Rectangle visibleRegion);
- // serializing
-
- /**
- * @return an identifier used to reference this GUIComponent inside of {@link SubmodelComponentParams}
- */
- public String getIdentifier()
- {
- return identifierDelegate.get();
- }
-
- @SuppressWarnings("static-method")
- public Map<String, Object> getInstantiationParameters()
- {
- return new TreeMap<>();
- }
-
// listeners
/**
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
+import net.mograsim.logic.ui.serializing.IndirectGUIComponentCreator;
public class GUINandGate extends SimpleRectangularGUIGate
{
static
{
ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINandGate.class, NandGate::new));
+ // TODO read params
+ IndirectGUIComponentCreator.setComponentProvider(GUINandGate.class.getCanonicalName(), (m, p) -> new GUINandGate(m, 1));
}
}
\ No newline at end of file
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.eclipse.swt.graphics.Color;
gc.drawText(label, getPosX() + (rectWidth - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
gc.setFont(oldFont);
}
-
- @Override
- public Map<String, Object> getInstantiationParameters()
- {
- Map<String, Object> m = super.getInstantiationParameters();
- m.put(kLogicWidth, logicWidth);
- return m;
- }
}
\ No newline at end of file
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
import org.eclipse.swt.graphics.Color;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.wires.MovablePin;
import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
import net.mograsim.preferences.Preferences;
public class SimpleRectangularSubmodelComponent extends SubmodelComponent
gc.drawRectangle(getBounds());
}
- @Override
- public SubmodelComponentParams calculateParams()
- {
- SubmodelComponentParams ret = super.calculateParams();
- ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName();
- Map<String, Object> m = new TreeMap<>();
- m.put(kLabel, label);
- m.put(kInCount, inputPinNames.toArray());
- m.put(kOutCount, outputPinNames.toArray());
- m.put(kLogicWidth, logicWidth);
- ret.specialized = m;
- return ret;
- }
-
@Override
protected Pin addSubmodelInterface(MovablePin supermodelPin)
{
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.function.Function;
import net.haspamelodica.swt.helper.gcs.GCConfig;
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.mograsim.logic.ui.model.wires.MovablePin;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerPinParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerWireParams;
import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InterfacePinParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters.InnerComponentParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams.InnerPinParams;
/**
* A {@link GUIComponent} consisting of another model. A <code>SubmodelComponent</code> can have so-called "interface pins" connecting the
return false;
}
- // serializing
+ // serializing; TODO move to serializing classes
+
+ public SubmodelComponentParams calculateParams()
+ {
+ return calculateParams(c -> "class:" + c.getClass().getCanonicalName());
+ }
/**
* @return {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}.
*/
- public SubmodelComponentParams calculateParams()
+ public SubmodelComponentParams calculateParams(Function<GUIComponent, String> getIdentifier)
{
SubmodelComponentParams params = new SubmodelComponentParams();
- params.name = getIdentifier();
- params.type = SubmodelComponent.class.getSimpleName();
- params.composition = calculateCompositionParams();
+ params.submodel = calculateSubmodelParams(getIdentifier);
params.width = getWidth();
params.height = getHeight();
return params;
}
- protected ComponentCompositionParams calculateCompositionParams()
+ private SubmodelParameters calculateSubmodelParams(Function<GUIComponent, String> getIdentifier)
{
- ComponentCompositionParams params = new ComponentCompositionParams();
+ SubmodelParameters params = new SubmodelParameters();
params.innerScale = getSubmodelScale();
- List<GUIComponent> compList = submodelModifiable.getComponents();
+ List<GUIComponent> compList = submodel.getComponents();
Iterator<GUIComponent> componentIt = compList.iterator();
componentIt.next(); // Skip inner SubmodelInterface
InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1];
GUIComponent component = componentIt.next();
InnerComponentParams inner = new InnerComponentParams();
comps[i] = inner;
- inner.params = component.getInstantiationParameters();
inner.pos = new Point(component.getPosX(), component.getPosY());
- inner.name = component.getIdentifier();
+ inner.id = getIdentifier.apply(component);
i++;
}
params.subComps = comps;
- List<GUIWire> wireList = submodelModifiable.getWires();
+ List<GUIWire> wireList = submodel.getWires();
InnerWireParams wires[] = new InnerWireParams[wireList.size()];
i = 0;
for (GUIWire wire : wireList)
package net.mograsim.logic.ui.model.wires;
-import java.util.Map;
-
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.core.LogicObserver;
import net.mograsim.logic.core.wires.Wire.ReadEnd;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.atomic.SimpleRectangularGUIGate;
+import net.mograsim.logic.ui.serializing.IndirectGUIComponentCreator;
import net.mograsim.preferences.ColorDefinition;
import net.mograsim.preferences.ColorManager;
return end != null;
}
- // serializing
-
- @Override
- public Map<String, Object> getInstantiationParameters()
+ static
{
- Map<String, Object> m = super.getInstantiationParameters();
- m.put(SimpleRectangularGUIGate.kLogicWidth, pin.logicWidth);
- return m;
+ // TODO read params
+ IndirectGUIComponentCreator.setComponentProvider(WireCrossPoint.class.getCanonicalName(), (m, p) -> new WireCrossPoint(m, 1));
}
}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.JsonElement;
+
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.serializing.snippets.Renderer;
+import net.mograsim.logic.ui.serializing.snippets.RendererProvider;
+import net.mograsim.logic.ui.util.JsonHandler;
+import net.mograsim.preferences.ColorDefinition;
+import net.mograsim.preferences.ColorManager;
+import net.mograsim.preferences.Preferences;
+
+public class CodeSnippetSupplier
+{
+ private static final Map<String, String> standardSnippetIDClassNames = new HashMap<>();
+
+ private static final Map<String, RendererProvider> outlineRendererProvidersForComponentClassNames = new HashMap<>();
+ private static final Map<String, RendererProvider> symbolRendererProvidersForComponentClassNames = new HashMap<>();
+
+ private static final RendererProvider defaultOutlineRendererProvider;
+ private static final RendererProvider defaultSymbolRendererProvider;
+ static
+ {
+ // TODO this code does not belong here
+ defaultOutlineRendererProvider = (comp, params) -> (gc, visReg) ->
+ {
+ ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.foreground");
+ if (fg != null)
+ gc.setForeground(ColorManager.current().toColor(fg));
+ gc.drawRectangle(comp.getBounds());
+ };
+ defaultSymbolRendererProvider = (comp, params) -> (gc, visReg) ->
+ {
+ ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text");
+ if (fg != null)
+ gc.setForeground(ColorManager.current().toColor(fg));
+ String id = "TODO";// TODO add an ID of sorts to DeserializedSubmodelComponent
+ Point idSize = gc.textExtent(id);
+ Rectangle bounds = comp.getBounds();
+ gc.drawText(id, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true);
+ };
+ }
+
+ static
+ {
+ try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./mapping.json"))
+ {
+ if (s == null)
+ throw new IOException("Resource not found");
+ Map<String, String> tmp = JsonHandler.readJson(s, Map.class);
+ standardSnippetIDClassNames.putAll(tmp);
+ }
+ catch (IOException e)
+ {
+ System.err.println("Failed to initialize standard snippet ID mapping: " + e.getMessage());
+ }
+ }
+
+ public static void addStandardSnippetID(String standardSnippetID, String associatedSnippetClassName)
+ {
+ standardSnippetIDClassNames.put(standardSnippetID, associatedSnippetClassName);
+ }
+
+ public static void setOutlineRendererProvider(String id, RendererProvider outlineRendererProvider)
+ {
+ outlineRendererProvidersForComponentClassNames.put(id, outlineRendererProvider);
+ }
+
+ public static void setSymbolRendererProvider(String id, RendererProvider symbolRendererProvider)
+ {
+ symbolRendererProvidersForComponentClassNames.put(id, symbolRendererProvider);
+ }
+
+ public static Renderer createOutlineRenderer(String id, DeserializedSubmodelComponent component, JsonElement params)
+ {
+ return getSnippet(id, outlineRendererProvidersForComponentClassNames, defaultOutlineRendererProvider).create(component, params);
+ }
+
+ public static Renderer createSymbolRenderer(String id, DeserializedSubmodelComponent component, JsonElement params)
+ {
+ return getSnippet(id, symbolRendererProvidersForComponentClassNames, defaultSymbolRendererProvider).create(component, params);
+ }
+
+ // TODO report errors
+ private static <C> C getSnippet(String id, Map<String, C> specializedCodeMap, C defaultSnippet)
+ {
+ if (id != null)
+ {
+ String snippetClassName;
+ if (id.startsWith("class:"))
+ snippetClassName = id.substring(6);
+ else
+ snippetClassName = standardSnippetIDClassNames.get(id);
+ if (snippetClassName != null)
+ {
+ tryLoadSnippetClass(snippetClassName);
+ C specializedCode = specializedCodeMap.get(snippetClassName);
+ if (specializedCode != null)
+ return specializedCode;
+ }
+ }
+ return defaultSnippet;
+ }
+
+ private static void tryLoadSnippetClass(String snippetClassName)
+ {
+ tryLoadClass(snippetClassName, "Error getting snippet code for component class: %s\n");
+ }
+
+ public static void tryLoadClass(String className, String errorMessageFormat)
+ {
+ try
+ {
+ CodeSnippetSupplier.class.getClassLoader().loadClass(className);
+ }
+ catch (@SuppressWarnings("unused") ClassNotFoundException e)
+ {
+ System.err.printf(errorMessageFormat, className);
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.serializing;
-
-import java.util.function.Supplier;
-
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
-
-/**
- * A {@link SimpleRectangularSubmodelComponent} which was created by deserializing a JSON file.
- *
- * @author Daniel Kirschten
- */
-public class DeserializedSimpleRectangularSubmodelComponent extends SimpleRectangularSubmodelComponent
- implements DeserializedSubmodelComponentI
-{
- public DeserializedSimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
- {
- super(model, logicWidth, label);
- }
-
- @Override
- public ViewModelModifiable getSubmodelModifiable()
- {
- return submodelModifiable;
- }
-
- @Override
- public void setIdentifierDelegate(Supplier<String> identifierDelegate)
- {
- this.identifierDelegate = identifierDelegate;
- }
-
- @Override
- public void setSubmodelScale(double submodelScale)
- {
- super.setSubmodelScale(submodelScale);
- }
-
- @Override
- public void setInputPins(String... pinNames)
- {
- super.setInputPins(pinNames);
- }
-
- @Override
- public void setOutputPins(String... pinNames)
- {
- super.setOutputPins(pinNames);
- }
-}
\ No newline at end of file
package net.mograsim.logic.ui.serializing;
-import java.util.function.Supplier;
-
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
import net.mograsim.logic.ui.model.wires.MovablePin;
import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.serializing.snippets.Renderer;
-public class DeserializedSubmodelComponent extends SubmodelComponent implements DeserializedSubmodelComponentI
+public class DeserializedSubmodelComponent extends SubmodelComponent
{
+ public Renderer outlineRenderer;
+ public Renderer symbolRenderer;
+
public DeserializedSubmodelComponent(ViewModelModifiable model)
{
super(model);
@Override
protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
{
- // TODO
+ if (outlineRenderer != null)
+ outlineRenderer.render(gc, visibleRegion);
}
@Override
protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
{
- // TODO
+ if (symbolRenderer != null)
+ symbolRenderer.render(gc, visibleRegion);
}
- @Override
- public ViewModelModifiable getSubmodelModifiable()
+ public void setOutlineRenderer(Renderer outlineRenderer)
{
- return submodelModifiable;
+ this.outlineRenderer = outlineRenderer;
}
- @Override
- public void setIdentifierDelegate(Supplier<String> identifierDelegate)
+ public void setSymbolRenderer(Renderer symbolRenderer)
{
- this.identifierDelegate = identifierDelegate;
+ this.symbolRenderer = symbolRenderer;
+ }
+
+ public ViewModelModifiable getSubmodelModifiable()
+ {
+ return submodelModifiable;
}
@Override
+++ /dev/null
-package net.mograsim.logic.ui.serializing;
-
-import java.util.function.Supplier;
-
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
-
-/**
- * A {@link SubmodelComponent} which was created by deserializing a JSON file.
- *
- * @author Daniel Kirschten
- */
-public interface DeserializedSubmodelComponentI
-{
- public ViewModelModifiable getSubmodelModifiable();
-
- /**
- * Sets the identifier delegate used by this deserialized component.
- *
- * @author Daniel Kirschten
- */
- public void setIdentifierDelegate(Supplier<String> identifierDelegate);
-}
\ No newline at end of file
import java.io.IOException;
import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
+import com.google.gson.JsonElement;
+
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.atomic.SimpleRectangularGUIGate;
-import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
-import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.ui.util.JsonHandler;
public class IndirectGUIComponentCreator
{
- private final static Map<String, String> componentMapping;
+ private static final Map<String, String> standardComponentIDs = new HashMap<>();
+
+ private static final Map<String, ComponentProvider> componentProviders = new HashMap<>();
static
{
- Map<String, String> tmp;
- try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./mapping.json"))
+ try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./standardComponentIDMapping.json"))
{
- tmp = JsonHandler.readJson(s, Map.class);
+ if (s == null)
+ throw new IOException("Resource not found");
+ Map<String, String> tmp = JsonHandler.readJson(s, Map.class);
+ // don't use putAll to apply sanity checks
+ tmp.forEach((st, id) ->
+ {
+ try
+ {
+ addStandardComponentID(st, id);
+ }
+ catch (IllegalArgumentException e)
+ {
+ System.err.println("Component ID mapping contained illegal entry: " + e.getMessage());
+ }
+ });
}
catch (IOException e)
{
- System.err.println("Failed to initialize component mapping; Components cannot be created from file.");
- e.printStackTrace();
- tmp = new HashMap<>();
+ System.err.println("Failed to initialize standard snippet ID mapping: " + e.getMessage());
}
- componentMapping = tmp;
}
- public static GUIComponent create(ViewModelModifiable model, String name, Map<String, Object> params)
+ public static void addStandardComponentID(String standardComponentID, String associatedComponentID)
+ {
+ if (!associatedComponentID.startsWith("file:") && !associatedComponentID.startsWith("class:"))
+ throw new IllegalArgumentException("Unrecognized component ID format: " + associatedComponentID);
+ standardComponentIDs.put(standardComponentID, associatedComponentID);
+ }
+
+ public static void setComponentProvider(String className, ComponentProvider componentProvider)
+ {
+ componentProviders.put(className, componentProvider);
+ }
+
+ public static GUIComponent createComponent(ViewModelModifiable model, String id, JsonElement params)
{
- try
+ if (id != null)
{
- String path = componentMapping.get(name);
- if (path.startsWith("class:"))
+ String resolvedID;
+ if (id.startsWith("class:") || id.startsWith("file:"))
+ resolvedID = id;
+ else
+ resolvedID = standardComponentIDs.get(id);
+ if (resolvedID.startsWith("class:"))
{
- path = path.substring(6);
- return createComponentFromClass(model, path, params);
- } else if (path.startsWith("file:"))
- {
- path = path.substring(5);
- return SubmodelComponentDeserializer.create(model, path);
+ String className = resolvedID.substring(6);
+ tryLoadComponentClass(className);
+ ComponentProvider componentProvider = componentProviders.get(className);
+ if (componentProvider != null)
+ return componentProvider.create(model, params);
} else
- throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
- }
- catch (NullPointerException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
- | SecurityException | ClassNotFoundException | IllegalArgumentException e)
- {
- System.err.println("Failed to create requested component!");
- e.printStackTrace();
- return new SimpleRectangularSubmodelComponent(model, 1, "ERROR");
+ // we know id has to start with "file:" here
+ // because standardComponentIDs only contains strings starting with "class:" or "file:"
+ return SubmodelComponentDeserializer.create(model, resolvedID.substring(5));
}
+ throw new RuntimeException("Could not get component provider for ID " + id);
}
- private static GUIComponent createComponentFromClass(ViewModelModifiable model, String classname, Map<String, Object> params)
- throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
- ClassNotFoundException
+ private static void tryLoadComponentClass(String componentClassName)
{
- Class<?> c = Class.forName(classname);
- Object comp;
- if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
- {
- Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
- comp = constructor.newInstance(model, ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
- } else
- {
- Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
- comp = constructor.newInstance(model);
- }
- return (GUIComponent) comp;
+ CodeSnippetSupplier.tryLoadClass(componentClassName, "Error loading component class %s\n");
+ }
+
+ public static interface ComponentProvider
+ {
+ public GUIComponent create(ViewModelModifiable model, JsonElement params);
}
-}
+}
\ No newline at end of file
package net.mograsim.logic.ui.serializing;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.GUIComponent;
import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.MovablePin;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerWireParams;
import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InterfacePinParams;
-import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters.InnerComponentParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams;
/**
* Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
*/
public final class SubmodelComponentDeserializer
{
- private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
-
/**
* Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
* SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
*/
public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params)
{
- DeserializedSubmodelComponentI comp = null;
- if (rectC.equals(params.type))
- {
- comp = createRectComponent(model, params);
- }
-
- if (comp == null)
- {
- comp = createSubmodelComponent(model, params);
- }
- comp.setIdentifierDelegate(() -> params.name);
- initInnerComponents(comp, params.composition);
- return (SubmodelComponent) comp;
- }
-
- // May return null
- @SuppressWarnings("unchecked")
- private static DeserializedSimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model,
- SubmodelComponentParams params)
- {
- try
- {
- Map<String, Object> m = params.specialized;
- DeserializedSimpleRectangularSubmodelComponent rect = new DeserializedSimpleRectangularSubmodelComponent(model,
- ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
- (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
- rect.setSubmodelScale(params.composition.innerScale);
-
- Object[] names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kInCount)).toArray();
- rect.setInputPins(Arrays.copyOf(names, names.length, String[].class));
-
- names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kOutCount)).toArray();
- rect.setOutputPins(Arrays.copyOf(names, names.length, String[].class));
-
- return rect;
- }
- catch (ClassCastException | NullPointerException e)
- {
- System.err.println("Failed to specialize component!");
- e.printStackTrace();
- return null;
- }
+ DeserializedSubmodelComponent comp = createSubmodelComponent(model, params);
+ initSubmodel(comp, params.submodel);
+ return comp;
}
private static DeserializedSubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
{
DeserializedSubmodelComponent comp = new DeserializedSubmodelComponent(model);
- comp.setSubmodelScale(params.composition.innerScale);
+ comp.setSubmodelScale(params.submodel.innerScale);
+ comp.setOutlineRenderer(
+ CodeSnippetSupplier.createOutlineRenderer(params.outlineRendererSnippetClass, comp, params.outlineRendererParams));
+ comp.setSymbolRenderer(
+ CodeSnippetSupplier.createSymbolRenderer(params.symbolRendererSnippetClass, comp, params.symbolRendererParams));
+ // TODO high level states
comp.setSize(params.width, params.height);
for (InterfacePinParams iPinParams : params.interfacePins)
- {
comp.addSubmodelInterface(
new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y));
- }
return comp;
}
@SuppressWarnings("unused")
- private static void initInnerComponents(DeserializedSubmodelComponentI comp, ComponentCompositionParams params)
+ private static void initSubmodel(DeserializedSubmodelComponent comp, SubmodelParameters params)
{
GUIComponent[] components = new GUIComponent[params.subComps.length];
for (int i = 0; i < components.length; i++)
{
InnerComponentParams cParams = params.subComps[i];
- String path = cParams.name;
- components[i] = IndirectGUIComponentCreator.create(comp.getSubmodelModifiable(), cParams.name, cParams.params);
+ String path = cParams.id;
+ components[i] = IndirectGUIComponentCreator.createComponent(comp.getSubmodelModifiable(), cParams.id, cParams.params);
components[i].moveTo(cParams.pos.x, cParams.pos.y);
}
package net.mograsim.logic.ui.serializing;
import java.io.IOException;
-import java.util.Map;
+
+import com.google.gson.JsonElement;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
*/
public class SubmodelComponentParams
{
- public String type, name;
+ // basic stuff
public double width, height;
public InterfacePinParams[] interfacePins;
- public ComponentCompositionParams composition;
- public Map<String, Object> specialized;
+ public SubmodelParameters submodel;
+
+ // functionality that needs to be expressed in Java code
+ public String outlineRendererSnippetClass;
+ public JsonElement outlineRendererParams;
+
+ public String symbolRendererSnippetClass;
+ public JsonElement symbolRendererParams;
public static class InterfacePinParams
{
public int logicWidth;
}
- public static class InnerWireParams
- {
- public InnerPinParams pin1, pin2;
- public Point[] path;
- }
-
- public static class InnerPinParams
- {
- public int compId;
- public String pinName;
- }
-
- public static class ComponentCompositionParams
+ public static class SubmodelParameters
{
public double innerScale;
public InnerComponentParams[] subComps;
public static class InnerComponentParams
{
public Point pos;
- public String name;
- public Map<String, Object> params;
+ public String id;
+ public JsonElement params;
+ }
+
+ public static class InnerWireParams
+ {
+ public InnerPinParams pin1, pin2;
+ public Point[] path;
+
+ public static class InnerPinParams
+ {
+ public int compId;
+ public String pinName;
+ }
}
}
+++ /dev/null
-mograsim version: 0.1.2
-{
- "GUIAm2901": "file:components/am2901/GUIAm2901.json",
- "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
- "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
- "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
- "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
- "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
- "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
- "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
- "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
- "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
- "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
- "GUI_rsLatch": "file:components/GUI_rsLatch.json",
- "GUIand": "file:components/GUIand.json",
- "GUIand41": "file:components/GUIand41.json",
- "GUIandor414": "file:components/GUIandor414.json",
- "GUIdemux2": "file:components/GUIdemux2.json",
- "GUIdff": "file:components/GUIdff.json",
- "GUIdlatch": "file:components/GUIdlatch.json",
- "GUIdlatch4": "file:components/GUIdlatch4.json",
- "GUIfulladder": "file:components/GUIfulladder.json",
- "GUIhalfadder": "file:components/GUIhalfadder.json",
- "GUImux1": "file:components/GUImux1.json",
- "GUImux1_4": "file:components/GUImux1_4.json",
- "GUInand3": "file:components/GUInand3.json",
- "GUInot4": "file:components/GUInot4.json",
- "GUIor4": "file:components/GUIor4.json",
- "GUIor_4": "file:components/GUIor_4.json",
- "GUIram2": "file:components/GUIram2.json",
- "GUIram4": "file:components/GUIram4.json",
- "GUIsel2_4": "file:components/GUIsel2_4.json",
- "GUIsel3_4": "file:components/GUIsel3_4.json",
- "GUIxor": "file:components/GUIxor.json",
- "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
-}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing.snippets;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+
+public interface Renderer
+{
+ public void render(GeneralGC t, Rectangle u);
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing.snippets;
+
+import com.google.gson.JsonElement;
+
+import net.mograsim.logic.ui.serializing.DeserializedSubmodelComponent;
+
+public interface RendererProvider
+{
+ public Renderer create(DeserializedSubmodelComponent component, JsonElement params);
+}
\ No newline at end of file
--- /dev/null
+mograsim version: 0.1.2
+{
+ "GUIAm2901": "file:components/am2901/GUIAm2901.json",
+ "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
+ "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
+ "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
+ "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
+ "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
+ "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
+ "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
+ "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
+ "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
+ "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
+ "GUI_rsLatch": "file:components/GUI_rsLatch.json",
+ "GUIand": "file:components/GUIand.json",
+ "GUIand41": "file:components/GUIand41.json",
+ "GUIandor414": "file:components/GUIandor414.json",
+ "GUIdemux2": "file:components/GUIdemux2.json",
+ "GUIdff": "file:components/GUIdff.json",
+ "GUIdlatch": "file:components/GUIdlatch.json",
+ "GUIdlatch4": "file:components/GUIdlatch4.json",
+ "GUIfulladder": "file:components/GUIfulladder.json",
+ "GUIhalfadder": "file:components/GUIhalfadder.json",
+ "GUImux1": "file:components/GUImux1.json",
+ "GUImux1_4": "file:components/GUImux1_4.json",
+ "GUInand3": "file:components/GUInand3.json",
+ "GUInot4": "file:components/GUInot4.json",
+ "GUIor4": "file:components/GUIor4.json",
+ "GUIor_4": "file:components/GUIor_4.json",
+ "GUIram2": "file:components/GUIram2.json",
+ "GUIram4": "file:components/GUIram4.json",
+ "GUIsel2_4": "file:components/GUIsel2_4.json",
+ "GUIsel3_4": "file:components/GUIsel3_4.json",
+ "GUIxor": "file:components/GUIxor.json",
+ "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
+}
\ No newline at end of file