source: java/main/src/main/java/com/framsticks/core/AbstractTree.java @ 101

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

HIGHLIGHTS:

  • improve tree side notes
  • improve GUI layout
  • add foldable list of occured events to EventControl?
  • improve automatic type conversion in proxy listeners
  • implement several Access functionalities as algorithms independent of Access type
  • introduce draft base classes for distributed experiments
  • automatically register dependant Java classes to FramsClass? registry
  • add testing prime experiment and configuration
  • simplify and improve task dispatching

CHANGELOG:
Improve task dispatching in RemoteTree?.

GUI no longer hangs on connection problems.

Make all dispatchers joinables.

Refactorize Thread dispatcher.

Remove Task and PeriodicTask?.

Use Java utilities in those situations.

Reworking tasks dispatching.

Fix bug in EventControl? listener dispatching.

Minor improvements.

Add testing configuration for ExternalProcess? in GUI.

More improvement to prime.

Support for USERREADONLY in GUI.

Add that flag to various params in Java classes.

Remove redundant register clauses from several FramsClassAnnotations?.

Automatically gather and register dependant classes.

Add configuration for prime.

Improve Simulator class.

Add prime.xml configuration.

Introduce draft Experiment and Simulator classes.

Add prime experiment tests.

Enclose typical map with listeners into SimpleUniqueList?.

Needfile works in GUI.

Improve needfile handling in Browser.

More improvement with NeedFile?.

Implementing needfile.

Update test.

Rename ChangeEvent? to TestChangeEvent?.

Automatic argument type search in RemoteTree? listeners.

MultiParamLoader? uses AccessProvider?. By default old implementation
enclosed in AccessStash? or Registry.

Minor changes.

Rename SourceInterface? to Source.

Also improve toString of File and ListSource?.

Remove unused SimpleSource? class.

Add clearing in HistoryControl?.

Show entries in table at EventControl?.

Improve EventControl?.

Add listeners registration to EventControl?.

Add foldable table to HistoryControl?.

Add control row to Procedure and Event controls.

Improve layout of controls.

Another minor change to gui layout.

Minor improvement in the SliderControl?.

Minor changes.

Move ReflectionAccess?.Backend to separate file.

It was to cluttered.

Cleanup in ReflectionAccess?.

Move setMin, setMax, setDef to AccessOperations?.

Extract loading operation into AccessOperations?.

Append Framsticks to name of UnsupportedOperationException?.

The java.lang.UnsupportedOperationException? was shadowing this class.

Rename params.Util to params.ParamsUtil?.

Several improvements.

Minor changes.

Implement revert functionality.

Improve local changes management.

Minor improvement.

Remove methods rendered superfluous after SideNoteKey? improvement.

Improve SideNoteKey?.

It is now generic type, so explicit type specification at
call site is no more needed.

Introduce SideNoteKey? interface.

Only Objects implementing that key may be used as side note keys.

Minor improvements.

Use strings instead of ValueControls? in several gui mappings.

