Changeset 98 for java


Ignore:
Timestamp:
07/08/13 23:04:56 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

CHANGELOG:
Get data also on tree expansion.

Use nice framstick icon for empty nodes.

Update panel after reload if it is current.

Add shallow reload procedure.

Cut Gui prefix from several tree classes.

Bring back counter of GuiTreeNode?.

Use IdentityHashMap? were it is more appriopriate.

Remove TreeListener?.

Do not use TreeListener? in GUI.

Minor change.

Done migration to GuiTreeModel?.

BrowserTest? in that version always crashes frams.linux.

Move rendering implementation into GuiAbstractNode?.

Use hand-crafted list in GuiTreeNode?.

Generally, it would be a great place for WeakIdentityHashMap?
(but there is none in Java Collection Framework).

Remove superfluous logging.

Fix bug in GuiTreeNode?.

Use IdentityHashMap? instead of HashMap?.

Improve structure update.

Filter out invalid uids in UniqueListAccess?.

Improve TreeCellRenderer?.

Add filtering in TrackConsole?.

Improve TreeModel?.

More changes.

More improvements.

More changes.

Remove TreeNode?.

Support MetaNode? in the GuiTreeModel?.

Implement more in GuiTreeModel?.

Add CompositeParam? interface to FramsClass? and AccessInterface?.

Allow access by number to UniqueList?.

Add UidComparator?.

Use TreeMap? as a default accessee in unique list.

It keeps order of keys.

Introduce classes to use with new TreeModel?.

Another step.

Migrate from TreeNode? to Node in many places.

Remove some uses of TreeNode? as DefaultMutableTreeNode?.

Remove Path from TreeNode? interface.

Remove Path from TreeNode?.

Add Path recration from node feature.

Reworking TreeCellRenderer?.

Minor change of TreeOperations? interface.

Remove last methods from TreeNode?.

Another minor step.

Do not store reference to TreeAtFrame? in TreeNode?.

Add proxy exceptionHandler to StatusBar?.

Move panels management to TreeAtFrame?.

Store localChanges in the NodeAtFrame?.

More cleanup.

Move name computing to TreeCellRenderer?.

Move tooltip and icon computations to TreeCellRenderer?.

More dispatches removed.

Remove most dispatching from TreeNode?.

TreeNode? does not actually redispatch tasks.

Make Tree embedded in Browser use SwingDispatcher?.

Make lazy binding of Tree with Dispatcher.

Minor changes.

Organizational change in AbstractTree?.

Make AbstractTree? compose from Thread instead of inherit from it.

Make SwingDispatcher? and AtOnceDispatcher? Joinable compatible.

Add ListPanelProvider?.

Improve Controls readonly and enabled handling.

Properly pass ExceptionHandlers? in more places.

Make Tree.get accept ValueParam?.

  • This is to allow access number of list elements.

Remove not needed get redirection in ClientAtServer?.

Rename tryResolve to tryGet.

Unify tryResolveAndGet into tryResolve.

Remove resolveTop from Tree interface.

Make Tree.get accept Future<Path>.

Use get to implement resolveTop also in ObjectTree?.

Unify resolveTop and get in RemoteTree?.

Another minor step.

More minor changes in tree operations.

Minor organizational changes.

In RemoteTree? first fetch info for root.

Reworking resolving.

Minor changes.

Make ListAccess? return proxy iterators (instead of creating temporary collection).

Let AccessInterface? return Iterable<Param>.

Improve resolving.

More improvements.

First working completion in ManagedConsole?.

Rename resolve to resolveTop.

This reflects the actuall functionality.

Change semantic of tryResolve and tryResolveAndGet.

