source: java/main/src/main/java/com/framsticks/core/Instance.java @ 84

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

HIGHLIGHTS:

  • simplification of entities management model
  • cleanup around params (improve hierarchy)
  • migrate from JUnit to TestNG
  • introduce FEST to automatically test GUI
  • improve slider control
  • loosen synchronization between gui tree and backend representation
  • and many other bug fixes

NOTICE:

  • a great many of lines is changed only because of substituting spaces with tabs

CHANGELOG (oldest changes at the bottom):

Some cleaning after fix found.

Fix bug with tree.

More changes with TreeNodes?.

Finally fix issue with tree.

Improve gui tree management.

Decouple update of values from fetch request in gui.

Minor changes.

Minor changes.

Minor change.

Change Path construction wording.

More fixes to SliderControl?.

Fix SliderControl?.

Fix SliderControl?.

Minor improvement.

Several changes.

Make NumberParam? a generic class.

Add robot to the gui test.

Setup common testing logging configuration.

Remove Parameters class.

Remove entityOwner from Parameters.

Move name out from Parameters class.

Move configuration to after the construction.

Simplify observers and endpoints.

Remove superfluous configureEntity overrides.

Add dependency on fest-swing-testng.

Use FEST for final print test.

Use FEST for more concise and readable assertions.

Divide test of F0Parser into multiple methods.

Migrate to TestNG

Minor change.

Change convention from LOGGER to log.

Fix reporting of errors during controls filling.

Bound maximal height of SliderControl?.

Minor improvements.

Improve tooltips for controls.

Also use Delimeted in more places.

Move static control utilities to Gui.

Rename package gui.components to controls.

Some cleaning in controls.

Improve Param classes placing.

Move ValueParam?, PrimitiveParam? and CompositeParam? one package up.

Improve ParamBuilder?.

Move getDef to ValueParam? and PrimitiveParam?.

Move getMax and getDef to ValueParam?.

Move getMin to ValueParam?.

Upgrade to laters apache commons versions.

Use filterInstanceof extensively.

Add instanceof filters.

Make ValueParam? in many places of Param.

Place assertions about ValueParam?.

Add ValueParam?

Rename ValueParam? to PrimitiveParam?

Minor changes.

Several improvements to params types.

Add NumberParam?.

Add TextControl? component.

Add .swp files to .gitignore

Greatly improved slider component.

Some improvements.

Make Param.reassign return also a state.

Add IterableIterator?.

Several changes.

  • Move util classes to better packages.
  • Remove warnings from eclim.

Several improvements.

Fix bug with BooleanParam?.

Some experiments with visualization.

Another fix to panel management.

Improve panel management.

Some refactorization around panels.

Add root class for panel.

