Jelajahi Sumber

#91 fix event mismatch

Ranides Atterwim 3 tahun lalu
induk
melakukan
837276ac94

+ 77 - 0
assira.commons/src/main/java/net/ranides/assira/observable/GenericMapEvent.java

@@ -0,0 +1,77 @@
+package net.ranides.assira.observable;
+
+import lombok.RequiredArgsConstructor;
+import net.ranides.assira.collection.prototype.GenericKey;
+import net.ranides.assira.collection.prototype.GenericMap;
+import net.ranides.assira.events.Event;
+
+public interface GenericMapEvent<K> extends Event {
+
+    GenericMap<K> map();
+
+    @RequiredArgsConstructor
+    class Remove<K> implements GenericMapEvent<K> {
+        private final GenericMap<K> map;
+        private final GenericKey<K,?> key;
+        private final Object value;
+
+        public GenericMap<K> map() {
+            return map;
+        }
+
+        public GenericKey<K,?> key() {
+            return key;
+        }
+
+        public Object value() {
+            return value;
+        }
+    }
+
+    @RequiredArgsConstructor
+    class Clear<K> implements GenericMapEvent<K> {
+        private final GenericMap<K> map;
+
+        public GenericMap<K> map() {
+            return map;
+        }
+    }
+
+    @RequiredArgsConstructor
+    class Put<K> implements GenericMapEvent<K> {
+        private final GenericMap<K> map;
+        private final GenericKey<K,?> key;
+        private final Object previous;
+        private final Object value;
+
+        public GenericMap<K> map() {
+            return map;
+        }
+
+        public GenericKey<K,?> key() {
+            return key;
+        }
+
+        public Object previous() {
+            return previous;
+        }
+
+        public Object value() {
+            return value;
+        }
+    }
+
+    @RequiredArgsConstructor
+    class PutAll<K> implements GenericMapEvent<K> {
+        private final GenericMap<K> map;
+        private final GenericMap<? extends K> values;
+
+        public GenericMap<K> map() {
+            return map;
+        }
+
+        public GenericMap<? extends K> values() {
+            return values;
+        }
+    }
+}

+ 12 - 1
assira.commons/src/main/java/net/ranides/assira/observable/ObservableCollection.java

@@ -28,7 +28,7 @@ public class ObservableCollection<T> extends ACollection<T> {
 
     @Override
     public Iterator<T> iterator() {
-        return new ObservableIterator<>(router, collection, collection.iterator());
+        return new CIterator(collection.iterator());
     }
 
     @Override
@@ -80,4 +80,15 @@ public class ObservableCollection<T> extends ACollection<T> {
             router.signalEvent(new CollectionEvent.Clear<>(collection));
         }
     }
+
+    private class CIterator extends ObservableIterator<T> {
+        public CIterator(Iterator<T> itr) {
+            super(itr);
+        }
+
+        @Override
+        protected void signalRemove(T value) {
+            router.signalEvent(new CollectionEvent.Remove<>(ObservableCollection.this, value));
+        }
+    }
 }

+ 46 - 1
assira.commons/src/main/java/net/ranides/assira/observable/ObservableGenericMap.java

@@ -1,12 +1,19 @@
 package net.ranides.assira.observable;
 
 import net.ranides.assira.collection.maps.OpenMultiMap;
+import net.ranides.assira.collection.prototype.GenericKey;
+import net.ranides.assira.collection.prototype.GenericMap;
 import net.ranides.assira.collection.prototype.OpenGenericMap;
 import net.ranides.assira.collection.utils.HashCollection;
+import net.ranides.assira.events.EventListener;
 import net.ranides.assira.events.EventRouter;
 