File size: 8.9 KB
Line 
1package com.framsticks.core;
2
3import java.util.Comparator;
4import java.util.Iterator;
5import java.util.Map;
6import java.util.PriorityQueue;
7
8import javax.annotation.Nonnull;
9
10import org.apache.commons.collections.map.ReferenceIdentityMap;
11import org.apache.logging.log4j.Logger;
12import org.apache.logging.log4j.LogManager;
13
14import com.framsticks.communication.queries.NeedFile;
15import com.framsticks.communication.queries.NeedFileAcceptor;
16import com.framsticks.params.Access;
17import com.framsticks.params.CompositeParam;
18import com.framsticks.params.FramsClass;
19import com.framsticks.params.ParamFlags;
20import com.framsticks.params.ParamsPackage;
21import com.framsticks.params.Registry;
22import com.framsticks.params.annotations.AutoAppendAnnotation;
23import com.framsticks.params.annotations.FramsClassAnnotation;
24import com.framsticks.params.annotations.ParamAnnotation;
25import com.framsticks.util.FramsticksException;
26import com.framsticks.util.Misc;
27import com.framsticks.util.dispatching.AbstractJoinable;
28import com.framsticks.util.dispatching.BufferedDispatcher;
29import com.framsticks.util.dispatching.Dispatcher;
30import com.framsticks.util.dispatching.Dispatching;
31import com.framsticks.util.dispatching.ExceptionResultHandler;
32import com.framsticks.util.dispatching.Joinable;
33import com.framsticks.util.dispatching.JoinableParent;
34import com.framsticks.util.dispatching.JoinableState;
35import com.framsticks.util.dispatching.RunAt;
36import com.framsticks.util.dispatching.Thread;
37import com.framsticks.util.dispatching.ThrowExceptionHandler;
38import com.framsticks.util.lang.Pair;
39
40/**
41 * @author Piotr Sniegowski
42 */
43@FramsClassAnnotation
44public abstract class AbstractTree extends AbstractJoinable implements Dispatcher<Tree>, Tree, JoinableParent, NeedFileAcceptor {
45
46        private static final Logger log = LogManager.getLogger(AbstractTree.class);
47
48        private Node root = null;
49        private ExceptionResultHandler handler = ThrowExceptionHandler.getInstance();
50
51        protected final BufferedDispatcher<Tree> bufferedDispatcher = new BufferedDispatcher<>();
52
53        protected final PriorityQueue<Pair<Integer, NeedFileAcceptor>> needFileAcceptors = new PriorityQueue<>(32, new Comparator<Pair<Integer, NeedFileAcceptor>>() {
54
55                @Override
56                public int compare(Pair<Integer, NeedFileAcceptor> arg0, Pair<Integer, NeedFileAcceptor> arg1) {
57                        if (arg0.first < arg1.first) {
58                                return -1;
59                        }
60                        if (arg0.first > arg1.first) {
61                                return 1;
62                        }
63                        return 0;
64                }
65        });
66
67        @Override
68        public void assignRootParam(CompositeParam param) {
69                if (root != null) {
70                        throw new FramsticksException().msg("root has already specified type");
71                }
72                root = new Node(this, param, null);
73                log.debug("assigned root type: {}", root);
74        }
75
76        @Override
77        public void assignRootObject(Object object) {
78                if (root == null) {
79                        throw new FramsticksException().msg("root is has no type specified");
80                }
81                if (root.getObject() != null) {
82                        throw new FramsticksException().msg("root has already object assigned").arg("current", root.getObject()).arg("candidate", object);
83                }
84                root = new Node(this, root.getParam(), object);
85                log.debug("assigned root object: {}", root);
86        }
87
88        @Override
89        public @Nonnull Node getAssignedRoot() {
90                if (root == null) {
91                        throw new FramsticksException().msg("root has no type specified yet");
92                }
93                return root;
94        }
95
96        public boolean isRootAssigned() {
97                // assert isActive();
98                return root != null;
99        }
100
101        protected String name;
102
103        public AbstractTree() {
104                setName("tree");
105        }
106
107        protected void tryRegisterOnChangeEvents(Path path) {
108
109        }
110
111        @Override
112        public final FramsClass getInfoFromCache(String id) {
113                assert isActive();
114                return registry.getFramsClass(id);
115        }
116
117        protected Registry registry = new Registry();
118
119
120        @Override
121        public @Nonnull Access prepareAccess(CompositeParam param) {
122                return registry.prepareAccess(param);
123        }
124
125        @Override
126        public void takeAllFrom(Registry source) {
127                registry.takeAllFrom(source);
128        }
129
130        @AutoAppendAnnotation
131        public void usePackage(ParamsPackage paramsPackage) {
132                log.debug("using package {} in tree {}", paramsPackage, this);
133                paramsPackage.register(registry);
134        }
135
136        @AutoAppendAnnotation
137        public void takeFromRegistry(Registry registry) {
138                log.debug("taking from registry {} in tree {}", registry, this);
139                this.registry.takeAllFrom(registry);
140        }
141
142
143        @Override
144        public void putInfoIntoCache(FramsClass framclass) {
145                registry.putFramsClass(framclass);
146        }
147
148
149        /**
150         * @return the handler
151         */
152        @Override
153        public ExceptionResultHandler getExceptionHandler() {
154                return handler;
155        }
156
157        /**
158         * @param handler the handler to set
159         */
160        @Override
161        public void setExceptionHandler(ExceptionResultHandler handler) {
162                this.handler = handler;
163        }
164
165        @Override
166        public void handle(FramsticksException exception) {
167                handler.handle(exception);
168        }
169
170        /**
171         * @return the dispatcher
172         */
173        @Override
174        public Dispatcher<Tree> getDispatcher() {
175                return bufferedDispatcher.getTargetDispatcher();
176        }
177
178        /**
179         * @param dispatcher the dispatcher to set
180         */
181        @Override
182        public void setDispatcher(Dispatcher<Tree> dispatcher) {
183                if (bufferedDispatcher.getTargetDispatcher() != null) {
184                        throw new FramsticksException().msg("dispatcher is already set").arg("tree", this).arg("dispatcher", bufferedDispatcher.getTargetDispatcher());
185                }
186                bufferedDispatcher.setTargetDispatcher(dispatcher);
187        }
188
189        /**
190         * @return the name
191         */
192        @ParamAnnotation(flags = ParamFlags.USERREADONLY)
193        public String getName() {
194                return name;
195        }
196
197        /**
198         * @param name the name to set
199         */
200        @ParamAnnotation
201        public void setName(String name) {
202                this.name = name;
203        }
204
205        /**
206         * @return the registry
207         */
208        @Override
209        public Registry getRegistry() {
210                return registry;
211        }
212
213        @Override
214        protected void joinableStart() {
215                if (bufferedDispatcher.getTargetDispatcher() == null) {
216                        bufferedDispatcher.setTargetDispatcher(new Thread<Tree>());
217                }
218                Dispatching.use(bufferedDispatcher.getTargetDispatcher(), this);
219        }
220
221        @Override
222        protected void joinableInterrupt() {
223                Dispatching.drop(bufferedDispatcher.getTargetDispatcher(), this);
224        }
225
226        @Override
227        protected void joinableFinish() {
228
229        }
230
231        @Override
232        protected void joinableJoin() throws InterruptedException {
233                Dispatching.join(bufferedDispatcher.getTargetDispatcher());
234        }
235
236        @Override
237        public void childChangedState(Joinable joinable, JoinableState state) {
238                if (joinable == bufferedDispatcher.getTargetDispatcher()) {
239                        proceedToState(state);
240                }
241        }
242
243        @Override
244        public boolean isActive() {
245                return bufferedDispatcher.isActive();
246        }
247
248        @Override
249        public void dispatch(RunAt<? extends Tree> runnable) {
250                bufferedDispatcher.dispatch(runnable);
251        }
252
253
254        @SuppressWarnings("unchecked")
255        protected final Map<Object, Object> sideNotes = (Map<Object, Object>) new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
256
257        @Override
258        public <T> void putSideNote(Object object, SideNoteKey<T> key, T value) {
259                assert isActive();
260                Misc.throwIfNull(object);
261                Misc.throwIfNull(key);
262                Misc.throwIfNull(value);
263                Object sideNote = sideNotes.get(object);
264                if (sideNote == null) {
265                        sideNote = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
266                        sideNotes.put(object, sideNote);
267                }
268                @SuppressWarnings("unchecked")
269                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
270                sideNotesMap.put(key, value);
271        }
272
273        @SuppressWarnings("unchecked")
274        @Override
275        public <T> T getSideNote(Object object, SideNoteKey<T> key) {
276                assert isActive();
277                Misc.throwIfNull(object);
278                Misc.throwIfNull(key);
279                Object sideNote = sideNotes.get(object);
280                if (sideNote == null) {
281                        return null;
282                }
283                Object value = ((Map<SideNoteKey<?>, Object>) sideNote).get(key);
284                if (value == null) {
285                        return null;
286                }
287                return (T) value;
288        }
289
290        @Override
291        public boolean removeSideNote(Object object, SideNoteKey<?> key) {
292                assert isActive();
293                Object sideNote = sideNotes.get(object);
294                if (sideNote == null) {
295                        return false;
296                }
297                @SuppressWarnings("unchecked")
298                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
299                boolean result = (sideNotesMap.remove(key) != null);
300                if (sideNotesMap.isEmpty()) {
301                        sideNotes.remove(object);
302                }
303                return result;
304        }
305
306        @Override
307        public void addNeedFileAcceptor(int priority, NeedFileAcceptor acceptor) {
308                assert isActive();
309                needFileAcceptors.add(Pair.make(priority, acceptor));
310        }
311
312        @Override
313        public void removeNeedFileAcceptor(NeedFileAcceptor acceptor) {
314                assert isActive();
315                Iterator<Pair<Integer, NeedFileAcceptor>> i = needFileAcceptors.iterator();
316                while (i.hasNext()) {
317                        if (i.next().second == acceptor) {
318                                i.remove();
319                                break;
320                        }
321                }
322        }
323
324        @Override
325        public boolean acceptNeed(final NeedFile needFile) {
326                Dispatching.dispatchIfNotActive(this, new RunAt<AbstractTree>(needFile.getFuture()) {
327
328                        @Override
329                        protected void runAt() {
330                                for (Pair<Integer, NeedFileAcceptor> acceptor : needFileAcceptors) {
331                                        if (acceptor.second.acceptNeed(needFile)) {
332                                                return;
333                                        }
334                                }
335                                throw new FramsticksException().msg("failed to find need file acceptor in tree").arg("tree", AbstractTree.this);
336                        }
337                });
338                return true;
339        }
340
341}
342
Note: See TracBrowser for help on using the repository browser.