62014ca0168b6ad36d223a21bf7f545954471aef
[Mograsim.git] / net.mograsim.logic.ui / src / net / mograsim / logic / ui / serializing / CodeSnippetSupplier.java
1 package net.mograsim.logic.ui.serializing;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import com.google.gson.JsonElement;
9
10 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
11 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
12 import net.mograsim.logic.ui.serializing.snippets.Renderer;
13 import net.mograsim.logic.ui.serializing.snippets.RendererProvider;
14 import net.mograsim.logic.ui.util.JsonHandler;
15 import net.mograsim.preferences.ColorDefinition;
16 import net.mograsim.preferences.ColorManager;
17 import net.mograsim.preferences.Preferences;
18
19 public class CodeSnippetSupplier
20 {
21         private static final Map<String, String> standardSnippetIDClassNames = new HashMap<>();
22
23         private static final Map<String, RendererProvider> outlineRendererProvidersForComponentClassNames = new HashMap<>();
24         private static final Map<String, RendererProvider> symbolRendererProvidersForComponentClassNames = new HashMap<>();
25
26         private static final RendererProvider defaultOutlineRendererProvider;
27         private static final RendererProvider defaultSymbolRendererProvider;
28         static
29         {
30                 // TODO this code does not belong here
31                 defaultOutlineRendererProvider = (comp, params) -> (gc, visReg) ->
32                 {
33                         ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.foreground");
34                         if (fg != null)
35                                 gc.setForeground(ColorManager.current().toColor(fg));
36                         gc.drawRectangle(comp.getBounds());
37                 };
38                 defaultSymbolRendererProvider = (comp, params) -> (gc, visReg) ->
39                 {
40                         ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text");
41                         if (fg != null)
42                                 gc.setForeground(ColorManager.current().toColor(fg));
43                         String id = "TODO";// TODO add an ID of sorts to DeserializedSubmodelComponent
44                         Point idSize = gc.textExtent(id);
45                         Rectangle bounds = comp.getBounds();
46                         gc.drawText(id, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true);
47                 };
48         }
49
50         static
51         {
52                 try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./standardSnippetIDMapping.json"))
53                 {
54                         if (s == null)
55                                 throw new IOException("Resource not found");
56                         Map<String, String> tmp = JsonHandler.readJson(s, Map.class);
57                         standardSnippetIDClassNames.putAll(tmp);
58                 }
59                 catch (IOException e)
60                 {
61                         System.err.println("Failed to initialize standard snippet ID mapping: " + e.getMessage());
62                 }
63         }
64
65         public static void addStandardSnippetID(String standardSnippetID, String associatedSnippetClassName)
66         {
67                 standardSnippetIDClassNames.put(standardSnippetID, associatedSnippetClassName);
68         }
69
70         public static void setOutlineRendererProvider(String id, RendererProvider outlineRendererProvider)
71         {
72                 outlineRendererProvidersForComponentClassNames.put(id, outlineRendererProvider);
73         }
74
75         public static void setSymbolRendererProvider(String id, RendererProvider symbolRendererProvider)
76         {
77                 symbolRendererProvidersForComponentClassNames.put(id, symbolRendererProvider);
78         }
79
80         public static Renderer createOutlineRenderer(String id, DeserializedSubmodelComponent component, JsonElement params)
81         {
82                 return getSnippet(id, outlineRendererProvidersForComponentClassNames, defaultOutlineRendererProvider).create(component, params);
83         }
84
85         public static Renderer createSymbolRenderer(String id, DeserializedSubmodelComponent component, JsonElement params)
86         {
87                 return getSnippet(id, symbolRendererProvidersForComponentClassNames, defaultSymbolRendererProvider).create(component, params);
88         }
89
90         // TODO report errors
91         private static <C> C getSnippet(String id, Map<String, C> specializedCodeMap, C defaultSnippet)
92         {
93                 if (id != null)
94                 {
95                         String snippetClassName;
96                         if (id.startsWith("class:"))
97                                 snippetClassName = id.substring(6);
98                         else
99                                 snippetClassName = standardSnippetIDClassNames.get(id);
100                         if (snippetClassName != null)
101                         {
102                                 tryLoadSnippetClass(snippetClassName);
103                                 C specializedCode = specializedCodeMap.get(snippetClassName);
104                                 if (specializedCode != null)
105                                         return specializedCode;
106                         }
107                 }
108                 return defaultSnippet;
109         }
110
111         private static void tryLoadSnippetClass(String snippetClassName)
112         {
113                 tryInvokeStaticInitializer(snippetClassName, "Error getting snippet code for component class: %s: %s\n");
114         }
115
116         public static void tryInvokeStaticInitializer(String className, String errorMessageFormat)
117         {
118                 try
119                 {
120                         Class.forName(className, true, CodeSnippetSupplier.class.getClassLoader());
121                 }
122                 catch (ClassNotFoundException e)
123                 {
124                         System.err.printf(errorMessageFormat, className, "ClassNotFoundException thrown: " + e.getMessage());
125                 }
126         }
127 }