+import java.util.Map;
+
 public class ObservableGenericMap<K> extends OpenGenericMap<K> {
 
+    private final EventRouter router;
+
     public ObservableGenericMap(EventRouter router) {
         this(router, HashCollection.INITIAL_SIZE, HashCollection.LOAD_FACTOR);
     }
@@ -16,7 +23,45 @@ public class ObservableGenericMap<K> extends OpenGenericMap<K> {
     }
 
     public ObservableGenericMap(EventRouter router, int capacity, float factor) {
-        super(new ObservableMap<>(router, new OpenMultiMap<>(capacity, factor)));
+        super(true);
+        this.router = router;
+        this.map = new ObservableContent(router, new OpenMultiMap<>(capacity, factor));
+    }
+
+    public EventRouter router() {
+        return router;
+    }
+
+    public <E extends GenericMapEvent<K>> void addEventListener(Class<E> event, EventListener<? super E> listener) {
+        router.addEventListener(event, listener);
+    }
+
+    private final class ObservableContent extends ObservableMap<GenericKey<K,?>, Object> {
+
+        public ObservableContent(EventRouter router, Map<GenericKey<K, ?>, Object> map) {
+            super(router, map);
+        }
+
+        @Override
+        protected void signalRemove(GenericKey<K, ?> key, Object prev) {
+            router.signalEvent(new GenericMapEvent.Remove<>(ObservableGenericMap.this, key, prev));
+        }
+
+        @Override
+        protected void signalClear() {
+            router.signalEvent(new GenericMapEvent.Clear<>(ObservableGenericMap.this));
+        }
+
+        @Override
+        protected void signalPut(GenericKey<K, ?> key, Object prev, Object value) {
+            router.signalEvent(new GenericMapEvent.Put<>(ObservableGenericMap.this, key, prev, value));
+        }
+
+        @Override
+        protected void signalPutAll(Map<? extends GenericKey<K, ?>, ?> m) {
+            router.signalEvent(new GenericMapEvent.PutAll<>(ObservableGenericMap.this, GenericMap.wrap((Map)m)) );
+        }
+
     }
 
 }

+ 10 - 14
assira.commons/src/main/java/net/ranides/assira/observable/ObservableIterator.java

@@ -1,36 +1,32 @@
 package net.ranides.assira.observable;
 
-import lombok.RequiredArgsConstructor;
-import net.ranides.assira.events.EventRouter;
-
-import java.util.Collection;
 import java.util.Iterator;
 
