Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / ModelComponent.java
index 40ab62f..d543c54 100644 (file)
@@ -30,9 +30,10 @@ public abstract class ModelComponent implements JSONSerializable
         */
        protected final LogicModelModifiable model;
        /**
-        * The name of this component. Is unique for all components in its model.
+        * The name of this component. Is unique for all components in its model.<br>
+        * Does never change, but can't be final since it is set in {@link #init()}.
         */
-       public final String name;
+       private String name;
        private final Rectangle bounds;
        /**
         * The list of all pins of this component by name.
@@ -53,9 +54,20 @@ public abstract class ModelComponent implements JSONSerializable
        // creation and destruction
 
        public ModelComponent(LogicModelModifiable model, String name)
+       {
+               this(model, name, true);
+       }
+
+       /**
+        * Creates a new {@link ModelComponent} and, if <code>callInit</code>, initializes the component (See {@link #init()}).<br>
+        * If <code>callInit==false</code>, make sure to call {@link #init()}!
+        * 
+        * @author Daniel Kirschten
+        */
+       protected ModelComponent(LogicModelModifiable model, String name, boolean callInit)
        {
                this.model = model;
-               this.name = name == null ? model.getDefaultComponentName(this) : name;
+               this.name = name;
                this.bounds = new Rectangle(0, 0, 0, 0);
                this.pinsByName = new HashMap<>();
                this.pinsUnmodifiable = Collections.unmodifiableMap(pinsByName);
@@ -65,11 +77,31 @@ public abstract class ModelComponent implements JSONSerializable
                this.pinAddedListeners = new ArrayList<>();
                this.pinRemovedListeners = new ArrayList<>();
 
-               // TODO this will crash the high level state debug shell because submodel is not yet set.
-               // The same problem exists in LogicModelModifiable.getDefaultComponentName; see there
+               if (callInit)
+                       init();
+       }
+
+       /**
+        * Initializes this component. This method should be called exactly once in this component's constructor.<br>
+        * <ul>
+        * <li>If <code>{@link #name}==null</code>, sets {@link #name} to {@link LogicModelModifiable#getDefaultComponentName(ModelComponent)}.
+        * <li>Registers this component in the model.
+        * </ul>
+        */
+       protected void init()
+       {
+               if (name == null)
+                       name = model.getDefaultComponentName(this);
                model.componentCreated(this, this::destroyed);
        }
 
+       // basic getters
+
+       public String getName()
+       {
+               return name;
+       }
+
        /**
         * Destroys this component. This method is called from {@link LogicModelModifiable#componentDestroyed(ModelComponent)
         * destroyComponent()} of the model this component is a part of.<br>
@@ -136,17 +168,30 @@ public abstract class ModelComponent implements JSONSerializable
         * Returns the pin with the given name of this component.
         * 
         * @throws IllegalArgumentException if there is no pin with the given name
+        * @see #getPinOrNull(String)
         * 
         * @author Daniel Kirschten
         */
        public Pin getPin(String name)
        {
-               Pin pin = pinsByName.get(name);
+               Pin pin = getPinOrNull(name);
                if (pin == null)
                        throw new IllegalArgumentException("No pin with the name " + name);
                return pin;
        }
 
+       /**
+        * Returns the pin with the given name of this component, or <code>null</code> if there is no such pin.
+        * 
+        * @see #getPin(String)
+        * 
+        * @author Daniel Kirschten
+        */
+       public Pin getPinOrNull(String name)
+       {
+               return pinsByName.get(name);
+       }
+
        // high-level access
 
        /**