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 * ShortProperty is an implementation of Property that stores a single short value.
35 *
36 * @author Michael Ludwig
37 */
38 @Factory(ShortProperty.Factory.class)
39 public final class ShortProperty implements Property {
40 private short[] data;
41
42 /**
43 * Create an ShortProperty.
44 */
45 public ShortProperty() {
46 data = new short[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 short data for all packed properties that this property has been packed
55 * with
56 */
57 public short[] 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 short 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, short val) {
83 data[componentIndex] = val;
84 }
85
86 @Override
87 public void swap(int a, int b) {
88 short 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 ShortProperties. Properties annotated with DefaultShort will use
105 * that value as the default for all components.
106 *
107 * @author Michael Ludwig
108 */
109 public static class Factory implements PropertyFactory<ShortProperty> {
110 private final short defaultValue;
111 private final Clone.Policy policy;
112
113 public Factory(Attributes attrs) {
114 defaultValue = attrs.hasAttribute(DefaultShort.class) ? attrs
115 .getAttribute(DefaultShort.class).value() : 0;
116 policy = attrs.hasAttribute(Clone.class) ? attrs.getAttribute(Clone.class)
117 .value()
118 : Clone.Policy.JAVA_DEFAULT;
119 }
120
121 public Factory(short defaultValue) {
122 this.defaultValue = defaultValue;
123 policy = Clone.Policy.JAVA_DEFAULT;
124 }
125
126 @Override
127 public ShortProperty create() {
128 return new ShortProperty();
129 }
130
131 @Override
132 public void setDefaultValue(ShortProperty property, int index) {
133 property.set(index, defaultValue);
134 }
135
136 @Override
137 public void clone(ShortProperty src, int srcIndex, ShortProperty 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 short attribute for properties.
159 *
160 * @author Michael Ludwig
161 */
162 @Attribute
163 @Retention(RetentionPolicy.RUNTIME)
164 public static @interface DefaultShort {
165 short value();
166 }
167 }