-class ObservableIterator<T> implements Iterator<T> {
-    private final EventRouter router;
-    private final Collection<T> source;
+public abstract class ObservableIterator<T> implements Iterator<T> {
+
     private final Iterator<T> itr;
+
     private T last;
 
-    public ObservableIterator(EventRouter router, Collection<T> source, Iterator<T> itr) {
-        this.router = router;
-        this.source = source;
+    public ObservableIterator(Iterator<T> itr) {
         this.itr = itr;
     }
 
     @Override
-    public boolean hasNext() {
+    public final boolean hasNext() {
         return itr.hasNext();
     }
 
     @Override
-    public T next() {
+    public final T next() {
         return last = itr.next();
     }
 
     @Override
-    public void remove() {
+    public final void remove() {
         itr.remove();
-        router.signalEvent(new CollectionEvent.Remove<>(source, last));
+        signalRemove(last);
     }
+
+    protected abstract void signalRemove(T value);
 }

+ 31 - 7
assira.commons/src/main/java/net/ranides/assira/observable/ObservableList.java

@@ -1,17 +1,20 @@
 package net.ranides.assira.observable;
 
-import lombok.RequiredArgsConstructor;
 import net.ranides.assira.events.EventListener;
 import net.ranides.assira.events.EventRouter;
 
 import java.util.*;
 
-@RequiredArgsConstructor
-class ObservableList<T> extends AbstractList<T> {
+public class ObservableList<T> extends AbstractList<T> {
+
+    private final EventRouter router;
 
     private final List<T> list;
 
-    private final EventRouter router;
+    public ObservableList(EventRouter router, List<T> list) {
+        this.router = router;
+        this.list = list;
+    }
 
     public EventRouter router() {
         return router;
@@ -73,17 +76,17 @@ class ObservableList<T> extends AbstractList<T> {
 
     @Override
     public Iterator<T> iterator() {
-        return new ObservableListIterator<>(router, list, list.listIterator());
+        return new CIterator(list.listIterator());
     }
 
     @Override
     public ListIterator<T> listIterator() {
-        return new ObservableListIterator<>(router, list, list.listIterator());
+        return new CIterator(list.listIterator());
     }
 
     @Override
     public ListIterator<T> listIterator(int index) {
-        return new ObservableListIterator<>(router, list, list.listIterator(index));
+        return new CIterator(list.listIterator(index));
     }
 
     @Override
@@ -112,4 +115,25 @@ class ObservableList<T> extends AbstractList<T> {
         }
         return false;
     }
+
+    private class CIterator extends ObservableListIterator<T> {
+        public CIterator(ListIterator<T> itr) {
+            super(itr);
+        }
+
+        @Override
+        protected void signalSet(T previous, T value) {
+            router.signalEvent(new ListEvent.Set<>(list, previous, value));
+        }
+
+        @Override
+        protected void signalAdd(T value) {
+            router.signalEvent(new ListEvent.Add<>(list, value));
+        }
+
+        @Override
+        protected void signalRemove(T value) {
+            router.signalEvent(new ListEvent.Remove<>(list, value));
+        }
+    }
 }

+ 24 - 22
assira.commons/src/main/java/net/ranides/assira/observable/ObservableListIterator.java

@@ -1,67 +1,69 @@
 package net.ranides.assira.observable;
 
-import net.ranides.assira.events.EventRouter;
-
-import java.util.List;
 import java.util.ListIterator;
 
-class ObservableListIterator<T> implements ListIterator<T> {
-    private final EventRouter router;
-    private final List<T> source;
+public abstract class ObservableListIterator<T> implements ListIterator<T> {
+
     private final ListIterator<T> itr;
+
     private T last;
 
-    public ObservableListIterator(EventRouter router, List<T> source, ListIterator<T> itr) {
-        this.source = source;
+    public ObservableListIterator(ListIterator<T> itr) {
         this.itr = itr;
-        this.router = router;
     }
 
     @Override
-    public boolean hasNext() {
+    public final boolean hasNext() {
         return itr.hasNext();
     }
 
     @Override
-    public T next() {
+    public final T next() {
         return last = itr.next();
     }
 
     @Override
-    public boolean hasPrevious() {
+    public final boolean hasPrevious() {
         return itr.hasPrevious();
     }
 
     @Override
-    public T previous() {
+    public final T previous() {
         return last = itr.previous();
     }
 
     @Override
-    public int nextIndex() {
+    public final int nextIndex() {
         return itr.nextIndex();
     }
 
     @Override
-    public int previousIndex() {
+    public final int previousIndex() {
         return itr.previousIndex();
     }
 
     @Override
-    public void set(T t) {
+    public final void set(T t) {
         itr.set(t);
-        router.signalEvent(new ListEvent.Set<>(source, last, t));
+        signalSet(last, t);
     }
 
     @Override
-    public void add(T t) {
+    public final void add(T t) {
         itr.add(t);
-        router.signalEvent(new ListEvent.Add<>(source, t));
+        signalAdd(t);
     }
 
     @Override
-    public void remove() {
+    public final void remove() {
         itr.remove();
-        router.signalEvent(new ListEvent.Remove<>(source, last));
+        signalRemove(last);
     }
-}
+
+    protected abstract void signalSet(T previous, T value);
+
+    protected abstract void signalAdd(T value);
+
+    protected abstract void signalRemove(T value);
+
+}

+ 32 - 14
assira.commons/src/main/java/net/ranides/assira/observable/ObservableMap.java

@@ -11,20 +11,11 @@ import java.util.Set;
 
 public class ObservableMap<K,V> extends AMap<K,V> {
 
-    private final Map<K,V> src;
-
     private final Map<K,V> map;
 
     private final EventRouter router;
 
     public ObservableMap(EventRouter router, Map<K, V> map) {
-        this.src = map;
-        this.map = map;
-        this.router = router;
-    }
-
-    protected ObservableMap(EventRouter router, Map<K,V> src, Map<K, V> map) {
-        this.src = map;
         this.map = map;
         this.router = router;
     }
@@ -37,6 +28,22 @@ public class ObservableMap<K,V> extends AMap<K,V> {
         router.addEventListener(event, listener);
     }
 
+    protected void signalPut(K key, V prev, V value) {
+        router.signalEvent(new MapEvent.Put<>(this, key, prev, value));
+    }
+
+    protected void signalRemove(K key, V prev) {
+        router.signalEvent(new MapEvent.Remove<>(this, key, prev));
+    }
+
+    protected void signalPutAll(Map<? extends K, ? extends V> m) {
+        router.signalEvent(new MapEvent.PutAll<>(this, m));
+    }
+
+    protected void signalClear() {
+        router.signalEvent(new MapEvent.Clear<>(this));
+    }
+
     @Override
     public int size() {
         return map.size();
@@ -65,7 +72,7 @@ public class ObservableMap<K,V> extends AMap<K,V> {
     @Override
     public V put(K key, V value) {
         V prev = map.put(key, value);
-        router.signalEvent(new MapEvent.Put<>(map, key, prev, value));
+        signalPut(key, prev, value);
         return prev;
     }
 
@@ -73,7 +80,7 @@ public class ObservableMap<K,V> extends AMap<K,V> {
     public V remove(Object key) {
         V prev = map.remove(key);
         if(prev != null) {
-            router.signalEvent(new MapEvent.Remove<>(src, (K)key, prev));
+            signalRemove((K) key, prev);
         }
         return prev;
     }
@@ -81,13 +88,13 @@ public class ObservableMap<K,V> extends AMap<K,V> {
     @Override
     public void putAll(Map<? extends K, ? extends V> m) {
         map.putAll(m);
-        router.signalEvent(new MapEvent.PutAll<>(src, m));
+        signalPutAll(m);
     }
 
     @Override
     public void clear() {
         map.clear();
-        router.signalEvent(new MapEvent.Clear<>(src));
+        signalClear();
     }
 
     @Override
@@ -96,7 +103,7 @@ public class ObservableMap<K,V> extends AMap<K,V> {
             @Override
             public Iterator<Entry<K, V>> iterator() {
                 Set<Entry<K, V>> entries = map.entrySet();
-                return new ObservableIterator<>(router, entries, entries.iterator());
+                return new CIterator(entries.iterator());
             }
 
             @Override
@@ -119,4 +126,15 @@ public class ObservableMap<K,V> extends AMap<K,V> {
             }
         };
     }
+
+    private class CIterator extends ObservableIterator<Entry<K, V>> {
+        public CIterator(Iterator<Entry<K, V>> itr) {
+            super(itr);
+        }
+
+        @Override
+        protected void signalRemove(Entry<K, V> entry) {
+            router.signalEvent(new MapEvent.Remove<K,V>(ObservableMap.this, entry.getKey(), entry.getValue()));
+        }
+    }
 }

+ 30 - 2
assira.commons/src/main/java/net/ranides/assira/observable/ObservablePrototypeMap.java

@@ -28,9 +28,9 @@ public class ObservablePrototypeMap extends PrototypeMap {
     }
 
     private ObservablePrototypeMap(boolean direct, EventRouter router, PrototypeMap parent, Map<Object, Object> content) {
-        super(direct, null, null);
+        super(true);
         this.parent = parent;
-        this.declared = new ObservableMap<>(router, this, content);
+        this.declared = new ObservableContent(router, content);
         this.router = router;
     }
 
@@ -42,4 +42,32 @@ public class ObservablePrototypeMap extends PrototypeMap {
         router.addEventListener(event, listener);
     }
 
+    private final class ObservableContent extends ObservableMap<Object, Object> {
+
+        public ObservableContent(EventRouter router, Map<Object, Object> map) {
+            super(router, map);
+        }
+
+        @Override
+        protected void signalRemove(Object key, Object prev) {
+            router.signalEvent(new MapEvent.Remove<>(ObservablePrototypeMap.this, key, prev));
+        }
+
+        @Override
+        protected void signalClear() {
+            router.signalEvent(new MapEvent.Clear<>(ObservablePrototypeMap.this));
+        }
+
+        @Override
+        protected void signalPut(Object key, Object prev, Object value) {
+            router.signalEvent(new MapEvent.Put<>(ObservablePrototypeMap.this, key, prev, value));
+        }
+
+        @Override
+        protected void signalPutAll(Map<? extends Object, ?> m) {
+            router.signalEvent(new MapEvent.PutAll<>(ObservablePrototypeMap.this, m) );
+        }
+
+    }
+
 }

+ 13 - 2
assira.commons/src/main/java/net/ranides/assira/observable/ObservableSet.java

@@ -8,7 +8,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Set;
 
-class ObservableSet<T> extends ASet<T> {
+public class ObservableSet<T> extends ASet<T> {
 
     private final EventRouter router;
 
@@ -29,7 +29,7 @@ class ObservableSet<T> extends ASet<T> {
 
     @Override
     public Iterator<T> iterator() {
-        return new ObservableIterator<>(router, collection, collection.iterator());
+        return new CIterator(collection.iterator());
     }
 
     @Override
@@ -81,4 +81,15 @@ class ObservableSet<T> extends ASet<T> {
             router.signalEvent(new CollectionEvent.Clear<>(collection));
         }
     }
+
+    private class CIterator extends ObservableIterator<T> {
+        public CIterator(Iterator<T> itr) {
+            super(itr);
+        }
+
+        @Override
+        protected void signalRemove(T value) {
+            router.signalEvent(new CollectionEvent.Remove<>(ObservableSet.this, value));
+        }
+    }
 }

+ 4 - 0
assira.core/src/main/java/net/ranides/assira/collection/prototype/GenericMap.java

@@ -33,6 +33,10 @@ import java.util.function.Function;
  */
 public interface GenericMap<K> {
 
+    static <K> GenericMap<K> wrap(Map<GenericKey<K,?>, Object> map) {
+        return new OpenGenericMap<>(map);
+    }
+
     /**
      * Returns size of map
      *

+ 7 - 2
assira.core/src/main/java/net/ranides/assira/collection/prototype/OpenGenericMap.java

@@ -25,7 +25,7 @@ import net.ranides.assira.reflection.util.ClassUtils;
 @SuppressWarnings("unchecked")
 public class OpenGenericMap<K> implements GenericMap<K> {
     
-    private final Map<GenericKey<K,?>, Object> map;
+    protected Map<GenericKey<K,?>, Object> map;
 
     /**
      * Creates new empty map
@@ -65,6 +65,11 @@ public class OpenGenericMap<K> implements GenericMap<K> {
         putAll(m);
     }
 
+    protected OpenGenericMap(boolean empty) {
+        assert empty : "this is constructor for empty map";
+        this.map = Collections.emptyMap();
+    }
+
     @Override
     public int size() {
         return map.size();
@@ -101,7 +106,7 @@ public class OpenGenericMap<K> implements GenericMap<K> {
     }
 
     @Override
-    public final void putAll(GenericMap<? extends K> m) {
+    public void putAll(GenericMap<? extends K> m) {
         if(m instanceof OpenGenericMap<?>) {
             map.putAll(((OpenGenericMap)m).map);
         } else {

+ 1 - 7
assira.core/src/main/java/net/ranides/assira/collection/prototype/PrototypeMap.java

@@ -70,18 +70,12 @@ public class PrototypeMap extends AMap<Object, Object> implements Map<Object, Ob
         this.declared = new OpenMap<>(content);
     }
 
-    private PrototypeMap(boolean empty) {
+    protected PrototypeMap(boolean empty) {
         assert empty : "this is constructor for empty map";
         this.parent = null;
         this.declared = Collections.emptyMap();
     }
 
-    protected PrototypeMap(boolean direct, PrototypeMap parent, Map<Object, Object> content) {
-        assert direct : "this is constructor for direct map";
-        this.parent = parent;
-        this.declared = content;
-    }
-
     /**
      * Returns prototype, or null
      *