File size: 8.9 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;
14
15import java.util.*;
16
17/**
18 * @author Piotr Sniegowski
19 */
20public abstract class Instance extends Entity {
21
22        private static final Logger log = Logger.getLogger(Instance.class.getName());
23
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)new ParamBuilder().setName("Instance").setId(name).setType("o").build(), 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 Runnable() {
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 Runnable() {
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 Runnable() {
106                        @Override
107                        public void run() {
108                                listeners.remove(listener);
109                        }
110                });
111        }
112
113
114        protected void fireListChange(Path path, ListChange change) {
115                assert isActive();
116                for (InstanceListener l : this.listeners) {
117                        l.onListChange(path, change);
118                }
119        }
120
121        protected void fireFetch(Path path) {
122                assert isActive();
123                for (InstanceListener l : this.listeners) {
124                        l.onFetch(path);
125                }
126        }
127
128
129        public final FramsClass getInfoFromCache(Path path) {
130                return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
131        }
132
133
134        public FramsClass getInfoFromCache(String id) {
135                assert isActive();
136                return registry.getInfoFromCache(id);
137        }
138
139        protected Registry registry = new Registry();
140
141        public AccessInterface createAccess(String name) {
142                assert isActive();
143                return registry.createAccess(name);
144        }
145
146
147        // TODO: make ValueParam
148        public <T> T get(Node node, Param childParam, Class<T> type) {
149                return bindAccess(node).get((ValueParam) childParam, type);
150        }
151
152        public void findInfo(final Path path, final Future<FramsClass> future) {
153                assert isActive();
154                final String name = path.getTop().getParam().getContainedTypeName();
155                final FramsClass framsClass = getInfoFromCache(name);
156                if (framsClass != null) {
157                        log.trace("info for " + name + " found in cache");
158                        future.result(framsClass, null);
159                        return;
160                }
161                fetchInfo(path, future);
162        }
163
164        public final AccessInterface bindAccess(Node node) {
165                assert node.getObject() != null;
166                AccessInterface access = registry.prepareAccess(node.getParam());
167                if (access == null) {
168                        log.error("missing access for: " + node.getParam());
169                        return null;
170                }
171                access.select(node.getObject());
172                return access;
173        }
174
175        public final <T> T getParam(Path path, String id, Class<T> type) {
176                return Casting.tryCast(type, registry.prepareAccess(path.getTop().getParam()).getParam(id));
177        }
178
179        public final AccessInterface bindAccess(Path path) {
180                assert path.isResolved();
181                return bindAccess(path.getTop());
182        }
183
184        public void resolve(final String targetPath, final Future<Path> future) {
185                assert isActive();
186                final Path path = getPath(targetPath);
187                resolve(path, new Future<Path>() {
188                        @Override
189                        public void result(Path result, Exception e) {
190                                assert isActive();
191                                if (e != null) {
192                                        future.result(path, e);
193                                        return;
194                                }
195                                if (path.isResolved(targetPath)) {
196                                        future.result(path, null);
197                                        return;
198                                }
199                                if (path.isResolved()) {
200                                        future.result(path, new Exception("testing"));
201                                        return;
202                                }
203                                resolve(targetPath, future);
204                        }
205                });
206        }
207
208        public void resolveAndFetch(final String targetPath, final Future<Path> future) {
209                assert isActive();
210                resolve(targetPath, new Future<Path>() {
211                        @Override
212                        public void result(final Path path, Exception e) {
213                                if (e != null) {
214                                        future.result(path, e);
215                                        return;
216                                }
217                                assert path.isResolved(targetPath);
218                                fetchValues(path, new StateFunctor() {
219                                        @Override
220                                        public void call(Exception e) {
221                                                future.result(path, e);
222                                        }
223                                });
224                        }
225                });
226        }
227
228        public Path createIfNeeded(String path) {
229                Path p;
230                while (!(p = getPath(path)).isResolved(path)) {
231                        create(p);
232                }
233                return p;
234        }
235
236        public Path createIfNeeded(Path path) {
237                assert isActive();
238                if (path.isResolved()) {
239                        return path;
240                }
241                return create(path);
242        }
243
244        public Path create(Path path) {
245                assert isActive();
246                assert !path.isResolved();
247                Path resolved = path.tryFindResolution();
248                if (!resolved.isResolved()) {
249                        log.debug("creating: " + path);
250                        AccessInterface access = registry.prepareAccess(path.getTop().getParam());
251                        assert access != null;
252                        Object child = access.createAccessee();
253                        assert child != null;
254                        if (path.size() == 1) {
255                                root = new Node(root.getParam(), child);
256                        } else {
257                                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
258                        }
259                        resolved = path.appendResolution(child);
260                }
261                tryRegisterOnChangeEvents(resolved);
262                return resolved;
263        }
264
265
266
267
268        public FramsClass processFetchedInfo(File file) {
269                assert isActive();
270                FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
271                if ("/".equals(file.getPath())) {
272                        if (root.getParam().getContainedTypeName() == null) {
273                                root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o " + framsClass.getId()).build(), root.getObject());
274                        }
275                }
276                registry.putInfoIntoCache(framsClass);
277                return framsClass;
278        }
279
280        public void processFetchedValues(Path path, List<File> files) {
281                assert isActive();
282                assert files.size() == 1;
283                assert path.isTheSame(files.get(0).getPath());
284                Node node = path.getTop();
285                MultiParamLoader loader = new MultiParamLoader();
286                loader.setNewSource(files.get(0).getContent());
287                loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
288
289                try {
290                        if (node.getParam() instanceof ObjectParam) {
291                                loader.addAccessInterface(bindAccess(node));
292                                loader.go();
293                                fireFetch(path);
294        //            for (NodeListener l : listeners) {
295        //                l.onChange(this);
296        //            }
297                                return;
298                        }
299
300                        ListAccess listAccess = ((ListAccess)bindAccess(node));
301                        assert listAccess != null;
302                        listAccess.clearValues();
303
304                        AccessInterface elementAccess = listAccess.getElementAccess();
305                        loader.addAccessInterface(elementAccess);
306                        MultiParamLoader.Status status;
307                        while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
308                                if (status == MultiParamLoader.Status.AfterObject) {
309                                        AccessInterface accessInterface = loader.getLastAccessInterface();
310
311                                        String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
312                                        Param param = new ParamBuilder().setType("o " + accessInterface.getId()).setId(id).build();
313                                        Object child = accessInterface.getSelected();
314                                        accessInterface.select(null);
315                                        assert child != null;
316                                        bindAccess(node).set((ValueParam) param, child);
317                                }
318                        }
319
320                        fireFetch(path);
321        //        for (NodeListener l : listeners) {
322        //            l.onChange(this);
323        //        }
324                } catch (Exception e) {
325                        log.error("exception occurred while loading: " + e);
326                }
327
328        }
329
330        public static Iterator<String> splitPath(String path) {
331                List<String> list = new LinkedList<String>();
332                for (String s : path.split("/")) {
333                        if (!s.isEmpty()) {
334                                list.add(s);
335                        }
336                }
337                return list.iterator();
338        }
339
340        public Registry getRegistry() {
341                return registry;
342        }
343
344        public Path getPath(String textual) {
345                return new Path(this, textual);
346        }
347
348        public Path getRootPath() {
349                return getPath("/");
350        }
351}
352
Note: See TracBrowser for help on using the repository browser.