package org.leumasjaffe.charsheet.model.observable; import java.util.Arrays; import java.util.function.Consumer; import org.leumasjaffe.observer.Observable; import org.leumasjaffe.observer.ObservableListener; import org.leumasjaffe.observer.ObserverDispatch; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.experimental.FieldDefaults; @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) public class BoolGate extends Observable.Instance { boolean[] data; int size; @AllArgsConstructor(access=AccessLevel.PRIVATE) @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) public class Handle { int index; public boolean get() { return BoolGate.this.get(index); } public void set(boolean bool) { // FIXME if (bool != get()) { BoolGate.this.set(index, bool); ObserverDispatch.notifySubscribers(BoolGate.this); } } public Meta createSubGate(int dim) { return new Meta(this, dim); } } @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) public static class Meta extends BoolGate { BoolGate.Handle callBack; private Meta(BoolGate.Handle callBack, int dim) { super(dim); this.callBack = callBack; } public ObservableListener makeListener() { ObservableListener obs = new ObservableListener<>(null, Meta::invokeCallback); obs.setObserved(this); return obs; } private static void invokeCallback(Object ignore, Meta self) { self.callBack.set(self.all()); } } public BoolGate(int dim) { size = dim; data = new boolean[dim]; Arrays.fill(data, false); } public boolean all() { for (int i = 0; i < size; ++i) { if (!data[i]) return false; } return true; } public Handle handle(int idx) { return this.new Handle(idx); } public boolean get(int idx) { return data[idx]; } public void set(int idx, boolean bool) { data[idx] = bool; } public boolean some(int...idxs) { return Arrays.stream(idxs).mapToObj(this::get).allMatch(Boolean::booleanValue); } public ObservableListener, BoolGate> makeListener(Consumer accepter) { ObservableListener, BoolGate> obs = new ObservableListener<>(accepter, (c, v) -> c.accept(v.all())); obs.setObserved(this); return obs; } }