Location:
java/main/src
Files:
7 added
4 deleted
71 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/communication/ClientSideManagedConnection.java

    r97 r98  
    176176
    177177        private <C> void sendImplementation(Request request, Dispatcher<C> dispatcher, ClientSideResponseFuture callback) {
     178                callback.setRequest(request);
    178179
    179180                if (getState().ordinal() > JoinableState.RUNNING.ordinal()) {
  • java/main/src/main/java/com/framsticks/communication/ClientSideResponseFuture.java

    r97 r98  
    1111        }
    1212
     13        protected Request request;
     14
    1315        protected abstract void processOk(Response response);
    1416
     
    1820                        processOk(response);
    1921                } else {
    20                         handle(new FramsticksException().msg("invalid response").arg("comment", response.getComment()));
     22                        handle(new FramsticksException().msg("invalid response").arg("comment", response.getComment()).arg("request", request));
    2123                }
    2224        }
    2325
     26        /**
     27         * @return the request
     28         */
     29        public Request getRequest() {
     30                return request;
     31        }
     32
     33        /**
     34         * @param request the request to set
     35         */
     36        public void setRequest(Request request) {
     37                this.request = request;
     38        }
     39
    2440}
  • java/main/src/main/java/com/framsticks/communication/Request.java

    r96 r98  
    4848        @Override
    4949        public String toString() {
    50                 return getCommand() + " request";
     50                // return getCommand();
     51                return "request " + stringRepresentation();
    5152        }
    5253
  • java/main/src/main/java/com/framsticks/communication/RequestHandler.java

    r97 r98  
    22
    33import com.framsticks.communication.queries.ApplicationRequest;
     4import com.framsticks.util.dispatching.ExceptionResultHandler;
    45
    56/**
    67 * @author Piotr Sniegowski
    78 */
    8 public interface RequestHandler {
     9public interface RequestHandler extends ExceptionResultHandler {
    910        public void handle(ApplicationRequest request, ServerSideResponseFuture responseCallback);
    1011}
  • java/main/src/main/java/com/framsticks/communication/ServerSideManagedConnection.java

    r97 r98  
    1212import java.net.Socket;
    1313import com.framsticks.util.dispatching.RunAt;
    14 import com.framsticks.util.dispatching.ThrowExceptionHandler;
    1514
    1615/**
     
    2120        private final static Logger log = Logger.getLogger(ServerSideManagedConnection.class);
    2221
    23         RequestHandler requestHandler;
     22        protected final RequestHandler requestHandler;
    2423
    2524        public ServerSideManagedConnection(Socket socket, RequestHandler requestHandler) {
     
    7069
    7170        protected final void respond(final Response response, final Integer id) {
    72                 //TODO TEH: pass it the hosted tree
    73                 senderThread.dispatch(new RunAt<Connection>(ThrowExceptionHandler.getInstance()) {
     71                senderThread.dispatch(new RunAt<Connection>(requestHandler) {
    7472                        @Override
    7573                        protected void runAt() {
  • java/main/src/main/java/com/framsticks/communication/Subscription.java

    r97 r98  
    7373
    7474        public void dispatchCall(final List<File> files) {
    75                 //TODO TEH
    7675                Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>(ThrowExceptionHandler.getInstance()) {
    7776                        @Override
  • java/main/src/main/java/com/framsticks/core/AbstractTree.java

    r97 r98  
    11package com.framsticks.core;
    2 import java.util.HashSet;
    3 import java.util.Set;
    42
    53import javax.annotation.Nonnull;
     
    108import com.framsticks.params.CompositeParam;
    119import com.framsticks.params.FramsClass;
    12 import com.framsticks.params.Param;
    1310import com.framsticks.params.ParamsPackage;
    1411import com.framsticks.params.Registry;
    1512import com.framsticks.params.annotations.AutoAppendAnnotation;
    1613import com.framsticks.params.annotations.FramsClassAnnotation;
     14import com.framsticks.params.annotations.ParamAnnotation;
     15import com.framsticks.util.FramsticksException;
     16import com.framsticks.util.dispatching.AbstractJoinable;
     17import com.framsticks.util.dispatching.Dispatcher;
    1718import com.framsticks.util.dispatching.Dispatching;
     19import com.framsticks.util.dispatching.ExceptionResultHandler;
     20import com.framsticks.util.dispatching.Joinable;
     21import com.framsticks.util.dispatching.JoinableDispatcher;
     22import com.framsticks.util.dispatching.JoinableParent;
     23import com.framsticks.util.dispatching.JoinableState;
    1824import com.framsticks.util.dispatching.RunAt;
    1925import com.framsticks.util.dispatching.Thread;
     
    2430 */
    2531@FramsClassAnnotation
    26 public abstract class AbstractTree extends Thread<Tree> implements Tree {
     32public abstract class AbstractTree extends AbstractJoinable implements Dispatcher<Tree>, Tree, JoinableParent {
    2733
    2834        private static final Logger log = Logger.getLogger(Tree.class);
    2935
    30         private Node root;
    31 
    32         @Override
    33         public void setRoot(Node node) {
    34                 root = node;
    35         }
    36 
    37         @Override
    38         public @Nonnull Node getRoot() {
    39                 assert root != null;
     36        private Node root = null;
     37        private ExceptionResultHandler handler = ThrowExceptionHandler.getInstance();
     38
     39        private JoinableDispatcher<Tree> dispatcher;
     40
     41        @Override
     42        public void assignRootParam(CompositeParam param) {
     43                if (root != null) {
     44                        throw new FramsticksException().msg("root has already specified type");
     45                }
     46                root = new Node(this, param, null);
     47                log.info("assigned root type: " + root);
     48        }
     49
     50        @Override
     51        public void assignRootObject(Object object) {
     52                if (root == null) {
     53                        throw new FramsticksException().msg("root is has no type specified");
     54                }
     55                if (root.getObject() != null) {
     56                        throw new FramsticksException().msg("root has already object assigned").arg("current", root.getObject()).arg("candidate", object);
     57                }
     58                root = new Node(this, root.getParam(), object);
     59                log.info("assigned root object: " + root);
     60        }
     61
     62        @Override
     63        public @Nonnull Node getAssignedRoot() {
     64                if (root == null) {
     65                        throw new FramsticksException().msg("root has no type specified yet");
     66                }
    4067                return root;
    4168        }
     
    4673        }
    4774
    48         protected Set<TreeListener> listeners = new HashSet<TreeListener>();
     75        protected String name;
    4976
    5077        public AbstractTree() {
    51                 setName("entity");
     78                setName("tree");
    5279        }
    5380
     
    5582
    5683        }
    57 
    58 
    59         protected void fireRun(Exception e) {
    60                 for (TreeListener l : this.listeners) {
    61                         l.onRun(e);
    62                 }
    63         }
    64 
    65         protected void fireStop(Exception e) {
    66                 for (TreeListener l : this.listeners) {
    67                         l.onStop(e);
    68                 }
    69         }
    70 
    71         @Override
    72         public void addListener(final TreeListener listener) {
    73                 assert Dispatching.isThreadSafe();
    74                 Dispatching.dispatchIfNotActive(this, new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
    75                         @Override
    76                         protected void runAt() {
    77                                 listeners.add(listener);
    78                         }
    79                 });
    80         }
    81 
    82         @Override
    83         public void removeListener(final TreeListener listener) {
    84                 assert Dispatching.isThreadSafe();
    85                 Dispatching.dispatchIfNotActive(this, new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
    86                         @Override
    87                         protected void runAt() {
    88                                 listeners.remove(listener);
    89                         }
    90                 });
    91         }
    92 
    93         protected void fireListChange(Path path, ListChange change) {
    94                 assert isActive();
    95                 for (TreeListener l : this.listeners) {
    96                         l.onListChange(path, change);
    97                 }
    98         }
    99 
    100         @Override
    101         public void notifyOfFetch(Path path) {
    102                 fireFetch(path);
    103         }
    104 
    105         protected void fireFetch(Path path) {
    106                 assert isActive();
    107                 for (TreeListener l : this.listeners) {
    108                         l.onFetch(path);
    109                 }
    110         }
    111 
    11284
    11385        @Override
     
    142114        }
    143115
    144         @Override
    145         protected void joinableStart() {
    146                 dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
    147                         @Override
    148                         protected void runAt() {
    149                                 if (!isRootAssigned()) {
    150                                         setRoot(new Node(Param.build().name("Tree").id(getName()).type("o").finish(CompositeParam.class), null));
    151                                 }
    152                         }
    153                 });
    154                 super.joinableStart();
    155         }
    156116
    157117        @Override
     
    159119                registry.putFramsClass(framclass);
    160120        }
     121
     122
     123        /**
     124         * @return the handler
     125         */
     126        @Override
     127        public ExceptionResultHandler getExceptionHandler() {
     128                return handler;
     129        }
     130
     131        /**
     132         * @param handler the handler to set
     133         */
     134        @Override
     135        public void setExceptionHandler(ExceptionResultHandler handler) {
     136                this.handler = handler;
     137        }
     138
     139        @Override
     140        public void handle(FramsticksException exception) {
     141                handler.handle(exception);
     142        }
     143
     144        /**
     145         * @return the dispatcher
     146         */
     147        @Override
     148        public JoinableDispatcher<Tree> getDispatcher() {
     149                return dispatcher;
     150        }
     151
     152        /**
     153         * @param dispatcher the dispatcher to set
     154         */
     155        @Override
     156        public void setDispatcher(JoinableDispatcher<Tree> dispatcher) {
     157                if (this.dispatcher != null) {
     158                        throw new FramsticksException().msg("dispatcher is already set").arg("tree", this).arg("dispatcher", dispatcher);
     159                }
     160                this.dispatcher = dispatcher;
     161        }
     162
     163        /**
     164         * @return the name
     165         */
     166        @ParamAnnotation
     167        public String getName() {
     168                return name;
     169        }
     170
     171        /**
     172         * @param name the name to set
     173         */
     174        @ParamAnnotation
     175        public void setName(String name) {
     176                this.name = name;
     177        }
     178
     179        @Override
     180        protected void joinableStart() {
     181                if (dispatcher == null) {
     182                        dispatcher = new Thread<Tree>();
     183                }
     184                Dispatching.use(dispatcher, this);
     185        }
     186
     187        @Override
     188        protected void joinableInterrupt() {
     189                Dispatching.drop(dispatcher, this);
     190        }
     191
     192        @Override
     193        protected void joinableFinish() {
     194
     195        }
     196
     197        @Override
     198        protected void joinableJoin() throws InterruptedException {
     199                Dispatching.join(dispatcher);
     200        }
     201
     202        @Override
     203        public void childChangedState(Joinable joinable, JoinableState state) {
     204                if (joinable == dispatcher) {
     205                        proceedToState(state);
     206                }
     207        }
     208
     209        @Override
     210        public boolean isActive() {
     211                if (dispatcher == null) {
     212                        throw new FramsticksException().msg("no dispatcher is set for tree yet").arg("tree", this);
     213                }
     214                return dispatcher.isActive();
     215        }
     216
     217        @Override
     218        public void dispatch(RunAt<? extends Tree> runnable) {
     219                if (dispatcher == null) {
     220                        throw new FramsticksException().msg("no dispatcher is set for tree yet").arg("tree", this);
     221                }
     222                dispatcher.dispatch(runnable);
     223        }
     224
    161225}
    162226
  • java/main/src/main/java/com/framsticks/core/Node.java

    r90 r98  
    55
    66import com.framsticks.params.CompositeParam;
    7 import com.framsticks.params.ParamBuilder;
     7import com.framsticks.util.FramsticksException;
     8// import com.framsticks.params.ParamBuilder;
     9import com.framsticks.util.lang.Strings;
    810
    911/**
     
    1315public class Node {
    1416
     17        protected final Tree tree;
    1518        protected final CompositeParam param;
    1619        protected final Object object;
    17         //protected final Map<String, Node> children = new HashMap<String, Node>();
    1820
    19         public Node() {
    20                 param = null;
    21                 object = null;
    22         }
    23 
    24         public Node(@Nonnull CompositeParam param, Object object) {
     21        public Node(Tree tree, @Nonnull CompositeParam param, Object object) {
    2522                assert param != null;
     23                assert tree != null;
     24                this.tree = tree;
    2625                this.param = param;
    2726                this.object = object;
    2827        }
    2928
    30         public Node(@Nonnull ParamBuilder builder, Object object) {
    31                 this(builder.finish(CompositeParam.class), object);
     29
     30        public final Tree getTree() {
     31                return tree;
    3232        }
    3333
     
    4040        }
    4141
     42        @Override
     43        public String toString() {
     44                return param.toString() + ":" + Strings.toStringNullProof(object, "<null>");
     45        }
     46
     47        public final boolean isResolved() {
     48                return object != null;
     49        }
     50
     51        public Node assureResolved() {
     52                if (!isResolved()) {
     53                        throw new FramsticksException().msg("path is not resolved").arg("node", this);
     54                }
     55                return this;
     56        }
     57
    4258}
  • java/main/src/main/java/com/framsticks/core/ObjectTree.java

    r97 r98  
    88import com.framsticks.params.Param;
    99import com.framsticks.params.PrimitiveParam;
     10import com.framsticks.params.ValueParam;
    1011import com.framsticks.params.annotations.AutoAppendAnnotation;
    1112import com.framsticks.params.annotations.FramsClassAnnotation;
    12 import com.framsticks.util.UnsupportedOperationException;
    1313import com.framsticks.params.types.ProcedureParam;
    1414import com.framsticks.util.FramsticksException;
    1515import com.framsticks.util.dispatching.Future;
     16
    1617import static com.framsticks.core.TreeOperations.*;
    1718
     
    2425                registry.registerAndBuild(object.getClass());
    2526                AccessInterface access = registry.createAccess(object.getClass());
    26                 setRoot(new Node(Param.build().forAccess(access).id(getName()).finish(CompositeParam.class), object));
     27                assignRootParam(Param.build().forAccess(access).id(getName()).finish(CompositeParam.class));
     28                assignRootObject(object);
    2729        }
    2830
    2931        public Object getRootObject() {
    30                 return getRoot().getObject();
     32                return getAssignedRoot().getObject();
    3133        }
    3234
     
    4345
    4446        @Override
    45         public void get(final Path path, Mode mode, Future<Object> future) {
     47        public void get(Path path, Mode mode, Future<Path> future) {
    4648                assert isActive();
    4749                log.debug("requesting: " + path);
    48                 fireFetch(path);
    49                 future.pass(path.getTopObject());
     50                path = resolveTopSync(path);
     51                future.pass(path);
    5052        }
    5153
    5254        @Override
    53         public void get(Path path, PrimitiveParam<?> param, Mode mode, Future<Object> future) {
     55        public void get(Path path, ValueParam param, Mode mode, Future<Object> future) {
    5456                assert isActive();
    55                 fireFetch(path);
     57                path = resolveTopSync(path);
    5658                future.pass(bindAccess(path).get(param, Object.class));
    5759        }
     
    8082        }
    8183
    82         @Override
    83         public void resolve(Path path, Future<Path> future) {
     84        protected Path resolveTopSync(Path path) {
    8485                assert isActive();
    8586                assert path.isOwner(this);
    8687                if (path.getTop().getObject() != null) {
    87                         future.pass(path);
    88                         return;
     88                        return path;
    8989                }
    90                 AccessInterface access = bindAccess(this, path.getUnder());
     90                AccessInterface access = bindAccess(path.getUnder());
    9191                Object object = access.get(path.getTop().getParam(), Object.class);
    9292                if (object == null) {
    93                         future.pass(path);
    94                         return;
     93                        return path;
    9594                }
    96                 future.pass(path.appendResolution(object));
     95                return path.appendResolution(object);
    9796        }
     97
    9898
    9999        @Override
     
    103103        }
    104104
    105         @Override
    106         public Path create(Path path) {
    107                 assert isActive();
    108                 assert !path.isResolved();
    109                 throw new UnsupportedOperationException();
    110         }
    111 
    112105}
  • java/main/src/main/java/com/framsticks/core/Path.java

    r97 r98  
    5858        public Path appendParam(CompositeParam param) {
    5959                assert isResolved();
    60                 return appendNode(new Node(param, null));
     60                return appendNode(new Node(tree, param, null));
    6161        }
    6262
     
    9999                public PathBuilder setLast(Object object) {
    100100                        Node n = nodes.pollLast();
    101                         nodes.add(new Node(n.getParam(), object));
     101                        nodes.add(new Node(n.getTree(), n.getParam(), object));
    102102                        return this;
    103103                }
     
    130130                }
    131131
     132
    132133                public PathBuilder resolve(@Nonnull Tree tree, String textual) {
    133134
     
    136137                        this.tree = tree;
    137138
    138                         nodes.add(tree.getRoot());
    139                         Node current = tree.getRoot();
     139                        Node current = tree.getAssignedRoot();
     140                        nodes.add(current);
    140141
    141142                        StringBuilder b = new StringBuilder();
    142143                        Iterator<String> i = splitPath(textual);
    143144                        while (i.hasNext() && current.getObject() != null) {
    144                                 AccessInterface access = tree.prepareAccess(current.getParam());
    145                                 if (access == null) {
    146                                         break;
    147                                 }
     145                                AccessInterface access = TreeOperations.bindAccess(current);// tree.prepareAccess(current.getParam());
    148146                                String e = i.next();
    149147                                Param p = access.getParam(e);
     
    155153                                b.append("/").append(e);
    156154                                access.select(current.getObject());
    157                                 current = new Node(c, getKnownChild(tree, access, c));
     155                                current = new Node(current.getTree(), c, getKnownChild(tree, access, c));
    158156                                nodes.add(current);
    159157                        }
     
    218216                assert Dispatching.isThreadSafe();
    219217                return this.textual.equals(textual);
     218        }
     219
     220        public final boolean isTheSameTextually(Path path) {
     221                assert Dispatching.isThreadSafe();
     222                return (tree == path.getTree()) && textual.equals(path.getTextual());
    220223        }
    221224
     
    242245                        return Path.build().resolve(tree, "/").finish();
    243246                }
    244                 Object child = getKnownChild(tree, TreeOperations.bindAccess(tree, getUnder()), getTop().getParam());
     247                Object child = getKnownChild(tree, TreeOperations.bindAccess(getUnder()), getTop().getParam());
    245248                if (child == null) {
    246249                        return this;
     
    249252        }
    250253
    251         public boolean matches(Path p) {
    252                 assert Dispatching.isThreadSafe();
    253                 assert tree == p.tree;
    254                 Iterator<Node> a = nodes.iterator();
    255                 Iterator<Node> b = p.nodes.iterator();
    256                 while (a.hasNext() && b.hasNext()) {
    257                         Node an = a.next();
    258                         Node bn = b.next();
    259                         if (an.object != bn.object) {
    260                                 return false;
    261                         }
    262                 }
    263                 return a.hasNext() == b.hasNext();
    264         }
    265254
    266255        public String getLastElement() {
     
    278267        }
    279268
    280         public void assureResolved() {
     269        public Path assureResolved() {
    281270                if (!isResolved()) {
    282271                        throw new FramsticksException().msg("path is not resolved").arg("path", this);
    283272                }
     273                return this;
    284274        }
    285275
     
    287277                return Path.build().resolve(tree, textual).finish();
    288278        }
     279
     280        public boolean isTheSameObjects(Path path) {
     281                if (tree != path.getTree()) {
     282                        return false;
     283                }
     284                if (size() != path.size()) {
     285                        return false;
     286                }
     287                if (!getTextual().equals(path.getTextual())) {
     288                        return false;
     289                }
     290                Iterator<Node> a = nodes.iterator();
     291                Iterator<Node> b = path.getNodes().iterator();
     292                while (a.hasNext()) {
     293                        assert b.hasNext();
     294                        if (a.next() != b.next()) {
     295                                return false;
     296                        }
     297                }
     298                return true;
     299        }
     300
     301
     302        // public boolean isEmpty() {
     303        //      return nodes.isEmpty();
     304        // }
    289305}
    290306
  • java/main/src/main/java/com/framsticks/core/Tree.java

    r97 r98  
    88import com.framsticks.params.PrimitiveParam;
    99import com.framsticks.params.Registry;
     10import com.framsticks.params.ValueParam;
    1011import com.framsticks.params.types.ProcedureParam;
    1112import com.framsticks.util.dispatching.Dispatcher;
     13import com.framsticks.util.dispatching.ExceptionResultHandler;
    1214import com.framsticks.util.dispatching.Future;
    1315import com.framsticks.util.dispatching.Joinable;
     16import com.framsticks.util.dispatching.JoinableDispatcher;
    1417
    15 public interface Tree extends Dispatcher<Tree>, Joinable {
     18public interface Tree extends Dispatcher<Tree>, Joinable, ExceptionResultHandler {
    1619
    17         public @Nonnull Node getRoot();
    18         public @Nonnull void setRoot(Node node);
     20        public @Nonnull Node getAssignedRoot();
     21        public void assignRootParam(CompositeParam param);
     22        public void assignRootObject(Object object);
    1923
    2024        public @Nonnull AccessInterface prepareAccess(CompositeParam param);
    2125        public void takeAllFrom(Registry source);
    22 
    23         public void addListener(TreeListener listener);
    24         public void removeListener(TreeListener listener);
    25 
    26         public void notifyOfFetch(Path path);
    2726
    2827        public FramsClass getInfoFromCache(String id);
     
    3029        public void putInfoIntoCache(FramsClass framclass);
    3130
    32         public void resolve(Path path, Future<Path> future);
     31        /**
     32         *
     33         * Functions accepts ValueParam, because it is also possible to get number of List elements.
     34         *
     35         */
     36        public void get(Path path, ValueParam param, Mode mode, Future<Object> future);
    3337
    34         public void get(Path path, PrimitiveParam<?> param, Mode mode, Future<Object> future);
    35 
    36         public void get(Path path, Mode mode, Future<Object> future);
     38        public void get(Path path, Mode mode, Future<Path> future);
    3739
    3840        public void call(Path path, ProcedureParam param, Object[] arguments, Future<Object> future);
    3941
     42        /**
     43         *
     44         * Functions accepts PrimitiveParam<?>, because it is not possible to set number of List elements.
     45         *
     46         */
    4047        public void set(Path path, PrimitiveParam<?> param, Object value, Future<Integer> future);
    4148
    4249        public void info(Path path, Future<FramsClass> future);
    4350
    44         public Path create(Path path);
     51        public void setExceptionHandler(ExceptionResultHandler handler);
     52
     53        public ExceptionResultHandler getExceptionHandler();
     54
     55        public void setDispatcher(JoinableDispatcher<Tree> dispatcher);
     56
     57        public JoinableDispatcher<Tree> getDispatcher();
     58
    4559}
  • java/main/src/main/java/com/framsticks/core/TreeOperations.java

    r97 r98  
    11package com.framsticks.core;
     2
    23
    34import java.util.List;
     
    1415import com.framsticks.params.Param;
    1516import com.framsticks.params.PrimitiveParam;
    16 import com.framsticks.params.ValueParam;
    1717import com.framsticks.params.types.ObjectParam;
    1818import com.framsticks.params.types.ProcedureParam;
     
    2828public final class TreeOperations {
    2929
    30         private static final Logger log = Logger.getLogger(TreeOperations.class.getName());
     30        private static final Logger log = Logger.getLogger(TreeOperations.class);
    3131
    3232        private TreeOperations() {
     
    3636                assert tree.isActive();
    3737                FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
    38                 if ("/".equals(file.getPath())) {
    39                         if (tree.getRoot().getParam().getContainedTypeName() == null) {
    40                                 tree.setRoot(new Node(Param.build().name("Tree").id(tree.getName()).type("o " + framsClass.getId()).finish(CompositeParam.class), tree.getRoot().getObject()));
    41                         }
    42                 }
     38                log.debug("process fetched info for " + tree + ": " + framsClass);
    4339                tree.putInfoIntoCache(framsClass);
    4440                return framsClass;
    4541        }
    4642
     43        public static void processFetchedValues(Path path, List<File> files) {
     44                Tree tree = path.getTree();
     45                assert tree.isActive();
     46                assert files.size() == 1;
     47                assert path.isTheSame(files.get(0).getPath());
     48
     49                if (!path.isResolved()) {
     50                        AccessInterface access = tree.prepareAccess(path.getTop().getParam());
     51                        Object child = access.createAccessee();
     52                        assert child != null;
     53                        if (path.size() == 1) {
     54                                tree.assignRootObject(child);
     55                        } else {
     56                                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
     57                        }
     58                        path = path.appendResolution(child);
     59                }
     60
     61                log.debug("process fetched values: " + path);
     62                Node node = path.getTop();
     63                MultiParamLoader loader = new MultiParamLoader();
     64                loader.setNewSource(files.get(0).getContent());
     65                loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
     66
     67                try {
     68                        if (node.getParam() instanceof ObjectParam) {
     69                                loader.addAccessInterface(bindAccess(node));
     70                                loader.go();
     71                                return;
     72                        }
     73
     74                        ListAccess listAccess = (ListAccess) bindAccess(node);
     75                        listAccess.clearValues();
     76
     77                        AccessInterface elementAccess = listAccess.getElementAccess();
     78                        loader.addAccessInterface(elementAccess);
     79                        MultiParamLoader.Status status;
     80                        while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
     81                                if (status == MultiParamLoader.Status.AfterObject) {
     82                                        AccessInterface accessInterface = loader.getLastAccessInterface();
     83
     84                                        String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
     85                                        //TODO listAccessParam
     86                                        CompositeParam param = Param.build().forAccess(accessInterface).id(id).finish(CompositeParam.class);
     87                                        Object child = accessInterface.getSelected();
     88                                        accessInterface.select(null);
     89                                        assert child != null;
     90                                        bindAccess(node).set(param, child);
     91                                }
     92                        }
     93
     94                } catch (FramsticksException e) {
     95                        throw new FramsticksException().msg("exception occurred while loading").cause(e);
     96                }
     97        }
     98
    4799        public static FramsClass getInfo(Path path) {
    48100                Tree tree = path.getTree();
    49101                assert tree.isActive();
     102                log.debug("get info for: " + path);
    50103                final String name = path.getTop().getParam().getContainedTypeName();
    51104                return tree.getInfoFromCache(name);
     
    53106
    54107        public static void findInfo(final Path path, final Future<FramsClass> future) {
     108                log.debug("find info for: " + path);
    55109                try {
    56110                        Tree tree = path.getTree();
     
    67121        }
    68122
    69         public static void processFetchedValues(Path path, List<File> files) {
    70                 Tree tree = path.getTree();
    71                 assert tree.isActive();
    72                 assert files.size() == 1;
    73                 assert path.isTheSame(files.get(0).getPath());
    74                 Node node = path.getTop();
    75                 MultiParamLoader loader = new MultiParamLoader();
    76                 loader.setNewSource(files.get(0).getContent());
    77                 loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
    78 
    79                 try {
    80                         if (node.getParam() instanceof ObjectParam) {
    81                                 loader.addAccessInterface(TreeOperations.bindAccess(tree, node));
    82                                 loader.go();
    83                                 tree.notifyOfFetch(path);
    84                                 return;
    85                         }
    86 
    87                         ListAccess listAccess = ((ListAccess) TreeOperations.bindAccess(tree, node));
    88                         assert listAccess != null;
    89                         listAccess.clearValues();
    90 
    91                         AccessInterface elementAccess = listAccess.getElementAccess();
    92                         loader.addAccessInterface(elementAccess);
    93                         MultiParamLoader.Status status;
    94                         while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
    95                                 if (status == MultiParamLoader.Status.AfterObject) {
    96                                         AccessInterface accessInterface = loader.getLastAccessInterface();
    97 
    98                                         String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
    99                                         //TODO listAccessParam
    100                                         Param param = Param.build().forAccess(accessInterface).id(id).finish();
    101                                         Object child = accessInterface.getSelected();
    102                                         accessInterface.select(null);
    103                                         assert child != null;
    104                                         TreeOperations.bindAccess(tree, node).set((ValueParam) param, child);
    105                                 }
    106                         }
    107 
    108                         tree.notifyOfFetch(path);
    109                 } catch (Exception e) {
    110                         log.error("exception occurred while loading: " + e);
    111                 }
    112 
    113         }
    114 
    115         public static void resolveAndGet(final Tree tree, final String targetPath, final Future<Path> future) {
    116                 resolve(tree, targetPath, new FutureHandler<Path>(future) {
    117                         @Override
    118                         protected void result(final Path path) {
    119                                 assert path.isResolved(targetPath);
    120                                 //TODO Future
    121                                 tree.get(path, Mode.FETCH, new FutureHandler<Object>(future) {
    122                                         @Override
    123                                         protected void result(Object object) {
    124                                                 future.pass(path);
    125                                         }
    126                                 });
    127                         }
    128                 });
    129         }
    130 
    131 
    132         public static void resolve(final Path path, final Future<Path> future) {
    133                 final Tree tree = path.getTree();
    134                 assert tree.isActive();
    135                 if (path.getTop().getObject() != null) {
    136                         if (getInfoFromCache(path) != null) {
    137                                 future.pass(path);
    138                                 return;
    139                         }
    140                         TreeOperations.findInfo(path, new FutureHandler<FramsClass>(future) {
    141                                 @Override
    142                                 protected void result(FramsClass result) {
    143                                         future.pass(path);
    144                                 }
    145                         });
    146                         return;
    147                 }
    148                 TreeOperations.findInfo(path, new FutureHandler<FramsClass>(future) {
    149                         @Override
    150                         protected void result(FramsClass result) {
    151                                 assert tree.isActive();
    152                                 assert path.getTop().getParam().isMatchingContainedName(result.getId());
    153                                 Path p = (path.getTop().getParam().getContainedTypeName() != null ? path : path.tryFindResolution());
    154                                 future.pass(TreeOperations.createIfNeeded(p));
    155                         }
    156                 });
    157         }
    158 
    159         public static Path createIfNeeded(Tree tree, String path) {
    160                 assert tree.isActive();
    161                 Path p;
    162                 while (!(p = Path.to(tree, path)).isResolved(path)) {
    163                         tree.create(p);
    164                 }
    165                 return p;
    166         }
    167 
    168         public static Path createIfNeeded(Path path) {
    169                 Tree tree = path.getTree();
    170                 assert tree.isActive();
    171                 if (path.isResolved()) {
    172                         return path;
    173                 }
    174                 return tree.create(path);
    175         }
     123
    176124
    177125        public static @Nonnull AccessInterface bindAccess(Tree tree, String path) {
     126                log.debug("bind access for textual: " + path + " in " + tree);
    178127                return bindAccess(Path.to(tree, path));
    179128        }
    180129
    181         public static @Nonnull AccessInterface bindAccess(Tree tree, Node node) {
     130        public static @Nonnull AccessInterface bindAccess(Node node) {
     131                Tree tree = node.getTree();
    182132                assert tree.isActive();
    183133                assert node.getObject() != null;
     
    194144                assert path.getTree().isActive();
    195145                path.assureResolved();
    196                 return bindAccess(path.getTree(), path.getTop());
     146                log.debug("bind access for: " + path);
     147                return bindAccess(path.getTop());
    197148        }
    198149
     
    219170        }
    220171
     172
    221173        /** This might not be correct. */
    222         public static void resolve(final Tree tree, final String targetPath, final Future<Path> future) {
     174        public static void tryGet(final Tree tree, final String targetPath, final Future<Path> future) {
     175                log.debug("resolve textual: " + targetPath + " for " + tree);
    223176                dispatchIfNotActive(tree, new RunAt<Tree>(future) {
    224177
    225178                        @Override
    226179                        protected void runAt() {
    227                                 tree.resolve(Path.to(tree, targetPath), new FutureHandler<Path>(future) {
     180                                final Path path = Path.to(tree, targetPath);
     181                                if (path.isResolved()) {
     182                                        future.pass(path);
     183                                        return;
     184                                }
     185
     186                                tree.get(path, Mode.FETCH, new FutureHandler<Path>(future) {
    228187                                        @Override
    229188                                        protected void result(Path result) {
    230                                                 assert result.getTree().isActive();
    231                                                 if (result.isResolved(targetPath)) {
    232                                                         future.pass(result);
    233                                                         return;
    234                                                 }
    235                                                 resolve(tree, targetPath, future);
     189                                                tryGet(tree, targetPath, future);
    236190                                        }
    237191                                });
  • java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java

    r97 r98  
    11package com.framsticks.diagnostics;
    22
    3 import java.util.Date;
    4 import java.io.File;
    5 import java.io.FileOutputStream;
    6 import java.io.IOException;
    7 import java.io.OutputStreamWriter;
    8 import java.io.PrintWriter;
    9 import java.text.SimpleDateFormat;
    103
    11 import org.apache.log4j.Logger;
    12 
    13 import com.framsticks.core.AbstractTreeListener;
    144import com.framsticks.core.Tree;
    15 import com.framsticks.core.Path;
    16 import com.framsticks.dumping.PrintWriterSink;
    17 import com.framsticks.dumping.SaveStream;
    185import com.framsticks.params.annotations.AutoAppendAnnotation;
    19 import com.framsticks.remote.RecursiveFetcher;
    20 import com.framsticks.util.FramsticksException;
    21 import com.framsticks.util.PeriodicTask;
    22 import com.framsticks.util.dispatching.ExceptionResultHandler;
    23 import com.framsticks.util.dispatching.FutureHandler;
    246import com.framsticks.util.dispatching.JoinableCollection;
    25 import com.framsticks.util.dispatching.ThrowExceptionHandler;
    26 import com.framsticks.util.io.Encoding;
    277
    288/**
     
    3010 */
    3111public class Diagnostics extends JoinableCollection<Tree> {
    32         private static final Logger log = Logger.getLogger(Diagnostics.class);
    3312
    3413
     
    4827                super.add(tree);
    4928
    50                 tree.addListener(new AbstractTreeListener() {
    51                         @Override
    52                         public void onRun(Exception e) {
    53                                 if (e != null) {
    54                                         return;
    55                                 }
     29                // tree.addListener(new AbstractTreeListener() {
     30                //      @Override
     31                //      public void onRun(Exception e) {
     32                //              if (e != null) {
     33                //                      return;
     34                //              }
    5635
    57                                 if (dumpsInterval != null) {
    58                                         new PeriodicTask<Tree>(ThrowExceptionHandler.getInstance(), tree, dumpsInterval * 1000) {
    59                                                 protected final ExceptionResultHandler repeater = new ExceptionResultHandler() {
     36                //              if (dumpsInterval != null) {
     37                //                      new PeriodicTask<Tree>(ThrowExceptionHandler.getInstance(), tree, dumpsInterval * 1000) {
     38                //                              protected final ExceptionResultHandler repeater = new ExceptionResultHandler() {
    6039
    61                                                         @Override
    62                                                         public void handle(FramsticksException exception) {
    63                                                                 log.error("caught error during diagnostics fetching (repeating): " + exception);
    64                                                                 again();
    65                                                         }
     40                //                                      @Override
     41                //                                      public void handle(FramsticksException exception) {
     42                //                                              log.error("caught error during diagnostics fetching (repeating): " + exception);
     43                //                                              again();
     44                //                                      }
    6645
    67                                                 };
    68                                                 @Override
    69                                                 protected void runAt() {
     46                //                              };
     47                //                              @Override
     48                //                              protected void runAt() {
    7049
    71                                                         log.info("starting periodic dump");
    72                                                         new RecursiveFetcher(tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
     50                //                                      log.info("starting periodic dump");
     51                //                                      new RecursiveFetcher(tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
    7352
    74                                                                 @Override
    75                                                                 protected void result(Void result) {
    76                                                                         log.info("tree resolved, saving");
    77                                                                         try {
    78                                                                                 final String fileName = dumpsPath + "/" + tree + "_" + new SimpleDateFormat(dumpsFormat).format(new Date()) + ".param";
    79                                                                                 File file = new File(fileName);
    80                                                                                 new SaveStream(new PrintWriterSink(new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Encoding.getFramsticksCharset()))), tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
     53                //                                              @Override
     54                //                                              protected void result(Void result) {
     55                //                                                      log.info("tree resolved, saving");
     56                //                                                      try {
     57                //                                                              final String fileName = dumpsPath + "/" + tree + "_" + new SimpleDateFormat(dumpsFormat).format(new Date()) + ".param";
     58                //                                                              File file = new File(fileName);
     59                //                                                              new SaveStream(new PrintWriterSink(new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Encoding.getFramsticksCharset()))), tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
    8160
    82                                                                                         @Override
    83                                                                                         protected void result(Void result) {
    84                                                                                                 again();
    85                                                                                         }
    86                                                                                 });
    87                                                                         } catch (IOException e) {
    88                                                                                 throw new FramsticksException().msg("failed to initiate dump").cause(e);
    89                                                                         }
    90                                                                 }
    91                                                         });
    92                                                 }
    93                                         };
    94                                 }
    95                         }
    96                 });
     61                //                                                                      @Override
     62                //                                                                      protected void result(Void result) {
     63                //                                                                              again();
     64                //                                                                      }
     65                //                                                              });
     66                //                                                      } catch (IOException e) {
     67                //                                                              throw new FramsticksException().msg("failed to initiate dump").cause(e);
     68                //                                                      }
     69                //                                              }
     70                //                                      });
     71                //                              }
     72                //                      };
     73                //              }
     74                //      }
     75                // });
    9776
    9877
  • java/main/src/main/java/com/framsticks/dumping/LoadStream.java

    r97 r98  
    5959                                        if (line.equals("ok")) {
    6060                                                if (query.first.equals("get")) {
    61                                                         Path path = TreeOperations.createIfNeeded(tree, query.second);
    62                                                         TreeOperations.processFetchedValues(path, files);
     61                                                        // Path path = null;
     62                                                        throw new UnimplementedException().msg("rework load stream");
     63                                                        // Path path = TreeOperations.createIfNeeded(tree, query.second);
     64                                                        // TreeOperations.processFetchedValues(path, files);
    6365                                                } else if (query.first.equals("info")) {
    6466                                                        assert files.size() == 1;
  • java/main/src/main/java/com/framsticks/dumping/SaveStream.java

    r97 r98  
    1414import com.framsticks.util.dispatching.Dispatching;
    1515import com.framsticks.util.dispatching.Future;
    16 import com.framsticks.util.dispatching.ThrowExceptionHandler;
    1716
    1817import org.apache.log4j.Logger;
     
    4847        protected void dispatchWrite(final Path path) {
    4948                ++dispatched;
    50                 //TODO TEH
    51                 tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
     49                tree.dispatch(new RunAt<Tree>(tree) {
    5250                        @Override
    5351                        protected void runAt() {
     
    8987                        }
    9088                        for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
    91                                 final Path childPath = path.appendNode(new Node(p, access.get(p, Object.class)));
     89                                final Path childPath = path.appendNode(new Node(path.getTree(), p, access.get(p, Object.class)));
    9290                                if (childPath.isResolved() && getInfoFromCache(childPath) != null) {
    9391                                        dispatchWrite(childPath);
  • java/main/src/main/java/com/framsticks/gui/Browser.java

    r97 r98  
    1414import com.framsticks.util.dispatching.ExceptionResultHandler;
    1515import com.framsticks.util.dispatching.Future;
    16 import com.framsticks.util.dispatching.FutureHandler;
    1716import com.framsticks.util.dispatching.Joinable;
    1817import com.framsticks.util.dispatching.JoinableCollection;
     
    4645
    4746        protected final List<PopupMenuEntryProvider> popupMenuEntryProviders = new LinkedList<>();
     47        // protected final SwingDispatcher
    4848
    4949        protected final MainFrame mainFrame;
     
    6363
    6464                mainFrame = new MainFrame(Browser.this);
     65
     66                // mainFrame.getStatusBar().setExceptionHandler(ThrowExceptionHandler.getInstance());
     67
    6568                addFrame(mainFrame);
    6669
     
    120123        public void addTree(Tree tree) {
    121124                log.info("adding tree: " + tree);
     125                tree.setDispatcher(new SwingDispatcher<Tree>());
    122126                trees.add(tree);
    123127        }
    124128
    125129        public void autoResolvePath(final String path, final Future<Path> future) {
    126                 final Tree i = trees.get("localhost");
    127                 i.dispatch(new RunAt<Tree>(future) {
    128                         @Override
    129                         protected void runAt() {
    130                                 TreeOperations.resolveAndGet(i, path, new FutureHandler<Path>(future) {
    131                                         @Override
    132                                         protected void result(final Path p) {
    133                                                 future.pass(p);
    134                                                 mainFrame.dispatch(new RunAt<Frame>(future) {
    135                                                         @Override
    136                                                         protected void runAt() {
    137                                                                 mainFrame.goTo(p);
    138                                                         }
    139                                                 });
    140                                         }
    141                                 });
    142                         }
    143                 });
     130                // final Tree i = trees.get("localhost");
     131                // i.dispatch(new RunAt<Tree>(future) {
     132                //      @Override
     133                //      protected void runAt() {
     134                //              TreeOperations.tryGet(i, path, new FutureHandler<Path>(future) {
     135                //                      @Override
     136                //                      protected void result(final Path p) {
     137                //                              future.pass(p);
     138                //                              mainFrame.dispatch(new RunAt<Frame>(future) {
     139                //                                      @Override
     140                //                                      protected void runAt() {
     141                //                                              mainFrame.goTo(p);
     142                //                                      }
     143                //                              });
     144                //                      }
     145                //              });
     146                //      }
     147                // });
    144148        }
    145149
     
    284288        }
    285289
    286         // @Override
    287         // public boolean isDone() {
    288         //      return frames.isDone() && trees.isDone();
     290        // final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
     291        // public boolean hasSubscribed(EventParam param) {
     292        //      assert frame.isActive();
     293        //      return userSubscriptions.containsKey(param);
    289294        // }
     295
     296        // public void unsubscribe(EventParam eventParam) {
     297        //      assert frame.isActive();
     298        //      if (!hasSubscribed(eventParam)) {
     299        //              log.error("could not unsubscribe from " + eventParam);
     300        //              return;
     301        //      }
     302        //      userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
     303        //      userSubscriptions.remove(eventParam);
     304        // }
     305
     306
     307
     308
    290309}
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r97 r98  
    1111import java.awt.event.MouseAdapter;
    1212import java.awt.event.MouseEvent;
    13 import java.util.HashMap;
     13import java.util.IdentityHashMap;
    1414import java.util.Map;
    1515
     
    2828import javax.swing.ToolTipManager;
    2929import javax.swing.UIManager;
    30 import javax.swing.event.TreeModelEvent;
    31 import javax.swing.event.TreeModelListener;
     30import javax.swing.event.TreeExpansionEvent;
     31import javax.swing.event.TreeExpansionListener;
    3232import javax.swing.event.TreeSelectionEvent;
    3333import javax.swing.event.TreeSelectionListener;
    34 import javax.swing.tree.DefaultMutableTreeNode;
    35 import javax.swing.tree.DefaultTreeModel;
    3634import javax.swing.tree.DefaultTreeSelectionModel;
    3735import javax.swing.tree.TreePath;
     
    4038import org.apache.log4j.Logger;
    4139
     40import com.framsticks.core.Mode;
    4241import com.framsticks.core.Path;
    4342import com.framsticks.core.Tree;
     43import com.framsticks.core.TreeOperations;
    4444import com.framsticks.gui.view.TreeCellRenderer;
    45 import com.framsticks.util.FramsticksException;
     45import com.framsticks.params.AccessInterface;
    4646import com.framsticks.util.dispatching.Dispatching;
    47 import com.framsticks.util.dispatching.ExceptionResultHandler;
     47import com.framsticks.util.dispatching.FutureHandler;
    4848import com.framsticks.util.dispatching.Joinable;
    4949import com.framsticks.util.dispatching.JoinableCollection;
    5050import com.framsticks.util.dispatching.JoinableParent;
    5151import com.framsticks.util.dispatching.JoinableState;
    52 import com.framsticks.util.dispatching.RunAt;
    53 import com.framsticks.util.lang.ScopeEnd;
    5452import com.framsticks.util.swing.KeyboardModifier;
    5553import com.framsticks.util.swing.MenuConstructor;
     
    7270        protected JScrollPane treeScrollPane;
    7371        protected JTree jtree;
    74         protected DefaultTreeModel treeModel;
    75         protected javax.swing.tree.MutableTreeNode rootNode;
     72        protected TreeModel treeModel;
     73
     74        protected MetaNode rootNode;
     75
    7676        protected JPanel treePanel;
    7777        protected JPopupMenu treePopupMenu;
    7878        protected JMenuItem treePopupMenuHeader;
    7979
    80         TreeNode currentlyPoppedTreeNode;
    8180        protected JPanel mainPanel;
    8281        protected JPanel leftPanel;
     
    9190        protected JMenu helpMenu;
    9291
    93         protected final Map<Tree, TreeAtFrame> treeAtFrames = new HashMap<Tree, TreeAtFrame>();
    94         protected JoinableCollection<Tree> trees = new JoinableCollection<Tree>();
     92        protected final Map<Tree, TreeAtFrame> treeAtFrames = new IdentityHashMap<>();
     93        protected JoinableCollection<Tree> trees = new JoinableCollection<>();
    9594
    9695        public Frame(Browser browser) {
     
    106105                log.debug("creating " + this);
    107106
    108 
    109107                Container contentPane = getSwing().getContentPane();
    110108                treePopupMenu = new JPopupMenu("title");
     
    114112                treePanel.setLayout(new BorderLayout());
    115113
    116                 treeModel = new DefaultTreeModel(null);
    117                 treeModel.addTreeModelListener(new TreeModelListener() {
    118 
    119                         @Override
    120                         public void treeNodesChanged(TreeModelEvent arg0) {
    121                                 log.trace("treeNodesChanged: " + arg0);
    122                         }
    123 
    124                         @Override
    125                         public void treeNodesInserted(TreeModelEvent arg0) {
    126                                 // log.trace("treeNodesInserted: " + arg0);
    127                         }
    128 
    129                         @Override
    130                         public void treeNodesRemoved(TreeModelEvent arg0) {
    131                                 log.trace("treeNodesRemoved: " + arg0);
    132                         }
    133 
    134                         @Override
    135                         public void treeStructureChanged(TreeModelEvent arg0) {
    136                                 log.trace("treeStructureChanged: " + arg0);
    137                         }
    138                 });
     114                rootNode = new MetaNode();
     115                rootNode.setName("root");
     116                treeModel = new TreeModel(this);
    139117
    140118                jtree = new JTree(treeModel);
     
    152130                });
    153131
     132                jtree.addTreeExpansionListener(new TreeExpansionListener() {
     133
     134                        @Override
     135                        public void treeCollapsed(TreeExpansionEvent e) {
     136
     137                        }
     138
     139                        @Override
     140                        public void treeExpanded(TreeExpansionEvent e) {
     141                                loadChildren(treeModel.convertToPath(e.getPath()), false);
     142                        }
     143                });
     144
    154145                jtree.setExpandsSelectedPaths(true);
    155146                jtree.setEditable(false);
    156                 jtree.setDoubleBuffered(true);
    157147                jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    158148                jtree.setShowsRootHandles(true);
     
    173163                });
    174164
    175                 new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED).join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)).join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)).join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)).join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
     165                new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED)
     166                        .join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
     167                        .join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
     168                        .join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
     169                        .join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
    176170
    177171                jtree.setCellRenderer(new TreeCellRenderer());
     
    182176                treePanel.add(treeScrollPane);
    183177
    184                 rootNode = new DefaultMutableTreeNode();
    185                 rootNode.setUserObject("root");
    186                 treeModel.setRoot(rootNode);
    187178
    188179                normalWorkPanel = new JPanel();
     
    248239                });
    249240
     241                new MenuConstructor(fileMenu).add(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK), new AbstractAction("Reload current") {
     242                        @Override
     243                        public void actionPerformed(ActionEvent actionEvent) {
     244
     245                                loadPath(treeModel.convertToPath(jtree.getSelectionPath()), true);
     246                        }
     247                });
     248
    250249        }
    251250
     
    254253        }
    255254
    256         public void addRootPath(Path path) {
     255        public void addRootPath(final Path path) {
    257256                assert isActive();
     257
    258258                Tree tree = path.getTree();
     259
     260                log.info("trying mount: " + path);
     261                if (!tree.getAssignedRoot().isResolved()) {
     262                        tree.get(path, Mode.FETCH, new FutureHandler<Path>(this) {
     263
     264                                @Override
     265                                protected void result(Path result) {
     266                                        addRootPath(result);
     267                                }
     268                        });
     269                        return;
     270                }
     271
    259272                assert browser.getTrees().contains(tree);
    260273
    261274                TreeAtFrame e = new TreeAtFrame(tree, this);
    262                 tree.addListener(e);
    263275                treeAtFrames.put(tree, e);
    264                 TreeNode node = new TreeNode(e, path);
    265                 e.rootTreeNode = node;
    266                 treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
    267                 jtree.expandPath(new TreePath(rootNode));
     276
     277                rootNode.getChildren().add(new TreeNode(tree.getAssignedRoot()));
     278                e.rootNode = tree.getAssignedRoot();
     279                treeModel.nodeStructureChanged(new TreePath(rootNode));
     280                // jtree.expandPath(new TreePath(rootNode));
    268281        }
    269282
     
    275288        }
    276289
     290
    277291        private void showPopup(MouseEvent e) {
    278292                assert isActive();
     
    280294                        return;
    281295                }
    282                 currentlyPoppedTreeNode = findTreeNodeByTreePath(jtree.getPathForLocation(e.getX(), e.getY()));
    283                 if (currentlyPoppedTreeNode == null) {
    284                         return;
    285                 }
    286 
    287                 Path path = currentlyPoppedTreeNode.getTreePath();
     296                TreePath treePath = jtree.getPathForLocation(e.getX(), e.getY());
     297
     298                Path path = treeModel.convertToPath(treePath);
    288299                treePopupMenu.removeAll();
    289300
     
    291302                        provider.provide(treePopupMenu, path);
    292303                }
    293                 // treePopupMenuHeader.setText(path.getTree().getName() + path.getTextual());
    294304                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
    295                 //currentlyPoppedPanel.getNode().getFramsClass().getName()
    296         }
    297 
    298         public TreeNode getCurrentlyPoppedTreeNode() {
    299                 assert isActive();
    300                 return currentlyPoppedTreeNode;
    301305        }
    302306
    303307        public void clear() {
    304                 treeModel.setRoot(null);
    305308                cardPanel.removeAll();
    306309                cardPanel.updateUI();
     
    308311        }
    309312
    310         public ScopeEnd startChange(final DefaultMutableTreeNode node) {
    311                 assert isActive();
    312                 final TreePath selection = jtree.getSelectionPath();
    313                 return new ScopeEnd() {
    314                         @Override
    315                         public void close() {
    316                                 assert isActive();
    317                                 treeModel.nodeChanged(node);
    318                                 jtree.setSelectionPath(selection);
    319                         }
    320                 };
    321         }
    322 
    323         public void selectTreeNode(final TreeNode treeNode) {
    324                 assert isActive();
    325                 /*              final Panel panel = treeNode.getOrCreatePanel();
    326                  if (panel == null) {
    327                  return;
    328                  }
    329                  panel.setCurrentTreeNode(treeNode);
    330                  treeNode.updateData();
    331                  showPanel(panel);*/
    332         }
    333 
    334         public TreeNode findTreeNodeByTreePath(TreePath treePath) {
     313        public void loadChildren(Path path, boolean reload) {
     314                if (path == null) {
     315                        return;
     316                }
     317                AccessInterface access = TreeOperations.bindAccess(path);
     318
     319                int count = access.getCompositeParamCount();
     320                for (int i = 0; i < count; ++i) {
     321                        Path childPath = path.appendParam(access.getCompositeParam(i)).tryFindResolution();
     322                        loadPath(childPath, reload);
     323                }
     324
     325        }
     326
     327        public void loadPath(Path path, boolean reload) {
     328                if (path == null) {
     329                        return;
     330                }
     331                if (path.isResolved() && !reload) {
     332                        return;
     333                }
     334                path.getTree().get(path, Mode.FETCH, new FutureHandler<Path>(this) {
     335                        @Override
     336                        protected void result(Path result) {
     337                                final TreePath treePath = treeModel.convertToTreePath(result);
     338
     339                                treeModel.nodeStructureChanged(treePath);
     340                                if (treePath.equals(jtree.getSelectionPath())) {
     341                                        treeAtFrames.get(result.getTree()).useOrCreatePanel(treePath);
     342                                }
     343                        }
     344                });
     345        }
     346
     347        public void chooseTreeNode(final TreePath treePath) {
    335348                assert isActive();
    336349                if (treePath == null) {
    337                         return null;
    338                 }
    339                 if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
    340                         return null;
    341                 }
    342                 return (TreeNode) treePath.getLastPathComponent();
    343         }
    344 
    345         public void chooseTreeNode(TreePath treePath) {
    346                 assert isActive();
    347                 final TreeNode treeNode = findTreeNodeByTreePath(treePath);
    348                 if (treeNode == null) {
    349                         return;
    350                 }
    351                 treeNode.select();
    352         }
    353 
    354         protected final ExceptionResultHandler dialogHandler = new ExceptionResultHandler() {
    355 
    356                 @Override
    357                 public void handle(FramsticksException exception) {
    358                         //TODO TEH
    359                         throw exception;
    360 
    361                 }
    362         };
    363 
    364         public void goTo(Path path) {
    365                 assert isActive();
    366                 final TreePath treePath = treeAtFrames.get(path.getTree()).getTreePath(path, false);
    367                 log.info("go to path: " + path + "(" + treePath + ")");
    368 
    369                 this.dispatch(new RunAt<Frame>(dialogHandler) {
    370                         @Override
    371                         protected void runAt() {
    372                                 log.info("executed");
    373                                 jtree.setSelectionPath(treePath);
    374                                 jtree.makeVisible(treePath);
    375                                 assert jtree.isVisible(treePath);
    376                         }
    377                 });
    378 
    379         }
    380 
    381         public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
    382                 assert isActive();
    383 
    384                 try (ScopeEnd e = startChange(parent)) {
    385                         treeModel.insertNodeInto(child, parent, parent.getChildCount());
    386                 }
    387         }
     350                        return;
     351                }
     352                if (treeModel.isChanging()) {
     353                        return;
     354                }
     355
     356                Path path = treeModel.convertToPath(treePath);
     357                if (path == null) {
     358                        return;
     359                }
     360                path = path.assureResolved();
     361                final Tree tree = path.getTree();
     362
     363                treeAtFrames.get(tree).useOrCreatePanel(treePath);
     364                loadChildren(path, false);
     365
     366        }
     367
     368
     369        // public void goTo(Path path) {
     370        //      assert isActive();
     371        //      final TreePath treePath = treeModel.convertToTreePath(path);
     372        //      log.info("go to path: " + path + "(" + treePath + ")");
     373
     374        //      this.dispatch(new RunAt<Frame>(this) {
     375        //              @Override
     376        //              protected void runAt() {
     377        //                      log.info("executed");
     378        //                      jtree.setSelectionPath(treePath);
     379        //                      jtree.makeVisible(treePath);
     380        //                      assert jtree.isVisible(treePath);
     381        //              }
     382        //      });
     383
     384        // }
    388385
    389386        @Override
     
    422419        }
    423420
     421        /**
     422         * @return the treeModel
     423         */
     424        public TreeModel getTreeModel() {
     425                return treeModel;
     426        }
     427
    424428}
  • java/main/src/main/java/com/framsticks/gui/ImageProvider.java

    r90 r98  
    77
    88import javax.swing.*;
     9
    910import java.util.HashMap;
    10 import java.util.LinkedHashMap;
     11import java.util.Map;
    1112
    1213/**
     
    2122         * HashMap stores icons. Key is icon path, Value is icon.
    2223         */
    23         private static HashMap<String, ImageIcon> icons = new LinkedHashMap<String, ImageIcon>();
     24        private static Map<String, ImageIcon> icons = new HashMap<String, ImageIcon>();
    2425
    2526        public static final String IMAGE = "image.png";
    2627        public static final String LOGO = "logo.png";
    2728
    28         //public static final String FOLDER_OPEN = "folder_open.png";
    29         //public static final String FOLDER_CLOSED = "folder_close.png";
    30         //public static final String NODE = "node.png";
     29        public static final String FOLDER_OPEN = "folder_open.png";
     30        public static final String FOLDER_CLOSED = "folder_close.png";
     31        public static final String NODE = "node.png";
    3132
    3233        public static final String SERVER = "server.png";
  • java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java

    r97 r98  
    22
    33import org.apache.log4j.Logger;
     4
    45
    56import javax.swing.*;
     
    6566        }
    6667
    67         @Override
    68         public void setCurrentTreeNode(TreeNode node) {
    69                 super.setCurrentTreeNode(node);
    70         }
    71 
    7268        protected abstract void applyChanges();
    7369
  • java/main/src/main/java/com/framsticks/gui/MultiPanel.java

    r97 r98  
    44
    55import javax.swing.*;
     6import javax.swing.tree.TreePath;
     7
    68import java.awt.*;
    79import java.util.List;
     
    4648
    4749        @Override
    48         public void setCurrentTreeNode(TreeNode currentTreeNode) {
    49                 super.setCurrentTreeNode(currentTreeNode);
     50        public void setCurrentTreePath(TreePath currentTreePath) {
     51                super.setCurrentTreePath(currentTreePath);
    5052                for (Panel p : panels) {
    51                         p.setCurrentTreeNode(currentTreeNode);
     53                        p.setCurrentTreePath(currentTreePath);
    5254                }
    5355        }
  • java/main/src/main/java/com/framsticks/gui/ObjectPanel.java

    r97 r98  
    1212
    1313import javax.swing.*;
     14import javax.swing.tree.TreePath;
    1415
    1516import java.util.Collection;
    16 import java.util.HashMap;
     17import java.util.IdentityHashMap;
    1718import java.util.Map;
    1819import static com.framsticks.util.lang.Containers.filterInstanceof;
    1920
    2021import com.framsticks.util.FramsticksException;
    21 import com.framsticks.util.dispatching.RunAt;
    2222
    2323@SuppressWarnings("serial")
    2424public class ObjectPanel extends ModifiablePanel implements ControlOwner {
    2525
    26         private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
     26        private static final Logger log = Logger.getLogger(ObjectPanel.class);
    2727
    28         final protected Map<Param, Control> components = new HashMap<Param, Control>();
    29         final protected Map<ValueParam, ValueControl> valueControls = new HashMap<ValueParam, ValueControl>();
     28        final protected Map<Param, Control> components = new IdentityHashMap<Param, Control>();
     29        final protected Map<ValueParam, ValueControl> valueControls = new IdentityHashMap<ValueParam, ValueControl>();
    3030
    3131        public ObjectPanel(Panel.Parameters parameters, Collection<Param> params) {
     
    3737                for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
    3838                        valueControls.put(c.getParam(), c);
     39                        c.setUserEnabled(true);
    3940                        c.setListener(new ValueControlListener() {
    4041                                @Override
    4142                                public boolean onChange(Object newValue) {
    42                                         if (currentTreeNode == null) {
     43                                        if (currentTreePath == null) {
    4344                                                return true;
    4445                                        }
    45                                         boolean result = currentTreeNode.changeValue(c, newValue);
     46                                        boolean result = treeAtFrame.changeValue(currentTreePath, c, newValue);
    4647                                        refreshControlButtons();
    4748                                        return result;
     
    5758        protected void applyChanges() {
    5859                assert frame.isActive();
    59                 assert currentTreeNode != null;
    60                 currentTreeNode.pushLocalChanges();
     60                assert currentTreePath != null;
     61                treeAtFrame.pushLocalChanges(currentTreePath);
    6162        }
    6263
    6364        protected void refreshControlButtons() {
    6465                assert frame.isActive();
    65                 applyButton.setEnabled(currentTreeNode.localChanges != null);
     66                applyButton.setEnabled(treeAtFrame.hasLocalChanges(currentTreePath));
    6667        }
    6768
     
    7172        @Override
    7273        public void pullValuesFromLocalToUser(AccessInterface access) {
    73                 assert currentTreeNode != null;
    74                 assert currentTreeNode.path.getTree().isActive();
     74                assert currentTreePath != null;
    7575                log.debug("refreshing components");
    7676
    77                 final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
     77                final Map<ValueControl, Object> values = new IdentityHashMap<ValueControl, Object>();
    7878                for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
    7979                        values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
    8080                }
    8181
    82                 frame.dispatch(new RunAt<Frame>(frame) {
    83                         @Override
    84                         protected void runAt() {
    85                                 if (currentTreeNode.localChanges != null) {
    86                                         for (Map.Entry<ValueControl, Object> e : currentTreeNode.localChanges.entrySet()) {
    87                                                 values.put(e.getKey(), e.getValue());
    88                                         }
    89                                 }
    90                                 for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
    91                                         e.getKey().pushValueToUserInterface(e.getValue());
    92                                 }
    93                                 refreshControlButtons();
    94                                 ObjectPanel.this.revalidate();
     82
     83                NodeAtFrame nodeAtFrame = treeAtFrame.getLocalInfo(currentTreePath);
     84                if (nodeAtFrame != null) {
     85                        for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
     86                                values.put(e.getKey(), e.getValue());
    9587                        }
    96                 });
     88                }
     89
     90                for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
     91                        e.getKey().pushValueToUserInterface(e.getValue());
     92                }
     93                refreshControlButtons();
     94                ObjectPanel.this.revalidate();
    9795
    9896        }
     
    109107
    110108        @Override
    111         public TreeNode getCurrentTreeNode() {
    112                 return super.getCurrentTreeNode();
    113         }
    114 
    115         @Override
    116109        public void handle(FramsticksException exception) {
    117110                frame.handle(exception);
    118111        }
    119112
    120         // public void updateValue() {
    121         //      //assert panel.getFrame().isActive();
     113        @Override
     114        public TreePath getCurrentTreePath() {
     115                return super.getCurrentTreePath();
     116        }
    122117
    123         //      final Node n = panel.getCurrentNode();
    124         //      panel.getBrowser().getManager().invokeLater(new Runnable() {
    125         //              @Override
    126         //              public void run() {
    127         //                      Object v = n.getAccess().get(param, Object.class);
    128         //                      if (v == null) {
    129         //                              v = param.getDef(Object.class);
    130         //                      }
    131         //                      final Object fv = v;
    132         //                      panel.getBrowser().invokeLater(new Runnable() {
    133         //                              @Override
    134         //                              public void run() {
    135         //                                      setValueImpl(fv);
    136         //                              }
    137         //                      });
    138         //              }
    139         //      });
    140         // }
    141118
    142119}
  • java/main/src/main/java/com/framsticks/gui/Panel.java

    r97 r98  
    44import com.framsticks.params.CompositeParam;
    55import com.framsticks.params.FramsClass;
    6 // import org.apache.log4j.Logger;
    76
    87import javax.swing.*;
     8import javax.swing.tree.TreePath;
     9
     10import org.apache.log4j.Logger;
    911
    1012/**
     
    1315@SuppressWarnings("serial")
    1416public abstract class Panel extends JPanel {
     17
     18        private static final Logger log = Logger.getLogger(Panel.class);
     19
    1520
    1621        public static class Parameters {
     
    2833        // private static final Logger log = Logger.getLogger(Panel.class.getName());
    2934
    30         protected TreeNode currentTreeNode;
     35        protected TreePath currentTreePath;
    3136        protected final TreeAtFrame treeAtFrame;
    3237        protected final Frame frame;
     
    4348                this.className = parameters.param.getContainedTypeName();
    4449                this.setName(parameters.param.getFramsTypeName());
     50                log.debug("created panel: " + this);
    4551        }
    4652
    47         public void setCurrentTreeNode(TreeNode currentTreeNode) {
    48                 this.currentTreeNode = currentTreeNode;
    49         }
    5053
    51         public TreeNode getCurrentTreeNode() {
    52                 return currentTreeNode;
    53         }
    5454
    5555        public final Frame getFrame() {
    5656                return frame;
     57        }
     58
     59        /**
     60         * @return the currentTreePath
     61         */
     62        public TreePath getCurrentTreePath() {
     63                return currentTreePath;
     64        }
     65
     66        /**
     67         * @param currentTreePath the currentTreePath to set
     68         */
     69        public void setCurrentTreePath(TreePath currentTreePath) {
     70                this.currentTreePath = currentTreePath;
    5771        }
    5872
     
    7084        @Override
    7185        public String toString() {
    72                 return uniqueName;
     86                return param.toString() + "(" + uniqueName + ")";
    7387        }
    7488
  • java/main/src/main/java/com/framsticks/gui/StatusBar.java

    r97 r98  
    2222        protected JTextField statusBar;
    2323        protected JPanel swing;
     24        protected ExceptionResultHandler exceptionHandler;
    2425
    2526        /**
     
    3536                        @Override
    3637                        protected void runAt() {
    37                                 log.error("error: " + exception);
     38                                log.error("error: ", exception);
    3839                                statusBar.setText(exception.getShortMessage(new StringBuilder()).toString());
     40                                if (exceptionHandler != null) {
     41                                        exceptionHandler.handle(exception);
     42                                }
    3943                        }
    4044                });
     
    7074        }
    7175
     76        /**
     77         * @return the exceptionHandler
     78         */
     79        public ExceptionResultHandler getExceptionHandler() {
     80                return exceptionHandler;
     81        }
     82
     83        /**
     84         * @param exceptionHandler the exceptionHandler to set
     85         */
     86        public void setExceptionHandler(ExceptionResultHandler exceptionHandler) {
     87                this.exceptionHandler = exceptionHandler;
     88        }
     89
    7290}
  • java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java

    r97 r98  
    11package com.framsticks.gui;
    22
     3import java.awt.event.ActionEvent;
     4import java.awt.event.ActionListener;
     5
     6import com.framsticks.util.dispatching.AbstractJoinable;
    37import com.framsticks.util.dispatching.Dispatcher;
     8import com.framsticks.util.dispatching.JoinableDispatcher;
    49import com.framsticks.util.dispatching.Task;
    510import com.framsticks.util.dispatching.ThrowExceptionHandler;
     
    1116 * @author Piotr Sniegowski
    1217 */
    13 public class SwingDispatcher<C> implements Dispatcher<C> {
     18public class SwingDispatcher<C> extends AbstractJoinable implements JoinableDispatcher<C> {
    1419
    1520        @SuppressWarnings("rawtypes")
     
    3742        @Override
    3843        public final void dispatch(RunAt<? extends C> runnable) {
    39                 assert !(runnable instanceof Task);
     44                if (runnable instanceof Task) {
     45                        final Task<?> task = (Task<?>) runnable;
     46                        Timer timer = new Timer(0, null);
     47                        timer.addActionListener(new ActionListener() {
     48
     49                                @Override
     50                                public void actionPerformed(ActionEvent event) {
     51                                        task.run();
     52                                }
     53
     54                        });
     55                        timer.setInitialDelay((int) (task.getMoment() - System.currentTimeMillis()));
     56                        timer.setRepeats(false);
     57                        timer.start();
     58                        return;
     59                }
    4060                SwingUtilities.invokeLater(runnable);
    4161        }
    4262
     63        @Override
     64        public String getName() {
     65                return "gui";
     66        }
     67
     68        @Override
     69        protected void joinableStart() {
     70
     71        }
     72
     73        @Override
     74        protected void joinableInterrupt() {
     75                finish();
     76        }
     77
     78        @Override
     79        protected void joinableFinish() {
     80
     81        }
     82
     83        @Override
     84        protected void joinableJoin() throws InterruptedException {
     85
     86        }
     87
    4388}
  • java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java

    r97 r98  
    44
    55import com.framsticks.core.Tree;
    6 import com.framsticks.core.TreeListener;
    7 import com.framsticks.core.ListChange;
    86import com.framsticks.core.Node;
    97import com.framsticks.core.Path;
     8import com.framsticks.core.TreeOperations;
     9import com.framsticks.gui.controls.ValueControl;
    1010import com.framsticks.params.CompositeParam;
    1111import com.framsticks.params.FramsClass;
     
    1414
    1515import javax.swing.tree.TreePath;
    16 import com.framsticks.util.dispatching.RunAt;
     16
     17
     18import com.framsticks.util.dispatching.FutureHandler;
     19import com.framsticks.util.lang.Casting;
    1720
    1821/**
    1922 * @author Piotr Sniegowski
    2023 */
    21 public class TreeAtFrame implements TreeListener {
     24public class TreeAtFrame {
    2225
    2326        private static final Logger log = Logger.getLogger(TreeAtFrame.class);
     
    2629        protected final Tree tree;
    2730        protected final Map<String, Panel> knownPanels = new HashMap<String, Panel>();
    28         protected TreeNode rootTreeNode;
     31        protected Node rootNode;
     32
     33        protected Map<TreeNode, NodeAtFrame> nodesStorage = new WeakHashMap<>();
    2934
    3035        public TreeAtFrame(Tree tree, Frame frame) {
     
    9095        }
    9196
    92         @Override
    93         public void onListChange(Path path, ListChange change) {
     97        public boolean hasLocalChanges(TreePath treePath) {
     98                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     99                if (nodeAtFrame == null) {
     100                        return false;
     101                }
     102                return !nodeAtFrame.localChanges.isEmpty();
     103        }
     104
     105        public NodeAtFrame assureLocalInfo(TreePath treePath) {
     106                assert frame.isActive();
     107                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     108
     109                if (nodeAtFrame == null) {
     110                        nodeAtFrame = new NodeAtFrame();
     111                        nodesStorage.put(Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()), nodeAtFrame);
     112                }
     113                return nodeAtFrame;
     114        }
     115
     116        public NodeAtFrame getLocalInfo(TreePath treePath) {
     117                return nodesStorage.get(treePath.getLastPathComponent());
     118        }
     119
     120        public boolean changeValue(TreePath treePath, ValueControl component, Object newValue) {
     121                log.debug("changing value of " + component + " to '" + newValue + "'");
     122
     123                assureLocalInfo(treePath).localChanges.put(component, newValue);
     124
     125                return true;
     126        }
     127
     128        public void pushLocalChanges(TreePath treePath) {
     129                assert frame.isActive();
     130
     131                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     132                if (nodeAtFrame == null) {
     133                        return;
     134                }
     135                Path path = frame.treeModel.convertToPath(treePath);
     136
     137                for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
     138                        TreeOperations.set(path, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(frame) {
     139                                @Override
     140                                protected void result(Integer flag) {
     141                                }
     142                        });
     143                }
     144        }
     145
     146        public void fillPanelWithValues(TreePath treePath) {
     147                NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
     148                if (nodeAtFrame == null) {
     149                        return;
     150                }
     151
     152                if (nodeAtFrame.panel == null) {
     153                        return;
     154                }
     155                Node node = TreeNode.tryGetNode(treePath);
     156                if (node == null) {
     157                        return;
     158                }
     159                nodeAtFrame.panel.setCurrentTreePath(treePath);
     160                nodeAtFrame.panel.pullValuesFromLocalToUser(TreeOperations.bindAccess(node));
     161
     162                frame.showPanel(nodeAtFrame.panel);
    94163
    95164        }
    96165
    97         public TreePath getTreePath(Path path, boolean create) {
    98                 assert frame.isActive();
    99                 TreeNode t = rootTreeNode;
    100                 TreePath result = new TreePath(frame.rootNode).pathByAddingChild(rootTreeNode);
    101                 List<Node> nodes = path.getNodes();
    102                 Iterator<Node> i = nodes.iterator();
    103                 i.next();
    104                 // Node first = i.next();
     166        public void useOrCreatePanel(TreePath treePath) {
     167                // node.assureResolved();
     168                Node node = TreeNode.tryGetNode(treePath);
    105169
    106                 // if (!t.path.isResolved()) {
    107                 //      t.path = new Path(path.getInstance(), nodes, first);
    108                 // }
    109                 while (i.hasNext()) {
    110                         Node n = i.next();
    111                         TreeNode r = null;
    112                         for (TreeNode c : t.childrenIterable()) {
    113                                 if (c.param.getId().equals(n.getParam().getId())) {
    114                                         r = c;
    115                                         break;
    116                                 }
     170                NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
     171
     172                if (nodeAtFrame.panel == null) {
     173                        CompositeParam param = node.getParam();
     174                        nodeAtFrame.panel = findPanel(param.computeAccessId());
     175                        if (nodeAtFrame.panel == null) {
     176                                FramsClass framsClass = node.getTree().getInfoFromCache(param.getContainedTypeName());
     177                                nodeAtFrame.panel = preparePanel(param, framsClass);
    117178                        }
    118                         if (r == null) {
    119                                 log.debug("missing " + n.getParam().getId() + " in " + t);
    120                                 if (!create) {
    121                                         return result;
    122                                 }
    123                                 Path p = Path.build().tree(path.getTree()).buildUpTo(nodes, n).finish();
    124 
    125 
    126                                 log.debug("forced resolution: creating treenode for " + p);
    127                                 TreeNode childNode = new TreeNode(TreeAtFrame.this, p);
    128 
    129                                 frame.addNode(childNode, t);
    130                                 // frame.treeModel.reload();
    131                                 // t.add(childNode);
    132                                 // frame.treeModel.nodeStructureChanged(t);
    133 
    134                                 r = childNode;
    135                         } else {
    136                                 // if (!r.path.isResolved()) {
    137                                 //      r.path = new Path(path.getInstance(), nodes, n);
    138                                 // }
    139                         }
    140                         result = result.pathByAddingChild(r);
    141                         t = r;
    142179                }
    143                 return result;
    144         }
    145 
    146         @Override
    147         public void onFetch(final Path path) {
    148                 assert tree.isActive();
    149                 log.trace("fetched " + path);
    150 
    151                 frame.dispatch(new RunAt<Frame>(frame) {
    152                         @Override
    153                         protected void runAt() {
    154 
    155                                 TreePath treePath = getTreePath(path, true);
    156                                 assert treePath.getPathCount() == path.size() + 1;
    157 
    158                                 final TreeNode result = (TreeNode) treePath.getLastPathComponent();
    159                                 // log.trace("found " + result + " == " + path);
    160                                 tree.dispatch(new RunAt<Tree>(frame) {
    161                                         @Override
    162                                         protected void runAt() {
    163                                                 result.reactForFetchResult(path, null);
    164                                         }
    165                                 });
    166                         }
    167                 });
    168         }
    169 
    170         @Override
    171         public void onRun(Exception e) {
    172 
    173         }
    174 
    175         @Override
    176         public void onStop(Exception e) {
    177 
     180                fillPanelWithValues(treePath);
    178181        }
    179182}
  • java/main/src/main/java/com/framsticks/gui/TreeNode.java

    r97 r98  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.communication.Subscription;
    4 import com.framsticks.communication.util.LoggingStateCallback;
    5 import com.framsticks.core.Mode;
     3import java.lang.ref.WeakReference;
     4import java.util.Iterator;
     5import java.util.LinkedList;
     6import java.util.List;
     7import java.util.concurrent.atomic.AtomicInteger;
     8
     9import javax.swing.tree.TreePath;
     10
     11import org.apache.log4j.Logger;
     12
     13import com.framsticks.core.Node;
    614import com.framsticks.core.Tree;
    7 import com.framsticks.core.TreeOperations;
    8 import com.framsticks.core.ListChange;
    9 import com.framsticks.core.Path;
    10 import com.framsticks.gui.controls.ValueControl;
    1115import com.framsticks.gui.view.TreeCellRenderer;
    1216import com.framsticks.params.AccessInterface;
    1317import com.framsticks.params.CompositeParam;
    14 import com.framsticks.params.FramsClass;
    15 import com.framsticks.params.types.*;
    16 import com.framsticks.remote.*;
     18import com.framsticks.params.types.StringParam;
     19import com.framsticks.util.FramsticksException;
    1720import com.framsticks.util.lang.Casting;
    18 import com.framsticks.util.lang.Holder;
     21import com.framsticks.util.lang.Pair;
    1922import com.framsticks.util.swing.TooltipConstructor;
    20 import com.framsticks.util.dispatching.ExceptionResultHandler;
    21 import com.framsticks.util.dispatching.FutureHandler;
    22 import com.framsticks.util.FramsticksException;
    23 import com.framsticks.util.Logging;
    24 import org.apache.log4j.Logger;
    25 import com.framsticks.util.dispatching.RunAt;
    26 
    27 import javax.swing.tree.DefaultMutableTreeNode;
    28 import java.util.HashMap;
    29 import java.util.LinkedList;
    30 import java.util.List;
    31 import java.util.Map;
    32 import static com.framsticks.util.lang.Containers.filterInstanceof;
    33 import com.framsticks.util.swing.TreeNodeUtils;
    34 import static com.framsticks.core.TreeOperations.*;
    35 
    36 /**
    37  * @author Piotr Sniegowski
    38  */
    39 @SuppressWarnings("serial")
    40 public class TreeNode extends DefaultMutableTreeNode implements NodeListener, ExceptionResultHandler {
    41 
    42         private static final Logger log = Logger.getLogger(TreeNode.class.getName());
    43 
    44         Panel panel;
    45 
    46         final protected Frame frame;
    47         final protected TreeAtFrame treeAtFrame;
    48 
    49         final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
    50         protected Map<ValueControl, Object> localChanges = null;
    51         protected String tooltip;
    52         protected String name;
     23
     24public class TreeNode extends AbstractNode {
     25        private static final Logger log = Logger.getLogger(TreeNode.class);
     26
     27
     28        protected static final AtomicInteger counter = new AtomicInteger();
     29
     30        protected final WeakReference<Object> reference;
    5331        protected final CompositeParam param;
    54         protected String iconName;
    55         protected Path path;
    56 
    57         public TreeNode(TreeAtFrame treeAtFrame, final Path path) {
    58                 this.frame = treeAtFrame.getFrame();
    59                 assert frame.isActive();
    60                 this.param = path.getTop().getParam();
    61                 this.name = this.param.getId();
    62                 log.debug("creating treenode " + name + ": " + path);
    63                 this.path = path;
    64                 this.treeAtFrame = treeAtFrame;
    65 
    66                 iconName = TreeCellRenderer.findIconName(name, path.getTextual());
    67                 tooltip = "?";
    68                 path.getTree().dispatch(new RunAt<Tree>(this) {
    69                         @Override
    70                         protected void runAt() {
    71                                 updateDescriptions(path);
    72                         }
    73                 });
    74         }
    75 
    76         public void fetch(final Path p) {
    77                 assert p.getTree().isActive();
    78                 log.debug("fetching: " + p);
    79                 p.getTree().get(p, Mode.FETCH, new FutureHandler<Object>(this) {
    80                         @Override
    81                         protected void result(Object result) {
    82 
    83                         }
    84                 });
    85         }
    86 
    87         protected void reactForFetchResult(final Path p, Exception e) {
    88                 assert p.getTree().isActive();
    89                 if (Logging.log(log, "fetch", TreeNode.this, e)) {
    90                         frame.dispatch(new RunAt<Frame>(this) {
    91                                 @Override
    92                                 protected void runAt() {
    93                                         log.debug("removing node from tree: " + p);
    94                                         frame.treeModel.removeNodeFromParent(TreeNode.this);
    95                                 }
    96                         });
    97                         return;
    98                 }
    99                 updateChildren(p);
    100                 frame.dispatch(new RunAt<Frame>(this) {
    101                         @Override
    102                         protected void runAt() {
    103                                 //TODO maybe this should be called from some better place
    104                                 useOrCreatePanel();
    105                         }
    106                 });
    107         }
    108 
    109         protected void postUpdatePath(final Path newPath) {
    110                 assert !frame.isActive();
    111                 /** TODO those two actions could be merged into single closure */
    112                 frame.dispatch(new RunAt<Frame>(this) {
    113                         @Override
    114                         protected void runAt() {
    115                                 updatePath(newPath);
    116                         }
    117                 });
    118                 updateDescriptions(newPath);
    119         }
    120 
    121         protected void updatePath(Path newPath) {
    122                 assert frame.isActive();
    123                 if (!path.isResolved()) {
    124                         path = newPath;
    125                         log.debug("updated treenode's path: " + path);
    126                         return;
    127                 }
    128                 if (path.matches(newPath)) {
    129                         return;
    130                 }
    131                 log.debug("removing all children due to path update");
    132                 this.removeAllChildren();
    133                 frame.treeModel.nodeStructureChanged(this);
    134         }
    135 
    136         public Iterable<TreeNode> childrenIterable() {
    137                 return filterInstanceof(TreeNodeUtils.children(TreeNode.this, frame.treeModel), TreeNode.class);
    138         }
    139 
    140         /** Update children, by removing non existing and adding new ones.
     32        protected final Tree tree;
     33        protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>();
     34        protected final int number;
     35
     36        public TreeNode(Tree tree, CompositeParam param, Object object) {
     37                this.tree = tree;
     38                this.param = param;
     39                reference = new WeakReference<Object>(object);
     40                number = counter.getAndIncrement();
     41        }
     42
     43        public TreeNode(Node node) {
     44                this(node.getTree(), node.getParam(), node.assureResolved().getObject());
     45        }
     46
     47        public Node tryCreateNode() {
     48                Object child = lock();
     49                if (child == null) {
     50                        return null;
     51                }
     52                return new Node(tree, param, child);
     53        }
     54
     55        @Override
     56        public int getChildCount() {
     57                Object referent = lock();
     58                if (referent == null) {
     59                        return 0;
     60                }
     61                AccessInterface access = tree.prepareAccess(param).select(referent);
     62                final int count = access.getCompositeParamCount();
     63                return count;
     64        }
     65
     66        public TreeNode getTreeNodeForChild(Object child) {
     67                Iterator<Pair<WeakReference<Object>, WeakReference<TreeNode>>> i = children.iterator();
     68                while (i.hasNext()) {
     69                        Pair<WeakReference<Object>, WeakReference<TreeNode>> p = i.next();
     70                        Object object = p.first.get();
     71                        if (object == null) {
     72                                i.remove();
     73                                continue;
     74                        }
     75                        TreeNode treeNode = p.second.get();
     76                        if (treeNode == null) {
     77                                i.remove();
     78                                continue;
     79                        }
     80                        if (object == child) {
     81                                return treeNode;
     82                        }
     83                }
     84                return null;
     85
     86                // WeakReference<GuiTreeNode> resultReference = children.get(child);
     87                // if (resultReference == null) {
     88                //      return null;
     89                // }
     90                // return resultReference.get();
     91        }
     92
     93        @Override
     94        public AbstractNode getChild(int number) {
     95                Object referent = lock();
     96                if (referent == null) {
     97                        throw new FramsticksException().msg("invalid state - missing referent");
     98                }
     99                AccessInterface access = tree.prepareAccess(param).select(referent);
     100
     101                final int count = access.getCompositeParamCount();
     102                if (number >= count) {
     103                        throw new FramsticksException().msg("invalid state - no child");
     104                }
     105
     106                CompositeParam childParam = access.getCompositeParam(number);
     107                Object child = access.get(childParam, Object.class);
     108                if (child == null) {
     109                        log.debug("returing dummy node for " + childParam + " in " + referent);
     110                        return new EmptyNode(childParam);
     111                }
     112
     113                TreeNode result = getTreeNodeForChild(child);
     114                if (result != null) {
     115                        return result;
     116                }
     117                result = new TreeNode(tree, childParam, child);
     118
     119                children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result)));
     120
     121                return result;
     122
     123        }
     124
     125        public Object lock() {
     126                return reference.get();
     127        }
     128
     129        @Override
     130        public int getIndexOfChild(AbstractNode child) {
     131                final TreeNode treeChild = Casting.tryCast(TreeNode.class, child);
     132                if (treeChild == null) {
     133                        return -1;
     134                }
     135                final Object childObject = treeChild.lock();
     136                final Object parentObject = lock();
     137                if (childObject == null || parentObject == null) {
     138                        return -1;
     139                }
     140                final AccessInterface access = tree.prepareAccess(param).select(parentObject);
     141
     142                final int count = access.getCompositeParamCount();
     143                for (int i = 0; i < count; ++i) {
     144                        Object c = access.get(access.getCompositeParam(i), Object.class);
     145                        if (c == childObject) {
     146                                return i;
     147                        }
     148                }
     149                log.debug(child + " not found in " + this);
     150                return -1;
     151        }
     152
     153        /**
     154         * @return the param
    141155         */
    142         protected void updateChildren(final Path p) {
    143                 assert p.getTree().isActive();
    144                 log.debug("updating children of " + this);
    145                 AccessInterface access = TreeOperations.bindAccess(p.getTree(), p.getTop());
    146                 final List<Path> childrenPaths = new LinkedList<Path>();
    147                 /**Prepare path for each child.*/
    148                 for (CompositeParam param : filterInstanceof(access.getParams(), CompositeParam.class)) {
    149                         childrenPaths.add(p.appendParam(param).tryFindResolution());
    150                 }
    151 
    152                 /**If some child were found, update in frame context.*/
    153                 if (childrenPaths.size() > 0) {
    154                         frame.dispatch(new RunAt<Frame>(this) {
    155                                 @Override
    156                                 protected void runAt() {
    157                                         // TreePath treePath = frame.startChange();
    158                                         updatePath(p);
    159                                         Map<String, TreeNode> current = new HashMap<String, TreeNode>();
    160                                         for (TreeNode n : childrenIterable()) {
    161                                                 current.put(n.path.getLastElement(), n);
    162                                         }
    163                                         assert current.size() == TreeNode.this.getChildCount();
    164                                         assert TreeNode.this.getChildCount() == frame.treeModel.getChildCount(TreeNode.this);
    165                                         log.trace("current " + TreeNode.this.getChildCount() + " children: " + current.values());
    166                                         for (Path childPath : childrenPaths) {
    167                                                 String e = childPath.getLastElement();
    168                                                 if (current.containsKey(e)) {
    169                                                         current.remove(e);
    170                                                         continue;
    171                                                 }
    172                                                 log.debug("update: treenode for " + p);
    173                                                 TreeNode childNode = new TreeNode(treeAtFrame, childPath);
    174 
    175                                                 frame.addNode(childNode, TreeNode.this);
    176                                         }
    177                                         for (TreeNode n : current.values()) {
    178                                                 frame.treeModel.removeNodeFromParent(n);
    179                                         }
    180                                         log.debug("updated children of " + TreeNode.this + ": " + TreeNode.this.getChildCount());
    181                                 }
    182                         });
     156        public CompositeParam getParam() {
     157                return param;
     158        }
     159
     160        /**
     161         * @return the tree
     162         */
     163        public Tree getTree() {
     164                return tree;
     165        }
     166
     167
     168        @Override
     169        public String toString() {
     170                return param.toString();
     171        }
     172
     173        public static Node tryGetNode(TreePath treePath) {
     174                return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode();
     175        }
     176
     177        @Override
     178        public boolean isLeaf() {
     179                Object referent = lock();
     180                if (referent == null) {
     181                        return true;
     182                }
     183                AccessInterface access = tree.prepareAccess(param).select(referent);
     184                return access.getCompositeParamCount() == 0;
     185        }
     186
     187
     188        @Override
     189        public void render(TreeCellRenderer renderer) {
     190                String name = param.getId();
     191
     192                Object child = lock();
     193                if (child != null) {
     194                        AccessInterface access = tree.prepareAccess(param).select(child);
     195
     196                        StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
     197
     198                        if (nameParam != null) {
     199                                name = access.get(nameParam, String.class);
     200                        }
     201
     202                        renderer.setToolTipText(new TooltipConstructor()
     203                                .append("frams", access.getId())
     204                                .append("java", child.getClass().getCanonicalName())
     205                                .append("access", access.getClass().getSimpleName())
     206                                .append("name", name)
     207                                .append("id", param.getId())
     208                                .append("object", Integer.toHexString(System.identityHashCode(child)))
     209                                .append("number", number)
     210                                .build());
    183211                } else {
    184                         log.debug("no children in " + TreeNode.this);
    185                 }
    186         }
    187 
    188         public void select() {
    189                 final Path p = path;
    190 
    191                 p.getTree().dispatch(new RunAt<Tree>(this) {
    192                         @Override
    193                         protected void runAt() {
    194                                 final Path updated = (p.isResolved()) ? p : p.tryFindResolution();
    195                                 if (updated.isResolved()) {
    196                                         Logging.log(log, "update", updated, null);
    197                                         fetch(updated);
    198                                         postUpdatePath(updated);
    199                                         return;
    200                                 }
    201                                 p.getTree().resolve(updated, new FutureHandler<Path>(Logging.logger(log, "resolve and select", TreeNode.this)) {
    202                                         @Override
    203                                         protected void result(Path result) {
    204                                                 fetch(result);
    205                                                 postUpdatePath(result);
    206                                         }
    207                                 });
    208                         }
    209                 });
    210 
    211         }
    212 
    213         @Override
    214         public String toString() {
    215                 return path.toString();
    216         }
    217 
    218         public final Panel getPanel() {
    219                 assert frame.isActive();
    220                 return panel;
    221         }
    222 
    223         protected void updateDescriptions(Path p) {
    224                 assert p.getTree().isActive();
    225 
    226                 if (!p.isResolved()) {
    227                         return;
    228                 }
    229                 AccessInterface access = TreeOperations.bindAccess(p);
    230 
    231                 final String tooltip = new TooltipConstructor().append("frams", access.getId()).append("java", p.getTopObject().getClass().getCanonicalName()).append("access", access.getClass().getSimpleName()).append("name", name).append("id", param.getId()).append("object", Integer.toHexString(System.identityHashCode(this))).build();
    232 
    233                 StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
    234                 final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
    235 
    236                 frame.dispatch(new RunAt<Frame>(this) {
    237                         @Override
    238                         protected void runAt() {
    239                                 TreeNode.this.tooltip = tooltip;
    240                                 TreeNode.this.name = name;
    241 
    242                                 log.debug("updated descriptions for " + path + ": " + name);
    243                         }
    244                 });
    245         }
    246 
    247         public void showPanel() {
    248                 assert frame.isActive();
    249                 assert panel != null;
    250                 frame.showPanel(panel);
    251         }
    252 
    253         public void fillPanelWithValues() {
    254                 assert frame.isActive();
    255                 if (panel == null) {
    256                         return;
    257                 }
    258                 final Path p = path;
    259                 assert p.isResolved();
    260                 panel.setCurrentTreeNode(this);
    261                 p.getTree().dispatch(new RunAt<Tree>(this) {
    262                         @Override
    263                         protected void runAt() {
    264                                 AccessInterface access = TreeOperations.bindAccess(p);
    265                                 panel.pullValuesFromLocalToUser(access);
    266 
    267                                 frame.dispatch(new RunAt<Frame>(this) {
    268                                         @Override
    269                                         protected void runAt() {
    270                                                 showPanel();
    271                                         }
    272                                 });
    273                         }
    274                 });
    275 
    276         }
    277 
    278         public void useOrCreatePanel() {
    279                 assert frame.isActive();
    280                 if (panel != null) {
    281                         log.trace("panel is already attached: " + path);
    282                         fillPanelWithValues();
    283                         return;
    284                 }
    285                 if (!path.isResolved()) {
    286                         log.trace("path is not resolved: " + path);
    287                         return;
    288                 }
    289 
    290                 CompositeParam param = path.getTop().getParam();
    291                 panel = treeAtFrame.findPanel(param.computeAccessId());
    292                 if (panel != null) {
    293                         log.debug("found prepared panel for: " + path);
    294                         fillPanelWithValues();
    295                         return;
    296                 }
    297                 final Path p = path;
    298                 log.debug("preparing panel: " + p);
    299                 p.getTree().dispatch(new RunAt<Tree>(this) {
    300                         @Override
    301                         protected void runAt() {
    302                                 assert p.getTree().isActive();
    303                                 final CompositeParam param = p.getTop().getParam();
    304                                 final FramsClass framsClass = p.getTree().getInfoFromCache(param.getContainedTypeName());
    305                                 frame.dispatch(new RunAt<Frame>(this) {
    306                                         @Override
    307                                         protected void runAt() {
    308                                                 panel = treeAtFrame.preparePanel(param, framsClass);
    309                                                 fillPanelWithValues();
    310                                         }
    311                                 });
    312                         }
    313                 });
    314         }
    315 
    316         public String getTooltip() {
    317                 assert frame.isActive();
    318                 return tooltip;
    319         }
    320 
    321         /*public void subscribe(final EventParam eventParam) {
    322                 assert browser.isActive();
    323                 if (hasSubscribed(eventParam)) {
    324                         log.error(eventParam + " is already subscribed for " + this);
    325                         return;
    326                 }
    327                 Node node = getNode();
    328                 node.getConnection().subscribe(node.getPath() + "/" + eventParam.getId(), new SubscriptionCallback() {
    329                         @Override
    330                         public EventCallback subscribed(final Subscription subscription) {
    331                                 if (subscription == null) {
    332                                         log.error("subscription failed");
    333                                         return null;
    334                                 }
    335                                 if (hasSubscribed(eventParam)) {
    336                                         //abort subscription
    337                                         return null;
    338                                 }
    339                                 userSubscriptions.put(eventParam, subscription);
    340                                 log.debug("subscription succeeded: " + subscription);
    341                                 subscription.setDispatcher(browser);
    342                                 return new EventCallback() {
    343                                         @Override
    344                                         public void call(SourceInterface content) {
    345                                                 assert browser.isActive();
    346                                                 log.info("event " + subscription + " occurred");
    347                                         }
    348                                 };
    349                         }
    350                 });
    351 
    352         }*/
    353 
    354         public boolean hasSubscribed(EventParam param) {
    355                 assert frame.isActive();
    356                 return userSubscriptions.containsKey(param);
    357         }
    358 
    359         public void unsubscribe(EventParam eventParam) {
    360                 assert frame.isActive();
    361                 if (!hasSubscribed(eventParam)) {
    362                         log.error("could not unsubscribe from " + eventParam);
    363                         return;
    364                 }
    365                 userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
    366                 userSubscriptions.remove(eventParam);
    367         }
    368 
    369         // @Override
    370         // public void onChildChange(final Child child, ListChange.Action action) {
    371         // assert browser.manager.isActive();
    372 
    373         // switch (action) {
    374         // case Remove: {
    375         // Dispatching.invokeDispatch(browser, browser.manager, new Runnable() {
    376         // @Override
    377         // public void run() {
    378         // assert browser.manager.isActive();
    379         // final TreeNode treeNode = (TreeNode) child.getUserObject();
    380         // if (treeNode == null) {
    381         // log.error("child " + child + " had no tree node attached");
    382         // return;
    383         // }
    384         // browser.invokeLater(new Runnable() {
    385         // @Override
    386         // public void run() {
    387         // assert browser.isActive();
    388         // TreePath path = browser.startChange();
    389         // //assert treeNode.getParent() == TreeNode.this;
    390         // if (treeNode.getParent() != null) {
    391         // browser.treeModel.removeNodeFromParent(treeNode);
    392         // }
    393         // //remove(treeNode);
    394         // browser.markNodeChanged(TreeNode.this, path);
    395         // }
    396         // });
    397         // }
    398         // });
    399         // break;
    400         // }
    401         // }
    402 
    403         // }
    404 
    405         public String getName() {
    406                 return name;
    407         }
    408 
    409         public String getIconName() {
    410                 return iconName;
    411         }
    412 
    413         @Override
    414         public void onUpgrade(Path path) {
    415         }
    416 
    417         @Override
    418         public void onChange(Path path) {
    419         }
    420 
    421         @Override
    422         public void onChildChange(Path path, ListChange.Action action) {
    423         }
    424 
    425         public final Frame getFrame() {
    426                 return frame;
    427         }
    428 
    429         public boolean changeValue(ValueControl component, Object newValue) {
    430                 log.debug("changing value of " + component + " to '" + newValue + "'");
    431 
    432                 if (localChanges == null) {
    433                         localChanges = new HashMap<ValueControl, Object>();
    434                 }
    435                 localChanges.put(component, newValue);
    436 
    437                 return true;
    438         }
    439 
    440         public Path getTreePath() {
    441                 assert frame.isActive();
    442                 return path;
    443         }
    444 
    445         public void pushLocalChanges() {
    446                 assert frame.isActive();
    447                 if (localChanges == null) {
    448                         return;
    449                 }
    450                 Map<ValueControl, Object> changes = localChanges;
    451                 localChanges = null;
    452                 final Holder<Integer> counter = new Holder<>(changes.size());
    453                 final Path p = path;
    454 
    455                 for (Map.Entry<ValueControl, Object> e : changes.entrySet()) {
    456                         set(p, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(this) {
    457                                 @Override
    458                                 protected void result(Integer flag) {
    459                                         counter.set(counter.get() - 1);
    460                                         if (counter.get() != 0) {
    461                                                 return;
    462                                         }
    463                                         log.debug("applied changes for: " + p);
    464                                         frame.dispatch(new RunAt<Frame>(this) {
    465                                                 @Override
    466                                                 protected void runAt() {
    467                                                         fillPanelWithValues();
    468                                                 }
    469                                         });
    470                                 }
    471 
    472                         });
    473                 }
    474         }
    475 
    476         @Override
    477         public void handle(FramsticksException exception) {
    478                 frame.handle(exception);
    479         }
     212                        renderer.setToolTipText("?");
     213                }
     214                renderer.setText(name);
     215                renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param)));
     216
     217        }
     218
    480219}
  • java/main/src/main/java/com/framsticks/gui/console/InteractiveConsole.java

    r97 r98  
    109109                        }
    110110                });
    111 
    112 
    113111        }
    114112
  • java/main/src/main/java/com/framsticks/gui/console/ManagedConsole.java

    r97 r98  
    33import java.util.LinkedList;
    44import java.util.List;
    5 
    65
    76import com.framsticks.communication.ClientSideManagedConnection;
     
    1110import com.framsticks.communication.Response;
    1211import com.framsticks.communication.queries.ApplicationRequest;
     12import com.framsticks.core.Mode;
    1313import com.framsticks.core.Path;
    1414import static com.framsticks.core.TreeOperations.*;
     
    1717import com.framsticks.params.annotations.AutoAppendAnnotation;
    1818import com.framsticks.params.annotations.FramsClassAnnotation;
     19import com.framsticks.params.types.ListParam;
    1920import com.framsticks.remote.RemoteTree;
    2021import com.framsticks.util.FramsticksException;
     22import com.framsticks.util.dispatching.Dispatching;
    2123import com.framsticks.util.dispatching.FutureHandler;
     24import com.framsticks.util.dispatching.RunAt;
    2225import com.framsticks.util.lang.Casting;
    2326import com.framsticks.util.lang.Containers;
     
    2730@FramsClassAnnotation
    2831public class ManagedConsole extends InteractiveConsole {
     32
    2933
    3034        protected RemoteTree tree;
     
    7074        }
    7175
     76
    7277        @Override
    7378        protected void findCompletionPropositions(final String prefix) {
    7479                Pair<CharSequence, CharSequence> command = Request.takeIdentifier(prefix);
     80                if (command == null) {
     81                        return;
     82                }
    7583
    7684                Casting.throwCast(ApplicationRequest.class, Request.createRequestByTypeString(command.first.toString()));
     
    9098                // final Iterator<String> iterator = Path.splitPath(textual);
    9199
    92                 resolve(tree, textual, new FutureHandler<Path>(this) {
     100                tryGet(tree, textual, new FutureHandler<Path>(this) {
    93101
    94102                        @Override
    95                         protected void result(Path path) {
     103                        protected void result(final Path path) {
    96104                                if (!textual.startsWith(path.getTextual())) {
    97105                                        throw new FramsticksException().msg("invalid state").arg("line", prefix).arg("path", path);
    98106                                }
     107                                assert path.getTree().isActive();
    99108
    100                                 List<String> propositions = new LinkedList<String>();
    101                                 String remaining = textual.substring(path.getTextual().length());
    102                                 remaining = Path.PathBuilder.splitPath(remaining).next();
     109                                final Runnable finalizeCompletion = new Runnable() {
     110                                        @Override
     111                                        public void run() {
     112                                                String remaining = textual.substring(path.getTextual().length());
    103113
    104                                 for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
    105                                         if (p.getId().startsWith(remaining)) {
    106                                                 propositions.add(p.getId());
     114                                                String base = prefix.substring(0, prefix.length() - (textual.length() - path.getTextual().length()));
     115                                                if (path.size() > 1) {
     116                                                        base = base + "/";
     117                                                }
     118
     119                                                if (remaining.startsWith("/")) {
     120                                                        remaining = remaining.substring(1);
     121                                                }
     122
     123                                                if (remaining.indexOf('/') != -1) {
     124                                                        /** It is to long. */
     125                                                        return;
     126                                                }
     127                                                final List<String> propositions = new LinkedList<String>();
     128                                                for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
     129                                                        if (remaining.equals("") || p.getId().startsWith(remaining)) {
     130                                                                propositions.add(base + p.getId());
     131                                                        }
     132                                                }
     133
     134                                                dispatch(new RunAt<ManagedConsole>(ManagedConsole.this) {
     135
     136                                                        @Override
     137                                                        protected void runAt() {
     138                                                                processCompletionResult(prefix, propositions);
     139                                                        }
     140                                                });
    107141                                        }
     142                                };
     143
     144                                if (path.getTop().getParam() instanceof ListParam) {
     145                                        tree.get(path, Mode.FETCH, new FutureHandler<Path>(ManagedConsole.this) {
     146                                                @Override
     147                                                protected void result(Path result) {
     148                                                        finalizeCompletion.run();
     149                                                }
     150                                        });
     151                                        return;
    108152                                }
    109                                 processCompletionResult(prefix, propositions);
     153                                finalizeCompletion.run();
     154
    110155                        }
    111156                });
     
    119164                connection = tree.getConnection();
    120165        }
     166
     167        @Override
     168        protected void joinableStart() {
     169                super.joinableStart();
     170                Dispatching.use(tree, this);
     171        }
     172
     173        @Override
     174        protected void joinableInterrupt() {
     175                Dispatching.drop(tree, this);
     176                super.joinableInterrupt();
     177        }
     178
     179        @Override
     180        protected void joinableJoin() throws InterruptedException {
     181                Dispatching.join(tree);
     182                super.joinableJoin();
     183        }
    121184}
  • java/main/src/main/java/com/framsticks/gui/console/TrackConsole.java

    r97 r98  
    11package com.framsticks.gui.console;
     2
     3import java.awt.BorderLayout;
     4import java.awt.event.ActionEvent;
     5import java.awt.event.ActionListener;
     6
     7import javax.swing.Box;
     8import javax.swing.BoxLayout;
     9import javax.swing.JCheckBox;
    210
    311import com.framsticks.communication.Connection;
     
    816@FramsClassAnnotation
    917public class TrackConsole extends Console implements ConnectionListener {
     18
     19        volatile boolean writeOut = true;
     20        volatile boolean writeIn = true;
    1021
    1122        public TrackConsole() {
     
    3041        }
    3142
    32 
    3343        @Override
    3444        public void connectionOutgoing(String line) {
    35                 dispatchWrite(line);
     45                if (writeOut) {
     46                        dispatchWrite(line);
     47                }
    3648        }
    3749
    3850        @Override
    3951        public void connectionIncomming(String line) {
    40                 dispatchWrite(line);
     52                if (writeIn) {
     53                        dispatchWrite(line);
     54                }
     55        }
     56
     57        @Override
     58        protected void initializeGui() {
     59                super.initializeGui();
     60
     61                final Box box = new Box(BoxLayout.LINE_AXIS);
     62
     63                final JCheckBox outCheckbox = new JCheckBox();
     64                outCheckbox.setText("Show out");
     65                outCheckbox.setSelected(true);
     66                outCheckbox.addActionListener(new ActionListener() {
     67                        @Override
     68                        public void actionPerformed(ActionEvent arg0) {
     69                                writeOut = outCheckbox.isSelected();
     70                        }
     71                });
     72
     73                final JCheckBox inCheckbox = new JCheckBox();
     74                inCheckbox.setText("Show in");
     75                inCheckbox.setSelected(true);
     76                inCheckbox.addActionListener(new ActionListener() {
     77                        @Override
     78                        public void actionPerformed(ActionEvent arg0) {
     79                                writeIn = inCheckbox.isSelected();
     80                        }
     81                });
     82
     83                box.add(outCheckbox);
     84                box.add(Box.createHorizontalStrut(10));
     85                box.add(inCheckbox);
     86
     87                panel.add(box, BorderLayout.PAGE_END);
    4188        }
    4289
  • java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java

    r84 r98  
    2121                super(booleanParam);
    2222                checkBox = new JCheckBox();
    23                 checkBox.setEnabled(!isReadOnly());
    2423                checkBox.addActionListener(new ActionListener() {
    2524
     
    5251        }
    5352
     53        @Override
     54        protected void updateEnabled(boolean enabled) {
     55                checkBox.setEnabled(enabled);
     56        }
     57
    5458}
  • java/main/src/main/java/com/framsticks/gui/controls/Control.java

    r97 r98  
    2424        protected ControlOwner owner;
    2525
     26        protected abstract void updateEnabled(boolean enabled);
     27
     28        private boolean userEnabled = true;
     29
    2630        public Control(Param param) {
    2731                this.param = param;
    2832                setName(param.getId());
    29 
    30                 this.setEnabled(!param.hasFlag(Flags.READONLY));
    31                 // TODO: take care of textField exception: setEditable
    3233        }
    3334
     
    3839        public void setOwner(ControlOwner owner) {
    3940                this.owner = owner;
     41        }
     42
     43        /**
     44         * @return the userEnabled
     45         */
     46        public final boolean isUserEnabled() {
     47                return userEnabled;
     48        }
     49
     50        /**
     51         * @param userEnabled the userEnabled to set
     52         */
     53        public final void setUserEnabled(boolean userEnabled) {
     54                this.userEnabled = userEnabled;
     55                updateEnabled(!isReadonly());
     56        }
     57
     58        public final boolean isReadonly() {
     59                return !userEnabled || param.hasFlag(Flags.READONLY);
    4060        }
    4161
  • java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java

    r97 r98  
    22
    33import javax.swing.JPanel;
     4import javax.swing.tree.TreePath;
    45
    5 import com.framsticks.gui.TreeNode;
     6import com.framsticks.gui.Frame;
    67import com.framsticks.util.dispatching.ExceptionResultHandler;
    78
     
    910
    1011        public JPanel getPanel();
    11         public TreeNode getCurrentTreeNode();
     12        public TreePath getCurrentTreePath();
     13        public Frame getFrame();
    1214
    1315}
  • java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java

    r85 r98  
    2828                }
    2929                list.setEditable(false);
    30                 list.setEnabled(!isReadOnly());
    3130                list.addItemListener(new ItemListener() {
    3231                        @Override
     
    6160        }
    6261
     62        @Override
     63        protected void updateEnabled(boolean enabled) {
     64                list.setEnabled(enabled);
     65
     66        }
     67
    6368}
  • java/main/src/main/java/com/framsticks/gui/controls/EventControl.java

    r84 r98  
    3939        }
    4040
     41        @Override
     42        protected void updateEnabled(boolean enabled) {
     43                button.setEnabled(enabled);
     44        }
     45
    4146        /*
    4247        @Override
  • java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java

    r97 r98  
    33import com.framsticks.core.Tree;
    44import com.framsticks.core.Path;
     5import com.framsticks.gui.Frame;
    56import com.framsticks.gui.Gui;
    6 import com.framsticks.gui.TreeNode;
    77import com.framsticks.params.Param;
    88import com.framsticks.params.ValueParam;
     
    1515import javax.swing.*;
    1616import javax.swing.border.BevelBorder;
     17import javax.swing.tree.TreePath;
    1718
    1819import org.apache.log4j.Logger;
     
    2021import java.awt.event.ActionEvent;
    2122import java.awt.event.ActionListener;
    22 import java.util.HashMap;
     23import java.util.IdentityHashMap;
    2324import java.util.LinkedList;
    2425import java.util.List;
     
    3233        protected final JButton procedureButton;
    3334
    34         final protected Map<ValueParam, ValueControl> components = new HashMap<>();
     35        final protected Map<ValueParam, ValueControl> components = new IdentityHashMap<>();
    3536
    3637        public ProcedureControl(ProcedureParam procedureParam) {
     
    5455                        @Override
    5556                        public void actionPerformed(ActionEvent e) {
    56                                 TreeNode treeNode = owner.getCurrentTreeNode();
    57                                 assert treeNode != null;
    5857
    59                                 log.debug("calling " + getParam() + " on " + treeNode);
    60                                 final Path path = treeNode.getTreePath();
     58                                final Path path = getFrame().getTreeModel().convertToPath(getCurrentTreePath());
    6159
    6260                                final List<Object> arguments = new LinkedList<Object>();
     
    9391
    9492        @Override
    95         public TreeNode getCurrentTreeNode() {
    96                 return owner.getCurrentTreeNode();
    97         }
    98 
    99         @Override
    10093        public ProcedureParam getParam() {
    10194                return (ProcedureParam) param;
    10295        }
    10396
     97        @Override
     98        protected void updateEnabled(boolean enabled) {
     99                procedureButton.setEnabled(enabled);
     100                for (ValueControl vc : components.values()) {
     101                        vc.setUserEnabled(enabled);
     102                }
     103        }
     104
     105        @Override
     106        public Frame getFrame() {
     107                return owner.getFrame();
     108        }
     109
     110        @Override
     111        public TreePath getCurrentTreePath() {
     112                return owner.getCurrentTreePath();
     113        }
     114
    104115}
  • java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java

    r97 r98  
    1717import org.apache.log4j.Logger;
    1818
    19 import com.framsticks.params.Flags;
    2019import com.framsticks.params.types.DecimalParam;
    2120import com.framsticks.params.types.FloatParam;
     
    5554                slider = new JSlider();
    5655
    57                 slider.setEnabled(!isReadOnly());
    5856                slider.setPaintLabels(false);
    5957                if (param instanceof DecimalParam) {
     
    110108                text.setHorizontalAlignment(JSlider.CENTER);
    111109
    112                 text.setEnabled(!param.hasFlag(Flags.READONLY));
    113110
    114111                slider.addChangeListener(new ChangeListener() {
     
    206203        }
    207204
     205        @Override
     206        protected void updateEnabled(boolean enabled) {
     207                slider.setEnabled(enabled);
     208                text.setEnabled(enabled);
     209        }
     210
    208211}
  • java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java

    r97 r98  
    1818                textArea.setLineWrap(true);
    1919                textArea.setWrapStyleWord(true);
    20                 textArea.setEditable(!isReadOnly());
    2120                addDefaultDocumentListener(textArea);
    2221
     
    4746        }
    4847
     48        @Override
     49        protected void updateEnabled(boolean enabled) {
     50                textArea.setEditable(enabled);
     51        }
     52
    4953}
  • java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java

    r90 r98  
    3131                this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Control.LINE_HEIGHT));
    3232
    33                 textField.setEditable(!isReadOnly());
    34 
    3533                addDefaultDocumentListener(textField);
    3634
     
    4846        }
    4947
     48        @Override
     49        protected void updateEnabled(boolean enabled) {
     50                textField.setEnabled(enabled);
     51        }
     52
    5053}
  • java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java

    r97 r98  
    9797        }
    9898
    99         public final boolean isReadOnly() {
    100                 return (param.getFlags() & Flags.READONLY) != 0;
    101         }
    102 
    103 
    10499
    105100}
  • java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java

    r90 r98  
    11package com.framsticks.gui.view;
    22
    3 import com.framsticks.gui.ImageProvider;
    4 import com.framsticks.gui.TreeNode;
     3import java.awt.Component;
    54
    6 import javax.swing.*;
     5import javax.swing.JTree;
    76import javax.swing.tree.DefaultTreeCellRenderer;
    87
    9 import org.apache.log4j.Logger;
    10 
    11 import java.awt.*;
     8import com.framsticks.gui.AbstractNode;
     9import com.framsticks.gui.ImageProvider;
     10import com.framsticks.params.CompositeParam;
    1211
    1312/**
     
    1615@SuppressWarnings("serial")
    1716public class TreeCellRenderer extends DefaultTreeCellRenderer {
    18         private static final Logger log =
    19                 Logger.getLogger(TreeCellRenderer.class);
    20 
    2117
    2218        public TreeCellRenderer() {
    23                 setOpenIcon(null);
    24                 setClosedIcon(null);
    25                 setLeafIcon(null);
     19
     20                // setOpenIcon(ImageProvider.loadImage(ImageProvider.FOLDER_OPEN));
     21                // setClosedIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED));
     22                // setLeafIcon(ImageProvider.loadImage(ImageProvider.NODE));
    2623        }
    2724
     
    3128                        boolean hasFocus) {
    3229
    33                 //super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
    34                 //              row, hasFocus);
     30                super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
     31
    3532                if (value == null) {
     33                        setText("!null value");
    3634                        return this;
    3735                }
    38                 if (!(value instanceof TreeNode)) {
     36
     37                if (!(value instanceof AbstractNode)) {
    3938                        setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
    4039                        setText("framsticks");
    4140                        return this;
    4241                }
    43                 TreeNode treeNode = (TreeNode)value;
    44                 assert treeNode.getFrame().isActive();
    45                 setToolTipText(treeNode.getTooltip());
    46                 setIcon(ImageProvider.loadImage(treeNode.getIconName()));
    47                 setText(treeNode.getName());
     42                ((AbstractNode) value).render(this);
     43
    4844                return this;
    4945        }
    5046
    51         public static String findIconName(String nodeName, String path) {
    52                 if (nodeName == null || path == null) {
    53                         log.warn("given invalid parameters: " + nodeName + " " + path);
    54                         // return null;
    55                         return ImageProvider.SERVER;
     47        public static String findIconName(CompositeParam param) {
     48                switch (param.getFramsTypeName()) {
     49                        case "o Server": return ImageProvider.SERVER;
     50                        case "o Simulator": return ImageProvider.SIMULATOR;
     51                        case "o CLI": return ImageProvider.CLI;
     52                        case "o World": return ImageProvider.WORLD;
     53                        case "o GenePools": return ImageProvider.GENEPOOLS;
     54                        case "l GenePool": return ImageProvider.SIMULATOR; //HERE
     55                        case "o GenePool": return ImageProvider.GENEPOOLS_GROUP; //HERE
     56
     57                        case "o Populations": return ImageProvider.POPULATIONS;
     58                        case "l Population": return ImageProvider.SIMULATOR; ///HERE
     59                        case "o Population": return ImageProvider.POPULATION_GROUP;
     60                        case "o ExpParams": return ImageProvider.EXPERIMENT;
     61                        case "o stats": return ImageProvider.STATISTIC;
     62                        case "l Genotype uid": return ImageProvider.GENOTYPES_GROUP;
     63                        case "o Genotype": return ImageProvider.GENOTYPES;
     64
     65                        case "o Part": return ImageProvider.PART;
     66                        case "o Joint": return ImageProvider.JOINT;
     67                        case "o NeuroDef": return ImageProvider.NEURON_DEF;
     68                        case "o NeuroConn": return ImageProvider.NEURON_DEF;
     69
     70                        case "o MechPart": return ImageProvider.MECH_PART;
     71                        case "o MechJoint": return ImageProvider.MECH_JOINT;
     72                        case "o Neuro": return ImageProvider.NEURON;
     73
     74                        case "l Part": return ImageProvider.PART_GROUP;
     75                        case "l Joint": return ImageProvider.JOINT_GROUP;
     76                        case "l NeuroDef": return ImageProvider.NEURON_DEF_GROUP;
     77                        case "l NeuroConn": return ImageProvider.NEURON_DEF_GROUP;
     78
     79                        case "l MechPart": return ImageProvider.MECH_PART_GROUP;
     80                        case "l MechJoint": return ImageProvider.MECH_JOINT_GROUP;
     81                        case "l Neuro": return ImageProvider.NEURON_GROUP;
     82
     83                        case "o Creature": return ImageProvider.CREATURE;
     84                        case "l Creature uid": return ImageProvider.CREATURES_GROUP;
     85                        case "l Event id": return ImageProvider.EVENT;
     86                        case "o Event": return ImageProvider.EVENT;
     87
    5688                }
    57                 if (path.equals("/")) {
    58                         return ImageProvider.SERVER;
    59                 }
    60                 if (path.endsWith("simulator")) {
    61                         return ImageProvider.SIMULATOR;
    62                 }
    63                 if (path.endsWith("cli")) {
    64                         return ImageProvider.CLI;
    65                 }
    66                 if (path.endsWith("world")) {
    67                         return ImageProvider.WORLD;
    68                 }
    69                 if (path.endsWith("genepools")) {
    70                         return ImageProvider.GENEPOOLS;
    71                 }
    72                 if (path.endsWith("populations")) {
    73                         return ImageProvider.POPULATIONS;
    74                 }
    75                 if (path.endsWith("experiment")) {
    76                         return ImageProvider.EXPERIMENT;
    77                 }
    78                 if (path.endsWith("stats")) {
    79                         return ImageProvider.STATISTIC;
    80                 }
    81                 if (nodeName.equals("creatures") || path.endsWith("creatures")) {
    82                         return ImageProvider.CREATURES_GROUP;
    83                 }
    84                 if (nodeName.equals("Favourite Fields")) {
    85                         return ImageProvider.FAVORITE_FIELDS;
    86                 }
    87                 if (nodeName.equals("genotypes") || path.endsWith("creatures")) {
    88                         return ImageProvider.GENOTYPES_GROUP;
    89                 }
    90                 if (nodeName.equals("parts") || path.endsWith("parts")) {
    91                         return ImageProvider.PART_GROUP;
    92                 }
    93                 if (nodeName.equals("joints") || path.endsWith("joints")) {
    94                         return ImageProvider.JOINT_GROUP;
    95                 }
    96                 if (nodeName.equals("neurodefs") || path.endsWith("neurodefs")) {
    97                         return ImageProvider.NEURON_DEF_GROUP;
    98                 }
    99                 if (nodeName.equals("neuroconns") || path.endsWith("neuroconns")) {
    100                         return ImageProvider.NEURON_DEF_GROUP;
    101                 }
    102                 if (nodeName.equals("mechparts") || path.endsWith("mechparts")) {
    103                         return ImageProvider.MECH_PART_GROUP;
    104                 }
    105                 if (nodeName.equals("mechjoints") || path.endsWith("mechjoints")) {
    106                         return ImageProvider.MECH_JOINT_GROUP;
    107                 }
    108                 if (nodeName.equals("neurons") || path.endsWith("neurons")) {
    109                         return ImageProvider.NEURON_GROUP;
    110                 }
    111                 if (path.matches("^.*parts/[0-9]+$")) {
    112                         return ImageProvider.PART;
    113                 }
    114                 if (path.matches("^.*joints/[0-9]+$")) {
    115                         return ImageProvider.JOINT;
    116                 }
    117                 if (path.matches("^.*neurodefs/[0-9]+$")) {
    118                         return ImageProvider.NEURON_DEF;
    119                 }
    120                 if (path.matches("^.*neuroconns/[0-9]+$")) {
    121                         return ImageProvider.NEURON_DEF;
    122                 }
    123                 if (path.matches("^.*mechparts/[0-9]+$")) {
    124                         return ImageProvider.MECH_PART;
    125                 }
    126                 if (path.matches("^.*mechjoints/[0-9]+$")) {
    127                         return ImageProvider.MECH_JOINT;
    128                 }
    129                 if (path.matches("^.*neurons/[0-9]+$")) {
    130                         return ImageProvider.NEURON;
    131                 }
    132                 if (path.matches("^.*creatures/c[0-9]+$")) {
    133                         return ImageProvider.CREATURE;
    134                 }
    135                 if (path.matches("^.*genotypes/g[0-9]+$")) {
    136                         return ImageProvider.GENOTYPES;
    137                 }
    138                 if (path.matches("^.*populations/groups/[0-9]+$")) {
    139                         return ImageProvider.POPULATION_GROUP;
    140                 }
    141                 if (path.matches("^.*genepools/groups/[0-9]+$")) {
    142                         return ImageProvider.GENEPOOLS_GROUP;
    143                 }
    144                 if (path.matches("^.*events/e[0-9]+$")) {
    145                         return ImageProvider.EVENT;
    146                 }
    147                 return ImageProvider.SIMULATOR;
     89
     90
     91                return ImageProvider.SERVER;
    14892        }
    14993
    15094
     95
    15196}
  • java/main/src/main/java/com/framsticks/hosting/ClientAtServer.java

    r97 r98  
    99import com.framsticks.communication.queries.InfoRequest;
    1010import com.framsticks.communication.queries.SetRequest;
    11 import com.framsticks.core.Mode;
    1211import com.framsticks.core.Tree;
    1312import com.framsticks.core.Path;
     
    1817import com.framsticks.util.dispatching.AbstractJoinable;
    1918import com.framsticks.util.dispatching.Dispatching;
     19import com.framsticks.util.dispatching.ExceptionResultHandler;
    2020import com.framsticks.util.dispatching.FutureHandler;
    2121import com.framsticks.util.dispatching.Joinable;
     
    3131 * @author Piotr Sniegowski
    3232 */
    33 public class ClientAtServer extends AbstractJoinable implements RequestHandler, JoinableParent {
     33public class ClientAtServer extends AbstractJoinable implements RequestHandler, JoinableParent, ExceptionResultHandler {
    3434
    3535        protected final Server server;
     
    5252                assureNotEmpty(request.getPath());
    5353
    54                 resolve(tree, request.getPath(), new FutureHandler<Path>(responseCallback) {
     54                tryGet(tree, request.getPath(), new FutureHandler<Path>(responseCallback) {
    5555                        @Override
    5656                        protected void result(final Path path) {
     57
     58                                if (!path.getTextual().equals(request.getPath())) {
     59                                        throw new FramsticksException().msg("invalid path").arg("path", request.getPath());
     60                                }
    5761
    5862                                // final AccessInterface access = tree.prepareAccess(path);
     
    7377
    7478                                if (request instanceof GetRequest) {
    75                                         tree.get(path, Mode.FETCH, new FutureHandler<Object>(responseCallback) {
    76 
    77                                                 @Override
    78                                                 protected void result(Object result) {
    79                                                         if (result != access.getSelected()) {
    80                                                                 throw new FramsticksException().msg("mismatch objects during fetch").arg("path", path);
    81                                                         }
    82                                                         // TODO Auto-generated method stub
    83                                                         List<File> files = new LinkedList<File>();
    84                                                         ListSink sink = new ListSink();
    85                                                         access.save(sink);
    86                                                         files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
    87                                                         responseCallback.pass(new Response(true, "", files));
    88                                                 }
    89                                         });
     79                                        Object result = path.getTopObject();
     80                                        if (result != access.getSelected()) {
     81                                                throw new FramsticksException().msg("mismatch objects during fetch").arg("path", path);
     82                                        }
     83                                        List<File> files = new LinkedList<File>();
     84                                        ListSink sink = new ListSink();
     85                                        access.save(sink);
     86                                        files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
     87                                        responseCallback.pass(new Response(true, "", files));
    9088
    9189                                        return;
     
    148146        }
    149147
     148        @Override
     149        public void handle(FramsticksException exception) {
     150                tree.handle(exception);
     151        }
    150152
    151153}
  • java/main/src/main/java/com/framsticks/hosting/Server.java

    r97 r98  
    124124                        return;
    125125                }
    126                 //TODO TEH
    127                 acceptThread.dispatch(new RunAt<Accept>(ThrowExceptionHandler.getInstance()) {
     126                acceptThread.dispatch(new RunAt<Accept>(hosted) {
    128127                        @Override
    129128                        protected void runAt() {
  • java/main/src/main/java/com/framsticks/params/AccessInterface.java

    r97 r98  
    11package com.framsticks.params;
    22
    3 import java.util.Collection;
    43
    54import com.framsticks.params.types.ProcedureParam;
     
    7170        Object createAccessee();
    7271
    73         Collection<Param> getParams();
     72        Iterable<Param> getParams();
    7473
    7574        FramsClass getFramsClass();
     
    7776        void tryAutoAppend(Object object);
    7877
     78        int getCompositeParamCount();
     79
     80        CompositeParam getCompositeParam(int number);
     81
    7982
    8083}
  • java/main/src/main/java/com/framsticks/params/ArrayListAccess.java

    r90 r98  
    11package com.framsticks.params;
    22
     3import com.framsticks.util.UnimplementedException;
    34import com.framsticks.util.lang.Numbers;
    45
    56import java.util.ArrayList;
    6 import java.util.Collection;
    7 import java.util.LinkedList;
     7import java.util.Iterator;
    88import java.util.List;
     9import java.util.ListIterator;
    910
    1011/**
     
    3031
    3132        @Override
    32         public Param getParam(int i) {
    33                 //TODO listAccessParam
    34                 return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish();
     33        public CompositeParam getParam(int i) {
     34                if ((i < 0) ||  (i >= list.size())) {
     35                        return null;
     36                }
     37                return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish(CompositeParam.class);
    3538        }
    3639
    3740        @Override
    38         public Param getParam(String id) {
     41        public CompositeParam getParam(String id) {
    3942                Integer i = Numbers.parse(id, Integer.class);
    4043                return (i == null ? null : getParam(i));
     
    5356        @Override
    5457        public <T> T get(int i, Class<T> type) {
    55                 if (i < list.size()) {
    56                         return type.cast(list.get(i));
     58                if ((i < 0) ||  (i >= list.size())) {
     59                        return null;
    5760                }
    58                 return null;
     61                return type.cast(list.get(i));
    5962        }
    6063
     
    112115
    113116        @Override
    114         public Collection<Param> getParams() {
    115                 List<Param> result = new LinkedList<Param>();
    116                 if (list == null) {
    117                         return result;
    118                 }
    119                 for (int i = 0; i < list.size(); ++i) {
    120                         result.add(getParam(i));
    121                 }
    122                 return result;
     117        public Iterable<Param> getParams() {
     118                return new Iterable<Param>() {
     119
     120                        @Override
     121                        public Iterator<Param> iterator() {
     122                                return new Iterator<Param>() {
     123
     124                                        protected ListIterator<Object> internal = list.listIterator();
     125
     126                                        @Override
     127                                        public boolean hasNext() {
     128                                                return internal.hasNext();
     129                                        }
     130
     131                                        @Override
     132                                        public Param next() {
     133                                                Param param = Param.build().id(Integer.toString(internal.nextIndex())).forAccess(elementAccess).finish();
     134                                                internal.next();
     135                                                return param;
     136                                        }
     137
     138                                        @Override
     139                                        public void remove() {
     140                                                throw new UnimplementedException().msg("remove element from list").arg("list", ArrayListAccess.this);
     141
     142                                        }
     143                                };
     144                        }
     145                };
     146        }
     147
     148        @Override
     149        public int getCompositeParamCount() {
     150                return list.size();
     151        }
     152
     153        @Override
     154        public CompositeParam getCompositeParam(int number) {
     155                return getParam(number);
    123156        }
    124157
  • java/main/src/main/java/com/framsticks/params/CompositeParam.java

    r87 r98  
    3636        }
    3737
     38        @Override
     39        public String toString() {
     40                return getId() + ":" + this.getClass().getSimpleName() + "(" + containedTypeName + ")";
     41        }
     42
    3843}
  • java/main/src/main/java/com/framsticks/params/FramsClass.java

    r96 r98  
    4343        protected final List<Param> paramList;
    4444
     45        protected final List<CompositeParam> compositeParamList = new ArrayList<>();
     46
    4547        /**
    4648         * The param entry map <parameterId, param> (for fast accessing of parameters
    4749         * by their name)
    4850         */
    49         protected Map<String, Param> paramEntryMap = new LinkedHashMap<String, Param>();
    50 
    51         // /** The param getId map (for fast lookup of offset based on name */
    52         // protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
     51        protected Map<String, Param> paramEntryMap = new HashMap<>();
     52
    5353
    5454        @ParamAnnotation(id = "props", name = "props")
     
    6767                for (Param param : paramList) {
    6868                        paramEntryMap.put(param.getId(), param);
     69                        if (param instanceof CompositeParam) {
     70                                compositeParamList.add((CompositeParam) param);
     71                        }
    6972                }
    7073
     
    182185        }
    183186
     187        public final int getCompositeParamCount() {
     188                return compositeParamList.size();
     189        }
     190
     191        public final CompositeParam getCompositeParam(int i) {
     192                return compositeParamList.get(i);
     193        }
     194
    184195        @Override
    185196        public String toString() {
     
    190201                return new FramsClassBuilder();
    191202        }
     203
    192204}
  • java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java

    r96 r98  
    99import java.util.ArrayList;
    1010import java.util.Collections;
    11 import java.util.HashMap;
     11import java.util.IdentityHashMap;
    1212import java.util.LinkedList;
    1313import java.util.List;
     
    197197        }
    198198
    199         public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new HashMap<Class<?>, FramsClass>());
     199        public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new IdentityHashMap<Class<?>, FramsClass>());
    200200
    201201        public FramsClass forClass(Class<?> javaClass) throws ConstructionException {
  • java/main/src/main/java/com/framsticks/params/ReflectionAccess.java

    r96 r98  
    88import java.util.Comparator;
    99import java.util.HashMap;
     10import java.util.IdentityHashMap;
    1011import java.util.List;
    1112import java.util.Map;
     
    5657                }
    5758
    58                 protected final Map<ValueParam, ReflectedSetter> setters = new HashMap<>();
    59                 protected final Map<ValueParam, ReflectedGetter> getters = new HashMap<>();
    60                 protected final Map<ProcedureParam, ReflectedCaller> callers = new HashMap<>();
     59                protected final Map<ValueParam, ReflectedSetter> setters = new IdentityHashMap<>();
     60                protected final Map<ValueParam, ReflectedGetter> getters = new IdentityHashMap<>();
     61                protected final Map<ProcedureParam, ReflectedCaller> callers = new IdentityHashMap<>();
    6162                protected final List<Method> autoAppendMethods = new ArrayList<>();
    6263
  • java/main/src/main/java/com/framsticks/params/Registry.java

    r96 r98  
    77import com.framsticks.util.DoubleMap;
    88import com.framsticks.util.FramsticksException;
     9import com.framsticks.util.lang.Strings;
    910
    10 import java.util.HashMap;
     11import java.util.IdentityHashMap;
    1112import java.util.Map;
    1213import java.util.Set;
     
    2324        protected final DoubleMap<String, Class<?>> javaClasses = new DoubleMap<>();
    2425        protected final DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
    25         protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new HashMap<>();
     26        protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new IdentityHashMap<>();
    2627
    2728        /**
     
    108109        public @Nonnull AccessInterface createAccess(@Nonnull String name) throws ConstructionException {
    109110                try {
     111                        Strings.assureNotEmpty(name);
    110112                        FramsClass framsClass = getFramsClass(name);
    111113                        if (framsClass == null) {
  • java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java

    r97 r98  
    11package com.framsticks.params;
    22
    3 import java.util.Collection;
    43
    54import static com.framsticks.util.lang.Containers.filterInstanceof;
     
    113112                        ReassignResult<?> result = param.reassign(value, oldValue);
    114113                        Object casted = result.getValue();
    115                         if (!casted.equals(oldValue)) {
     114                        if (casted != null && !casted.equals(oldValue)) {
    116115                                internalSet(param, casted);
    117116                        }
     
    273272
    274273        @Override
    275         public Collection<Param> getParams() {
     274        public Iterable<Param> getParams() {
    276275                return framsClass.getParamEntries();
     276        }
     277
     278        @Override
     279        public int getCompositeParamCount() {
     280                return framsClass.getCompositeParamCount();
     281        }
     282
     283        @Override
     284        public CompositeParam getCompositeParam(int number) {
     285                return framsClass.getCompositeParam(number);
    277286        }
    278287
  • java/main/src/main/java/com/framsticks/params/UniqueListAccess.java

    r90 r98  
    11package com.framsticks.params;
    22
     3import com.framsticks.util.FramsticksException;
     4import com.framsticks.util.UnimplementedException;
     5import com.framsticks.util.UnsupportedOperationException;
    36import com.framsticks.util.lang.Casting;
    47import com.framsticks.util.lang.Numbers;
     
    1215public class UniqueListAccess extends ListAccess {
    1316
    14         private static final Logger log = Logger.getLogger(UniqueListAccess.class.getName());
     17        private static final Logger log = Logger.getLogger(UniqueListAccess.class);
    1518
    1619        Map<String, Object> map;
     
    2326        }
    2427
     28        public static Integer getUidNumber(String uid) {
     29                try {
     30                        return Integer.valueOf(uid.substring(1));
     31                } catch (NumberFormatException e) {
     32                        return null;
     33                }
     34        }
     35
     36        public static class UidComparator implements Comparator<String> {
     37
     38                protected String name;
     39
     40                /**
     41                 * @param name
     42                 */
     43                public UidComparator(String name) {
     44                        this.name = name;
     45                }
     46
     47                @Override
     48                public int compare(String a, String b) {
     49                        if (a.equals(b)) {
     50                                return 0;
     51                        }
     52                        int diff = a.length() - b.length();
     53                        if (diff != 0) {
     54                                return diff;
     55                        }
     56                        Integer au = getUidNumber(a);
     57                        Integer bu = getUidNumber(b);
     58                        if (au == null || bu == null) {
     59                                throw new FramsticksException().msg("comparator failure").arg("left", a).arg("right", b).arg("in", this);
     60                        }
     61                        return au - bu;
     62                }
     63
     64                @Override
     65                public String toString() {
     66                        return "comparator " + name;
     67                }
     68
     69
     70        }
     71
    2572        @Override
    2673        public Map<String, Object> createAccessee() {
    27                 return new HashMap<String, Object>();
    28         }
    29 
    30         @Override
    31         public Param getParam(int i) {
    32                 log.error("accesing unique list through index");
    33                 assert false;
    34                 return null;
    35                 //log.error("accesing unique list through index");
    36                 //return null;
    37                 //return Param.build().setId(Integer.toString(i)).setName(elementAccess.getId()).type("o " + elementAccess.getId()).build();
    38         }
    39 
    40         @Override
    41         public Param getParam(String id) {
     74                return new TreeMap<String, Object>(new UidComparator(elementAccess.toString()));
     75        }
     76
     77        @Override
     78        public CompositeParam getParam(int i) {
     79                if ((i < 0) ||  (i >= map.size())) {
     80                        return null;
     81                }
     82                return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish(CompositeParam.class);
     83        }
     84
     85        @Override
     86        public CompositeParam getParam(String id) {
    4287                Integer i = Numbers.parse(id, Integer.class);
    4388                if (i != null) {
    4489                        return getParam(i);
    4590                }
    46                 //TODO list access here
    47                 return Param.build().id(id).forAccess(elementAccess).finish();
     91                Integer uidNumber = getUidNumber(id);
     92                if (uidNumber == null) {
     93                        return null;
     94                }
     95                if (!map.containsKey(id)) {
     96                        return null;
     97                }
     98                return Param.build().id(id).forAccess(elementAccess).finish(CompositeParam.class);
    4899        }
    49100
     
    60111        @Override
    61112        public <T> T get(int i, Class<T> type) {
    62                 log.error("accesing unique list through index");
    63                 assert false;
    64                 return null;
    65                 //Object[] values = map.values().toArray();
    66                 //return Casting.tryCast(i < values.length ? values[i] : null, type);
     113                Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
     114                while (i > 0 && iterator.hasNext()) {
     115                        iterator.next();
     116                        --i;
     117                }
     118                if (i > 0) {
     119                        return null;
     120                }
     121                if (!iterator.hasNext()) {
     122                        return null;
     123                }
     124                return Casting.tryCast(type, iterator.next().getValue());
    67125        }
    68126
     
    73131                        return get(i, type);
    74132                }
    75                 return Casting.tryCast(type, map.containsKey(id) ? map.get(id) : null);
     133                Integer uidNumber = getUidNumber(id);
     134                if (uidNumber == null) {
     135                        return null;
     136                }
     137                return Casting.tryCast(type, map.get(id));
    76138        }
    77139
     
    110172        @Override
    111173        public <T> int set(int i, T value) {
    112                 log.error("accesing unique list through index");
    113                 //return setByUid(value, null);
    114                 return 0;
     174                throw new UnsupportedOperationException().msg("accesing unique list through index");
    115175        }
    116176
     
    184244
    185245        @Override
    186         public Collection<Param> getParams() {
    187                 List<Param> result = new LinkedList<Param>();
    188                 if (map == null) {
    189                         return result;
    190                 }
    191                 for (String k : map.keySet()) {
    192                         result.add(getParam(k));
    193                 }
    194                 return result;
     246        public Iterable<Param> getParams() {
     247                return new Iterable<Param>() {
     248
     249                        @Override
     250                        public Iterator<Param> iterator() {
     251                                return new Iterator<Param>() {
     252
     253                                        protected Iterator<Map.Entry<String, Object>> internal = map.entrySet().iterator();
     254
     255                                        @Override
     256                                        public boolean hasNext() {
     257                                                return internal.hasNext();
     258                                        }
     259
     260                                        @Override
     261                                        public Param next() {
     262                                                return Param.build().id(internal.next().getKey()).forAccess(elementAccess).finish();
     263                                        }
     264
     265                                        @Override
     266                                        public void remove() {
     267                                                throw new UnimplementedException().msg("remove element from list").arg("list", UniqueListAccess.this);
     268
     269                                        }
     270                                };
     271                        }
     272                };
     273        }
     274
     275        @Override
     276        public int getCompositeParamCount() {
     277                return map.size();
     278        }
     279
     280        @Override
     281        public CompositeParam getCompositeParam(int number) {
     282                return getParam(number);
    195283        }
    196284}
  • java/main/src/main/java/com/framsticks/params/types/ObjectParam.java

    r90 r98  
    5050        }
    5151
     52
    5253}
  • java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java

    r87 r98  
    66import com.framsticks.params.ReassignResult;
    77import com.framsticks.params.UniqueListAccess;
     8import com.framsticks.util.lang.Casting;
    89import com.framsticks.util.lang.Numbers;
    910
    10 import java.util.HashMap;
    1111import java.util.Map;
    1212
     
    5454                        information about it's elements is available, which would break resolution flow
    5555                        */
    56                         if (oldValue != null) {
    57                                 return new ReassignResult<Map<?,?>>((Map<?,?>) oldValue);
    58                         }
    59                         return ReassignResult.create(new HashMap<Object, Object>());
     56                        return new ReassignResult<Map<?,?>>(Casting.tryCast(Map.class, oldValue));
     57                        // return ReassignResult.create(new TreeMap<Object, Object>());
    6058                }
    6159
  • java/main/src/main/java/com/framsticks/parsers/F0Parser.java

    r97 r98  
    77import java.text.ParseException;
    88import java.util.ArrayList;
    9 import java.util.Collection;
    109import java.util.List;
    1110
     
    176175                List<Exception> exceptions = new ArrayList<Exception>();
    177176
    178                 Collection<Param> paramsC = access.getParams();
    179                 Param[] params = paramsC.toArray(new Param[] {null});
     177                List<Param> paramsL = new ArrayList<>();
     178
     179                for (Param param : access.getParams()) {
     180                        paramsL.add(param);
     181                }
     182
     183                Param[] params = paramsL.toArray(new Param[] {null});
    180184                if (params.length == 0) {
    181185                        return exceptions;
    182186                }
    183                 for (PrimitiveParam<?> p : Containers.filterInstanceof(paramsC, PrimitiveParam.class)) {
     187                for (PrimitiveParam<?> p : Containers.filterInstanceof(paramsL, PrimitiveParam.class)) {
    184188                        Object def = p.getDef(Object.class);
    185189                        if (def != null) {
  • java/main/src/main/java/com/framsticks/portals/Portal.java

    r97 r98  
    22
    33
    4 import com.framsticks.core.AbstractTreeListener;
    54import com.framsticks.core.Tree;
    6 import com.framsticks.core.TreeOperations;
    7 import com.framsticks.core.Path;
    85import com.framsticks.params.annotations.FramsClassAnnotation;
    96import com.framsticks.params.annotations.ParamAnnotation;
    10 import com.framsticks.util.Logging;
    11 import com.framsticks.util.dispatching.Dispatching;
    12 import com.framsticks.util.dispatching.FutureHandler;
    137import com.framsticks.util.dispatching.JoinableCollection;
    14 import com.framsticks.util.dispatching.RunAt;
    15 import com.framsticks.util.dispatching.ThrowExceptionHandler;
    16 
    17 import org.apache.log4j.Logger;
    188
    199
     
    2313@FramsClassAnnotation
    2414public class Portal extends JoinableCollection<Tree> {
    25 
    26         private final static Logger log = Logger.getLogger(Portal.class.getName());
    2715
    2816        @ParamAnnotation
     
    4937        public void add(final Tree tree) {
    5038                super.add(tree);
    51                 tree.addListener(new AbstractTreeListener() {
    52                         @Override
    53                         public void onRun(Exception e) {
    54                                 assert Dispatching.isThreadSafe();
     39                // tree.addListener(new AbstractTreeListener() {
     40                //      @Override
     41                //      public void onRun(Exception e) {
     42                //              assert Dispatching.isThreadSafe();
    5543
    56                                 super.onRun(e);
     44                //              super.onRun(e);
    5745
    58                                 if (e != null) {
    59                                         return;
    60                                 }
    61                                 final String path = "/simulator/genepools/groups/0/genotypes";
    62                                 tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
    63                                         @Override
    64                                         protected void runAt() {
    65                                                 TreeOperations.resolve(tree, path, new FutureHandler<Path>(Logging.logger(log, "resolve", path)) {
    66                                                         @Override
    67                                                         public void result(Path result) {
    68                                                                 Logging.log(log, "resolve", path, null);
    69                                                         }
    70                                                 });
    71                                         }
    72                                 });
    73                         }
    74                 });
     46                //              if (e != null) {
     47                //                      return;
     48                //              }
     49                //              final String path = "/simulator/genepools/groups/0/genotypes";
     50                //              tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
     51                //                      @Override
     52                //                      protected void runAt() {
     53                //                              tryGet(tree, path, new FutureHandler<Path>(Logging.logger(log, "resolve", path)) {
     54                //                                      @Override
     55                //                                      public void result(Path result) {
     56                //                                              Logging.log(log, "resolve", path, null);
     57                //                                      }
     58                //                              });
     59                //                      }
     60                //              });
     61                //      }
     62                // });
    7563        }
    7664
  • java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java

    r97 r98  
    5555                        for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
    5656                                Object child = access.get(p, Object.class);
    57                                 final Path childPath = path.appendNode(new Node(p, child));
     57                                final Path childPath = path.appendNode(new Node(path.getTree(), p, child));
    5858                                if (childPath.isResolved() && getInfoFromCache(childPath) != null) {
    5959                                        ++dispatched;
     
    6767                                }
    6868                                ++dispatched;
    69                                 tree.resolve(childPath, new FutureHandler<Path>(Logging.logger(log, "resolve", RecursiveFetcher.this)) {
     69                                tree.get(childPath, Mode.FETCH, new FutureHandler<Path>(Logging.logger(log, "resolve", RecursiveFetcher.this)) {
    7070                                        @Override
    7171                                        protected void result(Path result) {
     
    8383
    8484        protected void fetch(final Path path) {
    85                 tree.get(path, Mode.FETCH, new Future<Object>() {
     85                tree.get(path, Mode.FETCH, new Future<Path>() {
    8686
    8787                        @Override
     
    9292
    9393                        @Override
    94                         protected void result(Object object) {
    95                                 process(path);
     94                        protected void result(Path result) {
     95                                process(result);
    9696                        }
    9797                });
  • java/main/src/main/java/com/framsticks/remote/RemoteTree.java

    r97 r98  
    88import com.framsticks.core.AbstractTree;
    99import com.framsticks.core.Mode;
    10 import com.framsticks.core.TreeOperations;
    1110import com.framsticks.core.ListChange;
    12 import com.framsticks.core.Node;
    1311import com.framsticks.core.Path;
    1412import com.framsticks.params.*;
     
    2220import com.framsticks.util.*;
    2321import com.framsticks.util.dispatching.Dispatching;
     22import com.framsticks.util.dispatching.Dispatching.DispatcherWaiter;
    2423import com.framsticks.util.dispatching.Future;
    2524import com.framsticks.util.dispatching.FutureHandler;
     
    2726import com.framsticks.util.dispatching.JoinableParent;
    2827import com.framsticks.util.dispatching.JoinableState;
     28import com.framsticks.util.dispatching.ThrowExceptionHandler;
    2929import com.framsticks.util.lang.Casting;
    3030import com.framsticks.util.lang.Pair;
     
    5252        public Pair<Path, Subscription<?>> getSubscription(Path path) {
    5353                for (Pair<Path, Subscription<?>> s : subscriptions) {
    54                         if (s.first.matches(path)) {
     54                        if (s.first.isTheSameObjects(path)) {
    5555                                return s;
    5656                        }
     
    7575        public void setConnection(final ClientSideManagedConnection connection) {
    7676                this.connection = connection;
    77                 // final ExceptionResultHandler failure = new ExceptionResultHandler() {
    78                 //      @Override
    79                 //      public void handle(FramsticksException exception) {
    80                 //              log.fatal("failed to establish connection: ", exception);
    81                 //              // log.fatal("unsupported protocol version!\n minimal version is: " + "\nmanager protocol is: " + connection.getProtocolVersion());
    82                 //              Dispatching.drop(connection, RemoteTree.this);
    83                 //              fireRun(exception);
    84                 //      }
    85                 // };
    86 
     77        }
     78
     79        public final ClientSideManagedConnection getConnection() {
     80                return connection;
    8781        }
    8882
     
    9387        }
    9488
    95         public final ClientSideManagedConnection getConnection() {
    96                 return connection;
    97         }
    98 
    99         @Override
    100         public void get(final Path path, final PrimitiveParam<?> param, Mode mode, final Future<Object> future) {
     89        @Override
     90        public void get(final Path path, final ValueParam param, Mode mode, final Future<Object> future) {
    10191                assert isActive();
    10292                assert param != null;
    103                 assert path.isResolved();
     93                // assert path.isResolved();
    10494                //TODO only do that if needed
    10595                connection.send(new GetRequest().field(param.getId()).path(path.getTextual()), this, new ClientSideResponseFuture(future) {
     
    10797                        protected void processOk(Response response) {
    10898                                assert isActive();
    109                                 TreeOperations.processFetchedValues(path, response.getFiles());
    110                                 future.pass(bindAccess(path).get(param, Object.class));
     99                                processFetchedValues(path, response.getFiles());
     100                                future.pass(bindAccess(path.tryResolveIfNeeded()).get(param, Object.class));
    111101                        }
    112102                });
     
    164154                                        throw new FramsticksException().msg("path mismatch").arg("returned path", response.getFiles().get(0).getPath());
    165155                                }
    166                                 FramsClass framsClass = TreeOperations.processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
     156                                FramsClass framsClass = processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
    167157
    168158                                CompositeParam thisParam = path.getTop().getParam();
     
    176166
    177167        @Override
    178         public void get(final Path path, Mode mode, final Future<Object> future) {
    179                 assert isActive();
    180                 assert path.getTop().getObject() != null;
     168        public void get(final Path path, final Mode mode, final Future<Path> future) {
     169                assert isActive();
    181170
    182171                log.trace("fetching values for " + path);
    183                 connection.send(new GetRequest().path(path.getTextual()), this, new ClientSideResponseFuture(future) {
    184                         @Override
    185                         protected void processOk(Response response) {
    186                                 assert isActive();
    187                                 TreeOperations.processFetchedValues(path, response.getFiles());
    188                                 future.pass(path.getTopObject());
    189                         }
    190                 });
    191         }
    192 
    193         @Override
    194         public void resolve(final Path path, final Future<Path> future) {
    195                 TreeOperations.resolve(path, future);
    196         }
     172                findInfo(path, new FutureHandler<FramsClass>(future) {
     173                        @Override
     174                        protected void result(FramsClass result) {
     175
     176                                connection.send(new GetRequest().path(path.getTextual()), RemoteTree.this, new ClientSideResponseFuture(future) {
     177                                        @Override
     178                                        protected void processOk(Response response) {
     179                                                assert isActive();
     180                                                Path p = path.tryResolveIfNeeded();
     181                                                processFetchedValues(p, response.getFiles());
     182                                                future.pass(p.tryResolveIfNeeded().assureResolved());
     183                                        }
     184                                });
     185                        }
     186                });
     187        }
     188
    197189
    198190        @Override
    199191        protected void tryRegisterOnChangeEvents(final Path path) {
    200192                assert isActive();
    201                 AccessInterface access = TreeOperations.bindAccess(path);
     193                AccessInterface access = bindAccess(path);
    202194                if (!(access instanceof ListAccess)) {
    203195                        return;
     
    274266                        protected void result(Path result) {
    275267                                log.debug(listChange + ": " + result);
    276                                 fireListChange(result, listChange);
    277268                        }
    278269                };
     
    282273                assert isActive();
    283274                log.debug("reacting to change " + listChange + " in " + path);
    284                 AccessInterface access = TreeOperations.bindAccess(path);
     275                AccessInterface access = bindAccess(path);
    285276                assert access != null;
    286277
    287278                if ((listChange.getAction() == ListChange.Action.Modify) && (listChange.getPosition() == -1)) {
    288279                        final String p = path.getTextual();
    289                         TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
     280                        tryGet(this, p, futureListChanger(listChange, p));
    290281                        return;
    291282                }
     
    296287                        case Add: {
    297288                                final String p = path.getTextual() + "/" + childParam.getId();
    298                                 TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
     289                                tryGet(this, p, futureListChanger(listChange, p));
    299290                                break;
    300291                        }
    301292                        case Remove: {
    302293                                access.set(childParam, null);
    303                                 fireListChange(path, listChange);
    304294                                break;
    305295                        }
    306296                        case Modify: {
    307297                                final String p = path.getTextual() + "/" + childParam.getId();
    308                                 TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
     298                                tryGet(this, p, futureListChanger(listChange, p));
    309299                                break;
    310300                        }
     
    315305        public void set(final Path path, final PrimitiveParam<?> param, final Object value, final Future<Integer> future) {
    316306                assert isActive();
    317                 final Integer flag = TreeOperations.bindAccess(path).set(param, value);
     307                final Integer flag = bindAccess(path).set(param, value);
    318308
    319309                log.trace("storing value " + param + " for " + path);
     
    331321                Dispatching.use(connection, this);
    332322                super.joinableStart();
     323
     324                dispatch(new RunAt<RemoteTree>(ThrowExceptionHandler.getInstance()) {
     325                        @Override
     326                        protected void runAt() {
     327                                final DispatcherWaiter<Tree, Tree> waiter = new DispatcherWaiter<Tree, Tree>(RemoteTree.this);
     328
     329                                connection.send(new InfoRequest().path("/"), waiter, new ClientSideResponseFuture(this) {
     330                                        @Override
     331                                        protected void processOk(Response response) {
     332                                                FramsClass framsClass = processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
     333                                                assignRootParam(Param.build().name("Tree").id(RemoteTree.this.getName()).type("o " + framsClass.getId()).finish(CompositeParam.class));
     334                                        }
     335                                });
     336
     337                                waiter.waitFor();
     338                        }
     339                });
    333340        }
    334341
     
    373380        }
    374381
    375         @Override
    376         public Path create(Path path) {
    377                 assert isActive();
    378                 assert !path.isResolved();
    379                 Path resolved = path.tryFindResolution();
    380                 if (!resolved.isResolved()) {
    381                         log.debug("creating: " + path);
    382                         AccessInterface access = registry.prepareAccess(path.getTop().getParam());
    383                         assert access != null;
    384                         Object child = access.createAccessee();
    385                         assert child != null;
    386                         if (path.size() == 1) {
    387                                 setRoot(new Node(getRoot().getParam(), child));
    388                         } else {
    389                                 bindAccess(this, path.getUnder()).set(path.getTop().getParam(), child);
    390                         }
    391                         resolved = path.appendResolution(child);
    392                 }
    393                 tryRegisterOnChangeEvents(resolved);
    394                 return resolved;
    395         }
     382        // @Override
     383        // public Path create(Path path) {
     384        //      assert isActive();
     385        //      assert !path.isResolved();
     386        //      Path resolved = path.tryFindResolution();
     387        //      if (!resolved.isReso