source: java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java @ 99

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

HIGHLIGTS:

  • complete events implementation
  • add CLI in Java Framsticks server
  • add automatic registration for events in GUI
  • improve objects fetching (object are never overwritten with new instances)
  • properly react for ListChange? events
  • add ListPanel? with table view
    • columns to be shown may be statically specified in configuration
    • currently modyfying data through tables is not available
  • improve maven configuration
    • configuration file may be specified without touching pom.xml

CHANGELOG:
Extract constants from Flags into ParamFlags? and SetStateFlags?.

Extract flags I/O to FlagsUtils? class.

Configured maven to exec given resource configuration.

For example:
mvn exec:exec -Dframsticks.config=/configs/managed-console.xml

Cleanup pom.xml

Rename ObjectTree? to LocalTree? (also make LocalTree? and RemoteTree? final).

Minor change.

Add maximum number of columns in ListPanelProvider?.

Improve ColumnsConfig? interpretation.

Automatically fill FramsClass?.name if trying to construct empty.

Improve identitifer case mangling in XmlLoader?.

Introduce configurable ColumnsConfig?.

Draft working version of ListPanel?.

Table is being shown (although empty).

More improvements to table building.

Move some functionality from Frame to TreeModel?.

Move tree classes in gui to separate package.

Remove old table related classes.

Add draft implementation of TableModel?.

Redirect ParamBuilder?.forAccess to AccessInterface?.

Optimize ParamBuilder?.forAccess()

Do not clear list when loading.

Do not load fetched values directly.

Implement different AccessInterface? copying policy.

Optimize fetching values routine.

Remove Mode enum (work out get semantics).

Some improvements to ListChange? handling.

Improve UniqueListAccess?.

Add reaction for ListChanges? in the TreeNode?.

EventListeners? are being added in the TreeNode?.

Listeners for ListParams? are now very naive (they download
whole list).

Automatially register on events in GUI.

Events are working in RemoteTree? and Server.

Move listeners to the ClientSideManagedConnection?.

Remove old classes responsible for event subscriptions.

Improve event reading.

Improve events handling at server side.

Add register attribute in FramsClassAnnotation?
to automatically also register other classes.

Registering events works.

Setup for remote listeners registration.

More improvements.

Minor changes.

Add rootTree to the ClientAtServer?.

Moving CLI to the ClientAtServer?.

Fix bug: use Void.TYPE instead of Void.class

More development around CLI.

  • Improve Path resolving.

Add synthetic root to ObjectTree?.

It is needed to allow sybling for the original root
that would containg CLI.

Some work with registering events in RemoteTree?.

Draft implementation of listener registering in RemoteTree?.

Support events registration in the ObjectTree?.

Add events support to ReflectionAccess?.

EventParam? is recognized by ParamCandidate?.

Prepare interface for Events across project.

Add EventListener? and API for listeners in Tree.

