View Javadoc

1   /*
2    * Entreri, an entity-component framework in Java
3    *
4    * Copyright (c) 2013, Michael Ludwig
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without modification,
8    * are permitted provided that the following conditions are met:
9    *
10   *     Redistributions of source code must retain the above copyright notice,
11   *         this list of conditions and the following disclaimer.
12   *     Redistributions in binary form must reproduce the above copyright notice,
13   *         this list of conditions and the following disclaimer in the
14   *         documentation and/or other materials provided with the distribution.
15   *
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package com.lhkbob.entreri.property;
28  
29  import java.lang.annotation.Retention;
30  import java.lang.annotation.RetentionPolicy;
31  import java.util.Arrays;
32  
33  /**
34   * BooleanProperty is an implementation of Property that stores a single boolean
35   * property.
36   *
37   * @author Michael Ludwig
38   */
39  @Factory(BooleanProperty.Factory.class)
40  public final class BooleanProperty implements Property {
41      private boolean[] data;
42  
43      /**
44       * Create a BooleanProperty.
45       */
46      public BooleanProperty() {
47          data = new boolean[1];
48      }
49  
50      /**
51       * Return the backing boolean array of this property's IndexedDataStore. The array may
52       * be longer than necessary for the number of components in the system. Data can be
53       * accessed for a component directly using the component's index.
54       *
55       * @return The boolean data for all packed properties that this property has been
56       *         packed with
57       */
58      public boolean[] getIndexedData() {
59          return data;
60      }
61  
62      /**
63       * Get the value stored in this property for the given component index.
64       *
65       * @param componentIndex The component's index
66       *
67       * @return The object at the given offset for the given component
68       *
69       * @throws ArrayIndexOutOfBoundsException if the componentIndex is invalid
70       */
71      public boolean get(int componentIndex) {
72          return data[componentIndex];
73      }
74  
75      /**
76       * Store <var>val</var> in this property for the given component index.
77       *
78       * @param componentIndex The index of the component being modified
79       * @param val            The value to store
80       *
81       * @throws ArrayIndexOutOfBoundsException if the componentIndex is invalid
82       */
83      public void set(int componentIndex, boolean val) {
84          data[componentIndex] = val;
85      }
86  
87      @Override
88      public void swap(int a, int b) {
89          boolean t = data[a];
90          data[a] = data[b];
91          data[b] = t;
92      }
93  
94      @Override
95      public int getCapacity() {
96          return data.length;
97      }
98  
99      @Override
100     public void setCapacity(int size) {
101         data = Arrays.copyOf(data, size);
102     }
103 
104     /**
105      * Factory to create BooleanProperties. Properties annotated with DefaultBoolean will
106      * use that value as the default for all components.
107      *
108      * @author Michael Ludwig
109      */
110     public static class Factory implements PropertyFactory<BooleanProperty> {
111         private final boolean defaultValue;
112         private final Clone.Policy policy;
113 
114         public Factory(Attributes attrs) {
115             defaultValue = attrs.hasAttribute(DefaultBoolean.class) &&
116                            attrs.getAttribute(DefaultBoolean.class).value();
117             policy = attrs.hasAttribute(Clone.class) ? attrs.getAttribute(Clone.class)
118                                                             .value()
119                                                      : Clone.Policy.JAVA_DEFAULT;
120         }
121 
122         public Factory(boolean defaultValue) {
123             this.defaultValue = defaultValue;
124             policy = Clone.Policy.JAVA_DEFAULT;
125         }
126 
127         @Override
128         public BooleanProperty create() {
129             return new BooleanProperty();
130         }
131 
132         @Override
133         public void setDefaultValue(BooleanProperty property, int index) {
134             property.set(index, defaultValue);
135         }
136 
137         @Override
138         public void clone(BooleanProperty src, int srcIndex, BooleanProperty dst,
139                           int dstIndex) {
140             switch (policy) {
141             case DISABLE:
142                 // assign default value
143                 setDefaultValue(dst, dstIndex);
144                 break;
145             case INVOKE_CLONE:
146                 // fall through, since default implementation of INVOKE_CLONE is to
147                 // just function like JAVA_DEFAULT
148             case JAVA_DEFAULT:
149                 dst.set(dstIndex, src.get(srcIndex));
150                 break;
151             default:
152                 throw new UnsupportedOperationException(
153                         "Enum value not supported: " + policy);
154             }
155         }
156     }
157 
158     /**
159      * Default boolean attribute for properties.
160      *
161      * @author Michael Ludwig
162      */
163     @Attribute
164     @Retention(RetentionPolicy.RUNTIME)
165     public static @interface DefaultBoolean {
166         boolean value();
167     }
168 }