Commits

Michael Ludwig committed 692cc40

Guarantee that isEnabled() returns false for dead components. Add Iterator convenience wrapper for a single component type. Support private factory constructors

  • Participants
  • Parent commits 0650224

Comments (0)

Files changed (4)

File src/main/java/com/lhkbob/entreri/Component.java

     }
 
     /**
-     * @return True if this component is enabled, or false if it is disabled and
-     *         will appear as though it doesn't exist under default behavior
+     * Return true if this component is enabled, or false if it is disabled and
+     * will appear as though it doesn't exist under default behavior. False is
+     * always returned if the component is not live.
+     * 
+     * @return True if enabled
      */
     public boolean isEnabled() {
         // if isLive() returns false, index references the 0th index, which
         // just contains garbage
-        return owner.isEnabled(index);
+        return isLive() && owner.isEnabled(index);
     }
 
     /**

File src/main/java/com/lhkbob/entreri/ComponentData.java

      * Return whether or not the component this data is attached to is enabled.
      * This is an optimized shortcut for <code>getComponent().isEnabled()</code>
      * 
-     * @return True if the component is enabled
+     * @return True if the component is enabled, false if disabled or invalid
      */
     public final boolean isEnabled() {
-        return owner.isEnabled(index);
+        return index != 0 && owner.isEnabled(index);
     }
 
     /**

File src/main/java/com/lhkbob/entreri/EntitySystem.java

      * 
      * @return An iterator over the entities of the system
      */
+    @Override
     public Iterator<Entity> iterator() {
         return new EntityIterator();
     }
+    
+    /**
+     * Return an iterator over all components of with the given type. The
+     * returned iterator reuses a single ComponentData instance of T, so it is a
+     * fast iterator. This effectively wraps a {@link ComponentIterator} in a
+     * standard {@link Iterator} with a single required component type.
+     * 
+     * @param id The type of component to iterate over
+     * @return A fast iterator over components in this system
+     */
+    public <T extends ComponentData<T>> Iterator<T> iterator(TypeId<T> id) {
+        return new ComponentIteratorWrapper<T>(id);
+    }
 
     /**
      * <p>
         }
     }
     
+    private class ComponentIteratorWrapper<T extends ComponentData<T>> implements Iterator<T> {
+        private final T data;
+        private final ComponentIterator it;
+        
+        private boolean nextCalled;
+        private boolean hasNext;
+        
+        public ComponentIteratorWrapper(TypeId<T> type) {
+            data = createDataInstance(type);
+            it = new ComponentIterator(EntitySystem.this);
+            it.addRequired(data);
+            
+            nextCalled = false;
+            hasNext = false;
+        }
+        
+        @Override
+        public boolean hasNext() {
+            if (!nextCalled) {
+                hasNext = it.next();
+                nextCalled = true;
+            }
+            return hasNext;
+        }
+
+        @Override
+        public T next() {
+            if (!hasNext())
+                throw new NoSuchElementException();
+            nextCalled = false;
+            return data;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+    
     private class EntityIterator implements Iterator<Entity> {
         private int index;
         private boolean advanced;

File src/main/java/com/lhkbob/entreri/ReflectionComponentDataFactory.java

             paramTypes[i] = args[i].getClass();
         
         try {
-            Constructor<?> ctor = type.getConstructor(paramTypes);
+            // must use getDeclaredConstructor in case the class type is private
+            // or the constructor is not public
+            Constructor<?> ctor = type.getDeclaredConstructor(paramTypes);
             ctor.setAccessible(true);
             return (PropertyFactory<?>) ctor.newInstance(args);
         } catch (SecurityException e) {