X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.ui%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2Fserializing%2FIndirectGUIComponentCreator.java;h=ba713bd563178d6e2087a26f19b0e6f1af3c949e;hb=5897a6d81c418d27ca5bb402e5f1038e10a191fb;hp=f60b4034206953d7c3b79a2c2aff097287828ebe;hpb=1e4c26b6d59f2cc40ce5af657c54ce65788e2c43;p=Mograsim.git diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/serializing/IndirectGUIComponentCreator.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/serializing/IndirectGUIComponentCreator.java index f60b4034..ba713bd5 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/serializing/IndirectGUIComponentCreator.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/serializing/IndirectGUIComponentCreator.java @@ -2,78 +2,90 @@ package net.mograsim.logic.ui.serializing; 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 componentMapping; + private static final Map standardComponentIDs = new HashMap<>(); + + private static final Map componentProviders = new HashMap<>(); static { - Map 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 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 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 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