source: java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java @ 86

Last change on this file since 86 was 86, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

  • use java annotations to mark classes and fields to be used when:
    • using java classes with ReflectionAccess? to represent remote objects with FramsClass? description found by "info ..." requests
    • to build up FramsClass? representation of objects not present at remote server
  • allow using primitive types (instead of wraping counterparts) in reflected classes
  • rework FramsClass? creation process (add FramsClassBuilder?)
  • add more tests

CHANGELOG:
Prepare model.World class.

Minor change.

Use primitive types for Genotype and Creature classes.

Use primitive types in model.Neuro* classes.

Use primitive types in model.Joint* classes.

Use primitive types in model.Part* classes.

Fix primitive values.

Extract FramsClassBuilder?.

Add tests of Model classes.

More fixes.

Refactorize out ParamCandidate?.

Several fixes.

Fix all regressions after introducing annotations.

Use annotations throughout the project.

Add exception classes.

Improve creation of FramsClass?.

More changes.

Many changes regarding annotations.

Annotate classes in com.framsticks.model package.

Remove manual FramsClass? constructor.

Construct FramsClass? for Creature. Add test.

Add default values to the ParamAnnotation?.

Add ParamBuilderTest? and ParamAnnotation?.

Add FramsClassAnnotation?.

File size: 7.0 KB
Line 
1package com.framsticks.params;
2
3import java.io.IOException;
4import java.util.Collection;
5
6import static com.framsticks.util.lang.Containers.filterInstanceof;
7
8import org.apache.log4j.Logger;
9
10/**
11 * The Class SimpleAbstractAccess implements all the methods of AccessInterface
12 * which actions can be implemented with usage of {@link AccessInterface} methods
13 * or concern schema, which is stored in {@link #framsClass}
14 *
15 * Based on c++ class SimpleAbstractParam located in: cpp/gdk/param.*
16 *
17 * @author Jarek Szymczak <name.surname@gmail.com>, Mateusz Jarus (please
18 *         replace name and surname with my personal data)
19 *
20 * @author Piotr Sniegowski
21 */
22public abstract class SimpleAbstractAccess implements AccessInterface {
23
24        private final static Logger log = Logger.getLogger(SimpleAbstractAccess.class.getName());
25
26        @Override
27        public final FramsClass getFramsClass() {
28                return framsClass;
29        }
30
31        public void setFramsClass(FramsClass framsClass) {
32                this.framsClass = framsClass;
33        }
34        /**
35         * Simple String key, value class.
36         */
37        public static class Entry {
38
39                public final String key;
40                public final String value;
41
42                public Entry(String key, String value) {
43                        this.key = key;
44                        this.value = value;
45                }
46
47                @Override
48                public String toString() {
49                        return key + " = " + value;
50                }
51        }
52
53        protected FramsClass framsClass;
54
55        @Override
56        public String getId() {
57                return framsClass.getId();
58        }
59
60        @Override
61        public int getParamCount() {
62                return framsClass.getParamCount();
63        }
64
65        @Override
66        public Param getParam(int i) {
67                return framsClass.getParam(i);
68        }
69
70        @Override
71        public Param getParam(String id) {
72                return framsClass.getParam(id);
73        }
74
75        @Override
76        public Param getGroupMember(int gi, int n) {
77                return framsClass.getGroupMember(gi, n);
78        }
79
80        @Override
81        public <T> T get(int i, Class<T> type) {
82                return get(framsClass.getParamEntry(i, ValueParam.class), type);
83        }
84
85        @Override
86        public <T> T get(String id, Class<T> type) {
87                return get(framsClass.getParamEntry(id, ValueParam.class), type);
88        }
89
90        @Override
91        public <T> int set(int i, T value) {
92                return set(framsClass.getParamEntry(i, ValueParam.class), value);
93        }
94
95        @Override
96        public <T> int set(String id, T value) {
97                return set(framsClass.getParamEntry(id, ValueParam.class), value);
98        }
99
100        @Override
101        public <T> int set(ValueParam param, T value) {
102                int flags = 0;
103
104                //String id = param.getEffectiveId();
105                try {
106                        Object oldValue = get(param, param.getStorageType());
107                        ReassignResult<?> result = param.reassign(value, oldValue);
108                        Object casted = result.getValue();
109                        if (!casted.equals(oldValue)) {
110                                internalSet(param, casted);
111                        }
112                        flags = result.getFlags();
113                } catch (CastFailure e) {
114                        log.error("casting failure while set: ", e);
115                }
116                return flags;
117        }
118
119        @Override
120        public void setDefault(boolean numericOnly) {
121                for (int i = 0; i < framsClass.getParamCount(); i++) {
122                        setDefault(i, numericOnly);
123                }
124        }
125
126        @Override
127        public void setDefault(int i, boolean numericOnly) {
128                ValueParam entry = framsClass.getParamEntry(i, ValueParam.class);
129                if ((entry != null)     && (!numericOnly || entry.isNumeric())) {
130                        set(i, entry.getDef(entry.getStorageType()));
131                }
132        }
133
134        @Override
135        public void setMin() {
136                for (int i = 0; i < framsClass.getParamCount(); i++) {
137                        setMin(i);
138                }
139        }
140
141        @Override
142        public void setMin(int i) {
143                PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
144                if (entry == null) {
145                        return;
146                }
147                Object min = entry.getMin(entry.getStorageType());
148                if (min != null) {
149                        set(i, min);
150                }
151        }
152
153        @Override
154        public void setMax() {
155                for (int i = 0; i < framsClass.getParamCount(); i++) {
156                        setMax(i);
157                }
158        }
159
160        @Override
161        public void setMax(int i) {
162                PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
163                if (entry == null) {
164                        return;
165                }
166                Object max = entry.getMax(entry.getStorageType());
167                if (max != null) {
168                        set(i, max);
169                }
170        }
171
172        @Override
173        public void copyFrom(AccessInterface src) {
174                clearValues();
175                //TODO: iterate over self, and pull from src
176                /*
177                for (int i = 0; i < src.getFramsClass().size(); i++) {
178                        this.set(i, src.get(i, Object.class));
179                }
180                */
181        }
182
183
184
185
186        @Override
187        public void save(SinkInterface sink) {
188                assert framsClass != null;
189                sink.print(framsClass.getId()).print(":").breakLine();
190                for (PrimitiveParam p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) {
191                        Object value = get(p, Object.class);
192                        if (value == null) {
193                                continue;
194                        }
195                        sink.print(p.getId()).print(":");
196                        p.save(sink, value);
197                        sink.breakLine();
198                }
199                sink.breakLine();
200        }
201
202        private Entry readEntry(SourceInterface source)
203                        throws IOException {
204
205                String line;
206                String key = null;
207                StringBuilder value = null;
208                while ((line = source.readLine()) != null)
209                {
210                        if (key == null) {
211                                int colonIndex = line.indexOf(':');
212                                if (colonIndex == -1) {
213                                        return null;
214                                }
215                                key = line.substring(0, colonIndex);
216                                String inlineValue = line.substring(colonIndex + 1);
217
218
219                                if (!inlineValue.startsWith("~")) {
220                                        return new Entry(key, inlineValue);
221                                }
222                                value = new StringBuilder();
223                                value.append(inlineValue.substring(1));
224                                continue;
225                        }
226                        if (value.length() != 0) {
227                                value.append(System.getProperty("line.separator"));
228                        }
229                        if (line.contains("~")) {
230                                value.append(line.substring(0, line.indexOf("~")));
231                                return new Entry(key, value.toString());
232                        }
233                        value.append(line);
234                        /*
235                        if (line.contains("~")) {
236                                String lastLine = line.substring(0, line.indexOf("~"));
237                                if (lastLine.length() > 0) {
238                                        appendToValue(value, lastLine);
239                                }
240                                return new Entry(key, value.toString());
241                        }
242                        appendToValue(value, line);
243                        */
244                }
245                return null;
246        }
247
248        @Override
249        public void load(SourceInterface source) throws Exception {
250                //TODO not clearing values, because get from manager gives only fields, not children
251                //this.clearValues();
252
253                Entry entry;
254                while ((entry = readEntry(source)) != null) {
255                        Param param = getParam(entry.key);
256                        if (param == null) {
257                                continue;
258                        }
259                        if (!(param instanceof ValueParam)) {
260                                log.warn("param " + param + " is not a ValueParam");
261                                continue;
262                        }
263                        if ((param.getFlags() & Flags.DONTLOAD) != 0) {
264                                log.debug("DontLoad flag was set - not loading...");
265                        } else {
266                                int retFlags = this.set((ValueParam) param, entry.value);
267                                if ((retFlags & (Flags.PSET_HITMIN | Flags.PSET_HITMAX)) != 0) {
268                                        String which = ((retFlags & Flags.PSET_HITMIN) != 0) ? "small" : "big";
269                                        log.warn("value of key '" + entry.key + "' was too " + which + ", adjusted");
270                                }
271                        }
272                }
273        }
274
275        protected abstract <T> void internalSet(ValueParam param, T value);
276
277        @Override
278        public Collection<Param> getParams() {
279                return framsClass.getParamEntries();
280        }
281
282        /*
283        protected <T extends Comparable<T>> int setAndCut(Param param, Object value, Class<T> type) {
284                int flags = 0;
285                T val = type.cast(value);
286                T min = param.getMin(type);
287                T max = param.getMax(type);
288                if (min != null && val.compareTo(min) < 0) {
289                        val = min;
290                        flags |= Flags.PSET_HITMIN;
291                }
292                if (max != null && val.compareTo(max) > 0) {
293                        val = max;
294                        flags |= Flags.PSET_HITMAX;
295                }
296                internalSet(param, val);
297                return flags;
298        }*/
299
300
301}
Note: See TracBrowser for help on using the repository browser.