From: Fabian Stemmler Date: Sun, 2 Jun 2019 13:44:42 +0000 (+0200) Subject: BitDisplay, ManualSwitch now Observable. More Docs added in Timeline. X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=f338e2a024c8edca6ab72230747ea5e4889d8b0b;p=Mograsim.git BitDisplay, ManualSwitch now Observable. More Docs added in Timeline. --- diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/BitDisplay.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/BitDisplay.java index bc54c232..799f4124 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/BitDisplay.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/BitDisplay.java @@ -1,21 +1,27 @@ package net.mograsim.logic.core.components; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import net.mograsim.logic.core.LogicObservable; +import net.mograsim.logic.core.LogicObserver; import net.mograsim.logic.core.timeline.Timeline; import net.mograsim.logic.core.types.Bit; import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.core.wires.Wire.ReadEnd; import net.mograsim.logic.core.wires.Wire.ReadWriteEnd; -public class BitDisplay extends BasicComponent +public class BitDisplay extends BasicComponent implements LogicObservable { + private Collection observers; private final ReadEnd in; private BitVector displayedValue; public BitDisplay(Timeline timeline, ReadEnd in) { super(timeline, 1); + observers = new ArrayList<>(); this.in = in; in.registerObserver(this); compute(); @@ -25,6 +31,7 @@ public class BitDisplay extends BasicComponent protected void compute() { displayedValue = in.getValues(); + notifyObservers(); } public BitVector getDisplayedValue() @@ -48,4 +55,22 @@ public class BitDisplay extends BasicComponent { return List.of(); } + + @Override + public void registerObserver(LogicObserver ob) + { + observers.add(ob); + } + + @Override + public void deregisterObserver(LogicObserver ob) + { + observers.remove(ob); + } + + @Override + public void notifyObservers() + { + observers.forEach(ob -> ob.update(this)); + } } diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/ManualSwitch.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/ManualSwitch.java index fc6e9432..e3ae3720 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/components/ManualSwitch.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/components/ManualSwitch.java @@ -1,7 +1,11 @@ package net.mograsim.logic.core.components; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import net.mograsim.logic.core.LogicObservable; +import net.mograsim.logic.core.LogicObserver; import net.mograsim.logic.core.timeline.Timeline; import net.mograsim.logic.core.types.Bit; import net.mograsim.logic.core.wires.Wire.ReadEnd; @@ -13,14 +17,16 @@ import net.mograsim.logic.core.wires.Wire.ReadWriteEnd; * @author Christian Femers * */ -public class ManualSwitch extends Component +public class ManualSwitch extends Component implements LogicObservable { + private Collection observers; private ReadWriteEnd output; private boolean isOn; public ManualSwitch(Timeline timeline, ReadWriteEnd output) { super(timeline); + observers = new ArrayList<>(); if (output.length() != 1) throw new IllegalArgumentException("Switch output can be only a single wire"); this.output = output; @@ -47,6 +53,7 @@ public class ManualSwitch extends Component return; this.isOn = isOn; output.feedSignals(getValue()); + notifyObservers(); } public boolean isOn() @@ -71,4 +78,22 @@ public class ManualSwitch extends Component return List.of(output); } + @Override + public void registerObserver(LogicObserver ob) + { + observers.add(ob); + } + + @Override + public void deregisterObserver(LogicObserver ob) + { + observers.remove(ob); + } + + @Override + public void notifyObservers() + { + observers.forEach(ob -> ob.update(this)); + } + } diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java index 2dd5f976..e64c2cca 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java @@ -21,23 +21,33 @@ public class Timeline private final List> eventAddedListener; + public final LongSupplier stepByStepExec = () -> lastTimeUpdated; + public final LongSupplier realTimeExec = () -> System.currentTimeMillis(); + + /** + * Constructs a Timeline object. Per default the time function is set to step by step execution. + * + * @param initCapacity The initial capacity of the event queue. + */ public Timeline(int initCapacity) { events = new PriorityQueue<>(initCapacity); - eventAddedListener = new ArrayList<>(); - time = () -> lastTimeUpdated; + time = stepByStepExec; } /** * @param timestamp exclusive - * @return true if the first event is later than the timestamp + * @return true if the first event in queue is later than the given timestamp */ public BooleanSupplier laterThan(long timestamp) { return () -> timeCmp(events.peek().getTiming(), timestamp) > 0; } + /** + * @return true if there is at least one event enqueued. false otherwise + */ public boolean hasNext() { return !events.isEmpty(); @@ -53,6 +63,9 @@ public class Timeline executeUntil(laterThan(first.getTiming()), -1); } + /** + * Executes all events enqueued in the {@link Timeline}. Use very carefully! Events may generate new events, causing an infinite loop. + */ public void executeAll() { while (hasNext()) @@ -71,7 +84,6 @@ public class Timeline * EXEC_UNTIL_CONDITION if the condition was met * EXEC_UNTIL_EMPTY if events were executed until the {@link Timeline} was empty * @formatter:on - * @author Christian Femers, Fabian Stemmler */ public ExecutionResult executeUntil(BooleanSupplier condition, long stopMillis) { @@ -97,16 +109,31 @@ public class Timeline return hasNext() ? ExecutionResult.EXEC_UNTIL_EMPTY : ExecutionResult.EXEC_UNTIL_CONDITION; } + /** + * Sets the function, which defines the current simulation time at any time. + * + * @param time The return value of calling this function is the current simulation time. + */ public void setTimeFunction(LongSupplier time) { this.time = time; } + /** + * Calculates the current simulation time. + * + * @return The simulation time as defined by the time function. + */ public long getSimulationTime() { return time.getAsLong(); } + /** + * Retrieves the timestamp of the next event. + * + * @return The timestamp of the next enqueued event, if the {@link Timeline} is not empty, -1 otherwise. + */ public long nextEventTime() { if (!hasNext()) @@ -114,17 +141,26 @@ public class Timeline return events.peek().getTiming(); } + /** + * Clears the {@link Timeline} of enqueued events. + */ public void reset() { events.clear(); lastTimeUpdated = 0; } + /** + * Adds a listener, that is called when a {@link TimelineEvent} is added. + */ public void addEventAddedListener(Consumer listener) { eventAddedListener.add(listener); } + /** + * Removes the listener, if possible. It will no longer be called when a {@link TimelineEvent} is added. + */ public void removeEventAddedListener(Consumer listener) { eventAddedListener.remove(listener); @@ -185,7 +221,7 @@ public class Timeline } } - public static int timeCmp(long a, long b) + static int timeCmp(long a, long b) { return Long.signum(a - b); } diff --git a/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java b/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java index 35addff3..b26111f5 100644 --- a/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java +++ b/net.mograsim.logic.core/src/net/mograsim/logic/core/wires/Wire.java @@ -186,8 +186,7 @@ public class Wire private void notifyObservers() { - for (ReadEnd o : attached) - o.update(); + attached.forEach(r -> r.update()); } /** @@ -354,8 +353,7 @@ public class Wire @Override public void notifyObservers() { - for (LogicObserver ob : observers) - ob.update(this); + observers.forEach(ob -> ob.update(this)); } } diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIManualSwitch.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIManualSwitch.java index 8ca57ee5..a8d271e1 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIManualSwitch.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIManualSwitch.java @@ -49,7 +49,7 @@ public class GUIManualSwitch extends GUIComponent this.logicSwitch = logicSwitch; this.end = end; // TODO when ManualSwitch supports it, add listeners - end.addObserver((i, o) -> callComponentLookChangedListeners()); + end.registerObserver((i) -> callComponentLookChangedListeners()); } @Override diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java index 736c0ea6..c6c9432d 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java @@ -76,7 +76,7 @@ public class GUIWire public void setLogicModelBinding(ReadEnd end) { this.end = end; - end.addObserver((i, o) -> callWireLookChangedListeners()); + end.registerObserver((i) -> callWireLookChangedListeners()); } public Pin getPin1() diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/WireCrossPoint.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/WireCrossPoint.java index 0949ffbb..927e4e50 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/WireCrossPoint.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/WireCrossPoint.java @@ -34,7 +34,7 @@ public class WireCrossPoint extends GUIComponent public void setLogicModelBinding(ReadEnd end) { this.end = end; - end.addObserver((i, o) -> callComponentLookChangedListeners()); + end.registerObserver((i) -> callComponentLookChangedListeners()); } public int getLogicWidth()