source: java/main/src/main/java/com/framsticks/core/Instance.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: 9.0 KB
Line 
1package com.framsticks.core;
2
3import com.framsticks.communication.*;
4import com.framsticks.params.*;
5import com.framsticks.params.types.ObjectParam;
6import com.framsticks.parsers.Loaders;
7import com.framsticks.parsers.MultiParamLoader;
8import com.framsticks.util.*;
9import com.framsticks.util.UnsupportedOperationException;
10import com.framsticks.util.dispatching.Dispatching;
11import com.framsticks.util.dispatching.Future;
12import com.framsticks.util.lang.Casting;
13import org.apache.log4j.Logger;
14import com.framsticks.util.dispatching.RunAt;
15
16import java.util.*;
17
18/**
19 * @author Piotr Sniegowski
20 */
21public abstract class Instance extends Entity {
22
23        private static final Logger log = Logger.getLogger(Instance.class.getName());
24
25        protected Node root;
26
27        public Set<InstanceListener> listeners = new HashSet<InstanceListener>();
28
29        public Instance() {
30        }
31
32        @Override
33        protected void run() {
34                super.run();
35                root = new Node((CompositeParam) Param.build().name("Instance").id(name).type("o").finish(), null);
36                com.framsticks.model.Package.register(registry);
37        }
38
39        protected void fetchInfo(Path path, Future<FramsClass> future) {
40                future.result(null, new UnsupportedOperationException());
41        }
42
43        public void resolve(Path path, Future<Path> future) {
44                assert isActive();
45                assert path.isOwner(this);
46                if (path.getTop().getObject() != null) {
47                        future.result(path, null);
48                        return;
49                }
50                AccessInterface access = bindAccess(path.getUnder());
51                Object object = access.get(path.getTop().getParam(), Object.class);
52                if (object == null) {
53                        future.result(path, null);
54                        return;
55                }
56                future.result(path.appendResolution(object), null);
57        }
58
59        public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
60                stateFunctor.call(null);
61        }
62
63        public void fetchValues(Path path, StateFunctor stateFunctor) {
64                stateFunctor.call(null);
65        }
66
67        protected void tryRegisterOnChangeEvents(Path path) {
68
69        }
70
71        public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
72                assert isActive();
73                invokeLater(new RunAt<Instance>() {
74                        @Override
75                        public void run() {
76                                stateFunctor.call(new UnsupportedOperationException());
77                        }
78                });
79        }
80
81        protected void fireRun(Exception e) {
82                for (InstanceListener l : this.listeners) {
83                        l.onRun(e);
84                }
85        }
86
87        protected void fireStop(Exception e) {
88                for (InstanceListener l : this.listeners) {
89                        l.onStop(e);
90                }
91        }
92
93        public void addListener(final InstanceListener listener) {
94                assert Dispatching.isThreadSafe();
95                Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
96                        @Override
97                        public void run() {
98                                listeners.add(listener);
99                        }
100                });
101        }
102
103        public void removeListener(final InstanceListener listener) {
104                assert Dispatching.isThreadSafe();
105                Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
106                        @Override
107                        public void run() {
108                                listeners.remove(listener);
109                        }
110                });
111        }
112
113        protected void fireListChange(Path path, ListChange change) {
114                assert isActive();
115                for (InstanceListener l : this.listeners) {
116                        l.onListChange(path, change);
117                }
118        }
119
120        protected void fireFetch(Path path) {
121                assert isActive();
122                for (InstanceListener l : this.listeners) {
123                        l.onFetch(path);
124                }
125        }
126
127        public final FramsClass getInfoFromCache(Path path) {
128                return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
129        }
130
131        public FramsClass getInfoFromCache(String id) {
132                assert isActive();
133                return registry.getInfoFromCache(id);
134        }
135
136        protected Registry registry = new Registry();
137
138        public AccessInterface createAccess(String name) throws ConstructionException {
139                assert isActive();
140                return registry.createAccess(name);
141        }
142
143        // TODO: make ValueParam
144        public <T> T get(Node node, Param childParam, Class<T> type) {
145                return bindAccess(node).get((ValueParam) childParam, type);
146        }
147
148        public void findInfo(final Path path, final Future<FramsClass> future) {
149                assert isActive();
150                final String name = path.getTop().getParam().getContainedTypeName();
151                final FramsClass framsClass = getInfoFromCache(name);
152                if (framsClass != null) {
153                        log.trace("info for " + name + " found in cache");
154                        future.result(framsClass, null);
155                        return;
156                }
157                fetchInfo(path, future);
158        }
159
160        public final AccessInterface bindAccess(Node node) {
161                assert node.getObject() != null;
162
163                try {
164                        return registry.prepareAccess(node.getParam()).select(node.getObject());
165                } catch (ConstructionException e) {
166                        log.error("failed to bind access for " + node.getParam() + ": " + e);
167                }
168                return null;
169        }
170
171        public final <T> T getParam(Path path, String id, Class<T> type) {
172                return Casting.tryCast(type, registry.prepareAccess(path.getTop().getParam()).getParam(id));
173        }
174
175        public final AccessInterface bindAccess(Path path) {
176                assert path.isResolved();
177                return bindAccess(path.getTop());
178        }
179
180        public void resolve(final String targetPath, final Future<Path> future) {
181                assert isActive();
182                final Path path = getPath(targetPath);
183                resolve(path, new Future<Path>() {
184                        @Override
185                        public void result(Path result, Exception e) {
186                                assert isActive();
187                                if (e != null) {
188                                        future.result(path, e);
189                                        return;
190                                }
191                                if (path.isResolved(targetPath)) {
192                                        future.result(path, null);
193                                        return;
194                                }
195                                if (path.isResolved()) {
196                                        future.result(path, new Exception("testing"));
197                                        return;
198                                }
199                                resolve(targetPath, future);
200                        }
201                });
202        }
203
204        public void resolveAndFetch(final String targetPath, final Future<Path> future) {
205                assert isActive();
206                resolve(targetPath, new Future<Path>() {
207                        @Override
208                        public void result(final Path path, Exception e) {
209                                if (e != null) {
210                                        future.result(path, e);
211                                        return;
212                                }
213                                assert path.isResolved(targetPath);
214                                fetchValues(path, new StateFunctor() {
215                                        @Override
216                                        public void call(Exception e) {
217                                                future.result(path, e);
218                                        }
219                                });
220                        }
221                });
222        }
223
224        public Path createIfNeeded(String path) {
225                Path p;
226                while (!(p = getPath(path)).isResolved(path)) {
227                        create(p);
228                }
229                return p;
230        }
231
232        public Path createIfNeeded(Path path) {
233                assert isActive();
234                if (path.isResolved()) {
235                        return path;
236                }
237                return create(path);
238        }
239
240        public Path create(Path path) {
241                assert isActive();
242                assert !path.isResolved();
243                Path resolved = path.tryFindResolution();
244                if (!resolved.isResolved()) {
245                        log.debug("creating: " + path);
246                        AccessInterface access = registry.prepareAccess(path.getTop().getParam());
247                        assert access != null;
248                        Object child = access.createAccessee();
249                        assert child != null;
250                        if (path.size() == 1) {
251                                root = new Node(root.getParam(), child);
252                        } else {
253                                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
254                        }
255                        resolved = path.appendResolution(child);
256                }
257                tryRegisterOnChangeEvents(resolved);
258                return resolved;
259        }
260
261
262
263
264        public FramsClass processFetchedInfo(File file) {
265                assert isActive();
266                FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
267                if ("/".equals(file.getPath())) {
268                        if (root.getParam().getContainedTypeName() == null) {
269                                root = new Node((CompositeParam)Param.build().name("Instance").id(name).type("o " + framsClass.getId()).finish(), root.getObject());
270                        }
271                }
272                registry.putInfoIntoCache(framsClass);
273                return framsClass;
274        }
275
276        public void processFetchedValues(Path path, List<File> files) {
277                assert isActive();
278                assert files.size() == 1;
279                assert path.isTheSame(files.get(0).getPath());
280                Node node = path.getTop();
281                MultiParamLoader loader = new MultiParamLoader();
282                loader.setNewSource(files.get(0).getContent());
283                loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
284
285                try {
286                        if (node.getParam() instanceof ObjectParam) {
287                                loader.addAccessInterface(bindAccess(node));
288                                loader.go();
289                                fireFetch(path);
290        //            for (NodeListener l : listeners) {
291        //                l.onChange(this);
292        //            }
293                                return;
294                        }
295
296                        ListAccess listAccess = ((ListAccess)bindAccess(node));
297                        assert listAccess != null;
298                        listAccess.clearValues();
299
300                        AccessInterface elementAccess = listAccess.getElementAccess();
301                        loader.addAccessInterface(elementAccess);
302                        MultiParamLoader.Status status;
303                        while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
304                                if (status == MultiParamLoader.Status.AfterObject) {
305                                        AccessInterface accessInterface = loader.getLastAccessInterface();
306
307                                        String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
308                                        Param param = Param.build().type("o " + accessInterface.getId()).id(id).finish();
309                                        Object child = accessInterface.getSelected();
310                                        accessInterface.select(null);
311                                        assert child != null;
312                                        bindAccess(node).set((ValueParam) param, child);
313                                }
314                        }
315
316                        fireFetch(path);
317        //        for (NodeListener l : listeners) {
318        //            l.onChange(this);
319        //        }
320                } catch (Exception e) {
321                        log.error("exception occurred while loading: " + e);
322                }
323
324        }
325
326        public static Iterator<String> splitPath(String path) {
327                List<String> list = new LinkedList<String>();
328                for (String s : path.split("/")) {
329                        if (!s.isEmpty()) {
330                                list.add(s);
331                        }
332                }
333                return list.iterator();
334        }
335
336        public Registry getRegistry() {
337                return registry;
338        }
339
340        public Path getPath(String textual) {
341                return new Path(this, textual);
342        }
343
344        public Path getRootPath() {
345                return getPath("/");
346        }
347}
348
Note: See TracBrowser for help on using the repository browser.