File size: 6.4 KB
Line 
1package com.framsticks.util.dispatching;
2
3import org.apache.log4j.Logger;
4
5import com.framsticks.util.FramsticksException;
6
7/**
8 * @author Piotr Sniegowski
9 */
10public abstract class Dispatching {
11        private static final Logger log = Logger.getLogger(Dispatching.class);
12
13        public static boolean isThreadSafe() {
14                return true;
15        }
16
17        public static <C> void dispatchIfNotActive(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
18                if (dispatcher.isActive()) {
19                        runnable.runAt();
20                        return;
21                }
22                dispatcher.dispatch(runnable);
23        }
24
25        // public static boolean assertInvokeLater(Dispatcher dispatcher, RunAt runnable) {
26        //      dispatcher.invokeLater(runnable);
27        //      return true;
28        // }
29
30        public static <P, C> void invokeDispatch(Dispatcher<P> dispatcher, final Dispatcher<C> finalDispatcher, final RunAt<C> runnable) {
31                dispatcher.dispatch(new RunAt<P>(runnable) {
32                        @Override
33                        protected void runAt() {
34                                finalDispatcher.dispatch(runnable);
35                        }
36                });
37        }
38
39        public static void sleep(double seconds) {
40                log.debug("sleeping");
41                try {
42                        java.lang.Thread.sleep((long) (seconds * 1000));
43                } catch (InterruptedException e) {
44
45                }
46                log.debug("slept");
47        }
48
49        @SuppressWarnings("unchecked")
50        public static void dispatcherGuardedInvoke(Joinable joinable, RunAt<?> runnable) {
51                if (joinable instanceof Dispatcher) {
52                        dispatchIfNotActive(Dispatcher.class.cast(joinable), runnable);
53                        return;
54                }
55                runnable.runAt();
56        }
57
58        public static void use(final Joinable joinable, final JoinableParent owner) {
59                log.debug("using " + joinable + " by " + owner);
60                if (joinable.use(owner)) {
61                        log.debug("started " + joinable);
62                } else {
63                        log.debug("start of " + joinable + " already happened");
64                }
65        }
66
67        public static void drop(final Joinable joinable, final JoinableParent owner) {
68                log.debug("droping " + joinable + " by " + owner);
69                if (joinable.drop(owner)) {
70                        log.debug("stoped " + joinable);
71                } else {
72                        log.debug("stop of " + joinable + " deferred");
73                }
74        }
75
76        public static void join(Joinable joinable) throws InterruptedException {
77                log.debug("joining " + joinable);
78                try {
79                        joinable.join();
80                } catch (InterruptedException e) {
81                        log.debug("failed to join " + joinable);
82                        throw e;
83                }
84                log.debug("joined " + joinable);
85        }
86
87        public static void childChangedState(final JoinableParent parent, final Joinable joinable, final JoinableState state) {
88                if (state.ordinal() <= JoinableState.RUNNING.ordinal()) {
89                        return;
90                }
91                dispatcherGuardedInvoke(joinable, new RunAt<Object>(ThrowExceptionHandler.getInstance()) {
92                        @Override
93                        protected void runAt() {
94                                log.debug("joinable " + joinable + " is notifying parent " + parent + " about change to " + state);
95                                parent.childChangedState(joinable, state);
96                        }
97                });
98        }
99
100        public static void wait(Object object, long millis) {
101                try {
102                        synchronized (object) {
103                                object.wait(millis);
104                        }
105                } catch (InterruptedException e) {
106                }
107        }
108
109        public static void joinAbsolutely(Joinable joinable) {
110                log.debug("joining absolutely " + joinable);
111                while (true) {
112                        try {
113                                Dispatching.join(joinable);
114                                return;
115                        } catch (InterruptedException e) {
116                                // throw new FramsticksException().msg("failed to join").arg("dispatcher", dispatcher).cause(e);
117                        }
118                        log.debug("waiting for " + joinable);
119                        wait(joinable, 500);
120                }
121        }
122
123        public interface Query<T> extends ExceptionResultHandler {
124                T get();
125        }
126
127        public static abstract class QueryHandler<T> implements Query<T> {
128                ExceptionResultHandler handler;
129
130                /**
131                 * @param handler
132                 */
133                public QueryHandler(ExceptionResultHandler handler) {
134                        this.handler = handler;
135                }
136
137                @Override
138                public void handle(FramsticksException exception) {
139                        handler.handle(exception);
140                }
141        }
142
143        public static class QueryRunner<T, C> extends RunAt<C> {
144                protected final Query<T> query;
145                T result;
146                boolean ready = false;
147
148                /**
149                 * @param query
150                 */
151                public QueryRunner(Query<T> query) {
152                        super(query);
153                        this.query = query;
154                }
155
156                @Override
157                protected void runAt() {
158                        result = query.get();
159                        synchronized (this) {
160                                ready = true;
161                                this.notifyAll();
162                        }
163                }
164
165                public T get() {
166                        synchronized (this) {
167                                while (!ready) {
168                                        try {
169                                                this.wait(100);
170                                        } catch (InterruptedException e) {
171                                        }
172                                }
173                        }
174                        return result;
175                }
176        }
177
178        public static <T, C> T get(Dispatcher<C> dispatcher, Query<T> query) {
179                QueryRunner<T, C> runner = new QueryRunner<T, C>(query);
180                dispatcher.dispatch(runner);
181                return runner.get();
182        }
183
184        public static class DispatcherWaiter<C, T extends Dispatcher<C> & Joinable> implements Dispatcher<C> {
185                // protected boolean done = false;
186                protected final T dispatcher;
187                protected RunAt<? extends C> runnable;
188
189                /**
190                 * @param joinable
191                 */
192                public DispatcherWaiter(T dispatcher) {
193                        this.dispatcher = dispatcher;
194                }
195
196                public synchronized void waitFor() {
197                        while ((runnable == null) && (dispatcher.getState().ordinal() <= JoinableState.RUNNING.ordinal())) {
198                                try {
199                                        this.wait();
200                                } catch (InterruptedException e) {
201                                }
202                        }
203                        if (runnable != null) {
204                                runnable.run();
205                        }
206
207                }
208
209                @Override
210                public boolean isActive() {
211                        return dispatcher.isActive();
212                }
213
214                @Override
215                public synchronized void dispatch(RunAt<? extends C> runnable) {
216                        this.runnable = runnable;
217                        this.notifyAll();
218                }
219
220        }
221
222        public static class Waiter {
223                protected boolean done = false;
224
225                protected final double timeOut;
226                protected final ExceptionResultHandler handler;
227
228                /**
229                 * @param timeOut
230                 */
231                public Waiter(double timeOut, ExceptionResultHandler handler) {
232                        this.timeOut = timeOut;
233                        this.handler = handler;
234                }
235
236                public synchronized void pass() {
237                        done = true;
238                        this.notify();
239                }
240
241                public synchronized void waitFor() {
242                        long end = System.currentTimeMillis() + (int)(timeOut * 1000);
243                        while ((!done) && System.currentTimeMillis() < end) {
244                                try {
245                                        this.wait(end - System.currentTimeMillis());
246                                } catch (InterruptedException e) {
247                                        break;
248                                }
249                        }
250                        if (!done) {
251                                handler.handle(new FramsticksException().msg("waiter timed out"));
252                        }
253                }
254
255                public <T> Future<T> passInFuture(Class<T> type) {
256                        return new FutureHandler<T>(handler) {
257                                @Override
258                                protected void result(T result) {
259                                        Waiter.this.pass();
260                                }
261                        };
262                }
263        }
264
265
266        public static <C> void synchronize(Dispatcher<C> dispatcher, double seconds) {
267                final Waiter waiter = new Waiter(seconds, ThrowExceptionHandler.getInstance());
268                dispatcher.dispatch(new RunAt<C>(ThrowExceptionHandler.getInstance()) {
269                        @Override
270                        protected void runAt() {
271                                waiter.pass();
272                        }
273                });
274                waiter.waitFor();
275        }
276
277}
Note: See TracBrowser for help on using the repository browser.