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   * DoubleProperty is an implementation of Property that stores a single double value.
35   *
36   * @author Michael Ludwig
37   */
38  @Factory(DoubleProperty.Factory.class)
39  public final class DoubleProperty implements Property {
40      private double[] data;
41  
42      /**
43       * Create an DoubleProperty.
44       */
45      public DoubleProperty() {
46          data = new double[1];
47      }
48  
49      /**
50       * Return the backing int array of this property's IndexedDataStore. The array may be
51       * longer than necessary for the number of components in the system. Data can be
52       * accessed for a component directly using the component's index.
53       *
54       * @return The double data for all packed properties that this property has been
55       *         packed with
56       */
57      public double[] getIndexedData() {
58          return data;
59      }
60  
61      /**
62       * Get the value stored in this property for the given component index.
63       *
64       * @param componentIndex The component's index
65       *
66       * @return The object at the given offset for the given component
67       *
68       * @throws ArrayIndexOutOfBoundsException if the componentIndex is invalid
69       */
70      public double get(int componentIndex) {
71          return data[componentIndex];
72      }
73  
74      /**
75       * Store <var>val</var> in this property for the given component index.
76       *
77       * @param componentIndex The index of the component being modified
78       * @param val            The value to store, can be null
79       *
80       * @throws ArrayIndexOutOfBoundsException if the componentIndex is invalid
81       */
82      public void set(int componentIndex, double val) {
83          data[componentIndex] = val;
84      }
85  
86      @Override
87      public void swap(int a, int b) {
88          double t = data[a];
89          data[a] = data[b];
90          data[b] = t;
91      }
92  
93      @Override
94      public int getCapacity() {
95          return data.length;
96      }
97  
98      @Override
99      public void setCapacity(int size) {
100         data = Arrays.copyOf(data, size);
101     }
102 
103     /**
104      * Factory to create DoubleProperties. Properties annotated with DefaultDouble will
105      * use that value as the default for all components.
106      *
107      * @author Michael Ludwig
108      */
109     public static class Factory implements PropertyFactory<DoubleProperty> {
110         private final double defaultValue;
111         private final Clone.Policy policy;
112 
113         public Factory(Attributes attrs) {
114             defaultValue = attrs.hasAttribute(DefaultDouble.class) ? attrs
115                     .getAttribute(DefaultDouble.class).value() : 0.0;
116             policy = attrs.hasAttribute(Clone.class) ? attrs.getAttribute(Clone.class)
117                                                             .value()
118                                                      : Clone.Policy.JAVA_DEFAULT;
119         }
120 
121         public Factory(double defaultValue) {
122             this.defaultValue = defaultValue;
123             policy = Clone.Policy.JAVA_DEFAULT;
124         }
125 
126         @Override
127         public DoubleProperty create() {
128             return new DoubleProperty();
129         }
130 
131         @Override
132         public void setDefaultValue(DoubleProperty property, int index) {
133             property.set(index, defaultValue);
134         }
135 
136         @Override
137         public void clone(DoubleProperty src, int srcIndex, DoubleProperty dst,
138                           int dstIndex) {
139             switch (policy) {
140             case DISABLE:
141                 // assign default value
142                 setDefaultValue(dst, dstIndex);
143                 break;
144             case INVOKE_CLONE:
145                 // fall through, since default implementation of INVOKE_CLONE is to
146                 // just function like JAVA_DEFAULT
147             case JAVA_DEFAULT:
148                 dst.set(dstIndex, src.get(srcIndex));
149                 break;
150             default:
151                 throw new UnsupportedOperationException(
152                         "Enum value not supported: " + policy);
153             }
154         }
155     }
156 
157     /**
158      * Default double attribute for properties.
159      *
160      * @author Michael Ludwig
161      */
162     @Attribute
163     @Retention(RetentionPolicy.RUNTIME)
164     public static @interface DefaultDouble {
165         double value();
166     }
167 }