MCPcopy Create free account
hub / github.com/OpenEndedGroup/Field2 / Watches

Class Watches

src/main/java/fieldbox/boxes/Watches.java:20–111  ·  view source on GitHub ↗

Plugin: Watches for properties being changed and then fires change events off to the message bus.

Source from the content-addressed store, hash-verified

18 * Plugin: Watches for properties being changed and then fires change events off to the message bus.
19 */
20public class Watches extends Box {
21
22 private final MessageQueue<Quad<Dict.Prop, Box, Object, Object>, String> messageQueue;
23 static public final Dict.Prop<Watches> watches = new Dict.Prop<>("_watches").type().toCanon();
24
25 public Watches(MessageQueue<Quad<Dict.Prop, Box, Object, Object>, String> messageQueue) {
26 this.messageQueue = messageQueue;
27 this.properties.putToMap(Boxes.insideRunLoop, "main.__watch_updator__", this::update);
28 this.properties.put(watches, this);
29 }
30
31 public Watches()
32 {
33 this.messageQueue = new MessageQueue<Quad<Dict.Prop, Box, Object, Object>, String>() {
34 @Override
35 protected Consumer<Boolean> makeQueueServiceThread(BiConsumer<String, Quad<Dict.Prop, Box, Object, Object>> to) {
36
37 CompletableFuture<Boolean> stop = new CompletableFuture<Boolean>();
38
39 RunLoop.main.getLoop().attach(0, (x) -> {
40 try {
41 if (this.queue.size() > 0) Log.log("debug.messages", ()->" message queue :" + this.queue.size());
42
43 while (this.queue.peek() != null) {
44 Pair<String, Quad<Dict.Prop, Box, Object, Object>> m = this.queue.poll(1, TimeUnit.SECONDS);
45 if (m != null && !stop.isDone()) to.accept(m.first, m.second);
46 }
47 } catch (InterruptedException e) {
48 e.printStackTrace();
49 }
50 });
51
52 return x -> {
53 };
54 }
55 };
56 this.properties.putToMap(Boxes.insideRunLoop, "main.__watch_updator__", this::update);
57 this.properties.put(watches, this);
58 }
59
60 static public final Dict.Prop<LinkedHashMap<Dict.Prop, Object>> watchedPrevious = new Dict.Prop<>("_watchedPrevious");
61
62 SetMultimap<Dict.Prop, String> allWatches = MultimapBuilder.linkedHashKeys().linkedHashSetValues().build();
63
64 protected boolean update() {
65
66 breadthFirst(both()).forEach((x) -> {
67 LinkedHashMap<Dict.Prop, Object> previous = x.properties.computeIfAbsent(watchedPrevious, (k) -> new LinkedHashMap<>());
68 for (Dict.Prop p : allWatches .keySet()) {
69 Object was = previous.get(p);
70 Object now = x.properties.get(p);
71
72 if (!Util.safeEq(was, now))
73 {
74 fire(p, x, was, now, allWatches .get(p));
75 // fetch it again, fire can change the value of the property
76 now = x.properties.get(p);
77 previous.put(p, now instanceof Mutable ? ((Mutable)now).duplicate() : now);

Callers

nothing calls this directly

Calls 3

toCanonMethod · 0.80
typeMethod · 0.80
buildMethod · 0.45

Tested by

no test coverage detected