Changeset 90 for java


Ignore:
Timestamp:
07/02/13 16:20:07 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

CHANGELOG:
Make ProcedureParam? hold only ValueParams?.

Use id instead of names when naming gui components internally.

Basic procedure calling in GUI.

The actual procedure call is currently only backed
by the ObjectInstance?.

Add UnimplementedException?.

Improve naming of various gui elements.

Allow easy navigating in FEST Swing testing.

Add optional explicit order attribute to FramsClassAnnotation?.

That's because java reflection does return declared members
in any specific order. That ordering is needed only for
classes that have no representation in framsticks and need
a deterministic ordering of params.

Add ControlOwner? interface.

Add test for procedure calling in Browser.

First version of ParamAnnotation? for procedures.

Development of ProcedureParam?.

Add draft version of ProcedureParam? implementation in ReflectionAccess?.

Allow viewing FramsClasses? in gui Browser.

Extract ResourceBuilder? from ModelBuilder?.

Remove internalId from Param.

It was currently completely not utilised. Whether it is still needed
after introduction of ParamAnnotation? is arguable.

Add remaining param attributes to ParamAnnotation?.

Change AutoBuilder? semantics.

AutoBuilder? returns list of objects that are to be appended
with methods @AutoAppendAnnotation?.

This allows to omit explicit addition of ModelPackage? to instance
if the instance uses ModelBuilder? (registration of ModelPackage? comes
from schema).

Fix params ordering problem in auto created FramsClasses?.

Improve ObjectInstance?.

Several fixes to ModelBuilder?.

Improve test for ObjectInstance? in Browser.

Make initialization of robot static.

With robot recreated for second browser test, the test hanged
deep in AWT.

Add base convenience base test for Browser tests.

More tests to ObjectInstance?.

Rename Dispatcher.invokeLater() to dispatch().

Add assertDispatch.

It allows assertions in other threads, than TestNGInvoker.
Assertions are gathered after each method invocation and rethrown.

Use timeOut annotation attribute for tests involving some waiting.

Remove firstTask method (merge with joinableStart).

Clean up leftovers.

Remove unused FavouritesXMLFactory (the reading part is already
completely done with generic XmlLoader?, and writing part will be done
based on the same approach if needed).
Move UserFavourite? to the com.framsticks.gui.configuration package.

Remove GenotypeBrowser? as to specific.

This functionality will be available in ObjectInstance?.

Add interface ParamsPackage?.

Package containing registration of Java classes meant to use with
ReflectionAccess? may be in Instance using configuration.

Minor changes.

Make Group immutable.

Add AutoBuilder? interface extending Builder - only those would
be used to automatically build from XML.

Fix groups in FramsClass?.

Minor naming cleanup in Registry.

Add ModelComponent? interface.

All class creating the Model are implementing that interface.

Extract Model.build into ModelBuilder?.

ModelBuilder? will be compatible with other builders
and allow using it from configuration.

Fix NeuroConnection?.

Add synchronous get operation for dispatchers.

Rename JoinableMonitor? to Monitor.

Add ObjectInstance?.

This class is mainly for demonstration
and testing purposes.

Improve FramsServer? runner.

  • improve ExternalProcess? runner,
  • runner can kill the server but also react properly, when the server exists on it's own,
  • set default path to search for framsticks server installation,
  • add LoggingOutputListener?.
Location:
java/main/src
Files:
27 added
7 deleted
85 edited

Legend:

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

    r88 r90  
    4545        protected void joinableStart() {
    4646                try {
    47                         log.info("connecting to " + address);
     47                        log.debug("connecting to " + address);
    4848
    4949                        socket = new Socket(hostName, port);
     
    5151                        socket.setSoTimeout(500);
    5252
    53                         log.info("connected to " + hostName + ":" + port);
     53                        log.debug("connected to " + hostName + ":" + port);
    5454                        connected = true;
    5555                        runThreads();
     
    145145
    146146                public void dispatchResponseProcess(final Response response) {
    147                         Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
     147                        Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>() {
    148148                                @Override
    149149                                public void run() {
     
    193193                sentQuery.dispatcher = dispatcher;
    194194
    195                 senderThread.invokeLater(new RunAt<Connection>(){
     195                senderThread.dispatch(new RunAt<Connection>(){
    196196                        @Override
    197197                        public void run() {
  • java/main/src/main/java/com/framsticks/communication/Connection.java

    r88 r90  
    135135                Dispatching.use(threads, this);
    136136
    137                 receiverThread.invokeLater(new RunAt<Connection>() {
     137                receiverThread.dispatch(new RunAt<Connection>() {
    138138                        @Override
    139139                        public void run() {
  • java/main/src/main/java/com/framsticks/communication/ServerConnection.java

    r88 r90  
    6666
    6767        protected final void respond(final Response response, final Integer id) {
    68                 senderThread.invokeLater(new RunAt<Connection>() {
     68                senderThread.dispatch(new RunAt<Connection>() {
    6969                        @Override
    7070                        public void run() {
  • java/main/src/main/java/com/framsticks/communication/Subscription.java

    r85 r90  
    7575
    7676        public void dispatchCall(final List<File> files) {
    77                 Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
     77                Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>() {
    7878                        @Override
    7979                        public void run() {
  • java/main/src/main/java/com/framsticks/core/Framsticks.java

    r88 r90  
    44import com.framsticks.parsers.XmlLoader;
    55import com.framsticks.util.dispatching.JoinableCollection;
    6 import com.framsticks.util.dispatching.JoinableMonitor;
     6import com.framsticks.util.dispatching.Monitor;
    77
    88import org.apache.log4j.Logger;
     
    2323
    2424        public static Framsticks loadConfiguration(InputStream stream) {
    25                 return new XmlLoader().load(stream, Framsticks.class);
     25                return new XmlLoader().load(Framsticks.class, stream);
    2626        }
    2727
    2828        public static void main(final String[] args) {
    2929
    30                 final Framsticks framsticks = loadConfiguration(Framsticks.class.getResourceAsStream("/configs/framsticks.xml"));
    31 
    32                 new JoinableMonitor(framsticks).use().waitFor().drop().join();
    33 
    34                 // monitor.use();
    35                 // monitor.waitFor();
    36                 // monitor.drop();
    37                 // monitor.join();
     30                new Monitor(loadConfiguration(Framsticks.class.getResourceAsStream("/configs/framsticks.xml")))
     31                        .use()
     32                        .waitFor()
     33                        .drop()
     34                        .join();
    3835
    3936                log.info("exiting main");
  • java/main/src/main/java/com/framsticks/core/Instance.java

    r88 r90  
    88
    99import javax.annotation.Nonnull;
    10 import javax.annotation.OverridingMethodsMustInvokeSuper;
    1110
    1211import org.apache.log4j.Logger;
     
    1413import com.framsticks.communication.File;
    1514import com.framsticks.params.AccessInterface;
     15import com.framsticks.params.CompositeParam;
    1616import com.framsticks.params.ConstructionException;
    1717import com.framsticks.params.FramsClass;
    1818import com.framsticks.params.ListAccess;
    1919import com.framsticks.params.Param;
     20import com.framsticks.params.ParamsPackage;
    2021import com.framsticks.params.Registry;
    2122import com.framsticks.params.ValueParam;
     23import com.framsticks.params.annotations.AutoAppendAnnotation;
    2224import com.framsticks.params.annotations.FramsClassAnnotation;
    2325import com.framsticks.params.types.ObjectParam;
     26import com.framsticks.params.types.ProcedureParam;
    2427import com.framsticks.parsers.Loaders;
    2528import com.framsticks.parsers.MultiParamLoader;
     29import com.framsticks.util.FramsticksException;
    2630import com.framsticks.util.StateFunctor;
    2731import com.framsticks.util.UnsupportedOperationException;
     
    4044        private static final Logger log = Logger.getLogger(Instance.class.getName());
    4145
    42         protected Node root;
     46        private Node root;
     47
     48        protected @Nonnull Node setRoot(CompositeParam param, Object object) {
     49                // if (isRootAssigned()) {
     50                //      throw new FramsticksException().msg("root is already assigned");
     51                // }
     52                // assert isActive();
     53                root = new Node(param, object);
     54                return root;
     55        }
     56
     57        protected @Nonnull Node getRoot() {
     58                // assert isActive();
     59                assert root != null;
     60                return root;
     61        }
     62
     63        public boolean isRootAssigned() {
     64                // assert isActive();
     65                return root != null;
     66        }
    4367
    4468        protected Set<InstanceListener> listeners = new HashSet<InstanceListener>();
     
    6892        }
    6993
    70         public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
    71                 stateFunctor.call(null);
    72         }
    73 
    74         public void fetchValues(Path path, StateFunctor stateFunctor) {
    75                 stateFunctor.call(null);
    76         }
     94        /** This is part of the Instance interface.
     95         *
     96         */
     97        public abstract void fetchValue(Path path, Param param, StateFunctor stateFunctor);
     98
     99        /** This is part of the Instance interface.
     100         *
     101         */
     102        public abstract void fetchValues(Path path, StateFunctor stateFunctor);
     103
     104        /** This is part of the Instance interface.
     105         *
     106         */
     107        public abstract void call(Path path, ProcedureParam param, Object[] arguments, StateFunctor stateFunctor);
    77108
    78109        protected void tryRegisterOnChangeEvents(Path path) {
     
    82113        public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
    83114                assert isActive();
    84                 invokeLater(new RunAt<Instance>() {
     115                dispatch(new RunAt<Instance>() {
    85116                        @Override
    86117                        public void run() {
     
    104135        public void addListener(final InstanceListener listener) {
    105136                assert Dispatching.isThreadSafe();
    106                 Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
     137                Dispatching.dispatchIfNotActive(this, new RunAt<Instance>() {
    107138                        @Override
    108139                        public void run() {
     
    114145        public void removeListener(final InstanceListener listener) {
    115146                assert Dispatching.isThreadSafe();
    116                 Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
     147                Dispatching.dispatchIfNotActive(this, new RunAt<Instance>() {
    117148                        @Override
    118149                        public void run() {
     
    142173        public FramsClass getInfoFromCache(String id) {
    143174                assert isActive();
    144                 return registry.getInfoFromCache(id);
     175                return registry.getFramsClass(id);
    145176        }
    146177
     
    169200        }
    170201
     202        public final AccessInterface bindAccess(String path) {
     203                return bindAccess(getPath(path));
     204        }
     205
    171206        public final AccessInterface bindAccess(Node node) {
     207                assert isActive();
    172208                assert node.getObject() != null;
    173209
    174210                try {
    175                         return registry.prepareAccess(node.getParam()).select(node.getObject());
     211                        AccessInterface access = registry.prepareAccess(node.getParam());
     212                        if (access == null) {
     213                                throw new FramsticksException().msg("failed to prepare access for param").arg("param", node.getParam());
     214                        }
     215                        return access.select(node.getObject());
    176216                } catch (ConstructionException e) {
    177217                        log.error("failed to bind access for " + node.getParam() + ": " + e);
     
    185225
    186226        public final AccessInterface bindAccess(Path path) {
    187                 assert path.isResolved();
     227                path.assureResolved();
    188228                return bindAccess(path.getTop());
    189229        }
     
    260300                        assert child != null;
    261301                        if (path.size() == 1) {
    262                                 root = new Node(root.getParam(), child);
     302                                setRoot(getRoot().getParam(), child);
    263303                        } else {
    264304                                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
     
    277317                FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
    278318                if ("/".equals(file.getPath())) {
    279                         if (root.getParam().getContainedTypeName() == null) {
    280                                 root = new Node(Param.build().name("Instance").id(getName()).type("o " + framsClass.getId()), root.getObject());
    281                         }
    282                 }
    283                 registry.putInfoIntoCache(framsClass);
     319                        if (getRoot().getParam().getContainedTypeName() == null) {
     320                                setRoot(Param.build().name("Instance").id(getName()).type("o " + framsClass.getId()).finish(CompositeParam.class), getRoot().getObject());
     321                        }
     322                }
     323                registry.putFramsClass(framsClass);
    284324                return framsClass;
    285325        }
     
    299339                                loader.go();
    300340                                fireFetch(path);
    301         //            for (NodeListener l : listeners) {
    302         //                l.onChange(this);
    303         //            }
    304341                                return;
    305342                        }
     
    318355                                        String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
    319356                                        //TODO listAccessParam
    320                                         Param param = Param.build().type("o " + accessInterface.getId()).id(id).finish();
     357                                        Param param = Param.build().forAccess(accessInterface).id(id).finish();
    321358                                        Object child = accessInterface.getSelected();
    322359                                        accessInterface.select(null);
     
    327364
    328365                        fireFetch(path);
    329         //        for (NodeListener l : listeners) {
    330         //            l.onChange(this);
    331         //        }
    332366                } catch (Exception e) {
    333367                        log.error("exception occurred while loading: " + e);
     
    358392        }
    359393
     394        @AutoAppendAnnotation
     395        public void usePackage(ParamsPackage paramsPackage) {
     396                log.debug("using package " + paramsPackage + " in instance " + this);
     397                paramsPackage.register(registry);
     398        }
     399
     400        @AutoAppendAnnotation
     401        public void takeFromRegistry(Registry registry) {
     402                log.debug("taking from registry " + registry + " in instance " + this);
     403                this.registry.takeAllFrom(registry);
     404        }
     405
    360406        @Override
    361         @OverridingMethodsMustInvokeSuper
    362         protected void firstTask() {
    363                 root = new Node(Param.build().name("Instance").id(getName()).type("o"), null);
    364                 com.framsticks.model.Package.register(registry);
     407        protected void joinableStart() {
     408                dispatch(new RunAt<Instance>() {
     409                        @Override
     410                        public void run() {
     411                                if (!isRootAssigned()) {
     412                                        setRoot(Param.build().name("Instance").id(getName()).type("o").finish(CompositeParam.class), null);
     413                                }
     414                        }
     415                });
     416                super.joinableStart();
    365417        }
    366418
  • java/main/src/main/java/com/framsticks/core/LocalInstance.java

    r88 r90  
    5050
    5151        protected void acceptNext() {
    52                 acceptThread.invokeLater(new RunAt<Accept>() {
     52                acceptThread.dispatch(new RunAt<Accept>() {
    5353                        @Override
    5454                        public void run() {
     
    5757                                        assert socket != null;
    5858                                        log.debug("accepted socket: " + socket.getInetAddress().getHostAddress());
    59                                         invokeLater(new RunAt<LocalInstance>() {
     59                                        dispatch(new RunAt<LocalInstance>() {
    6060                                                @Override
    6161                                                public void run() {
     
    7474
    7575        public void tryBind(final Integer accept) {
    76                 acceptThread.invokeLater(new RunAt<Accept>() {
     76                acceptThread.dispatch(new RunAt<Accept>() {
    7777                        @Override
    7878                        public void run() {
  • java/main/src/main/java/com/framsticks/core/Node.java

    r87 r90  
    2929
    3030        public Node(@Nonnull ParamBuilder builder, Object object) {
    31                 this((CompositeParam) builder.finish(), object);
     31                this(builder.finish(CompositeParam.class), object);
    3232        }
    3333
  • java/main/src/main/java/com/framsticks/core/Path.java

    r87 r90  
    44import com.framsticks.params.CompositeParam;
    55import com.framsticks.params.Param;
     6import com.framsticks.util.FramsticksException;
    67import com.framsticks.util.dispatching.Dispatching;
    78
     
    3031                        return null;
    3132                }
    32                 return (instance.registry.prepareAccess(param) != null) ? child : null;
     33                try {
     34                        instance.registry.prepareAccess(param);
     35                        return child;
     36                } catch (FramsticksException e) {
     37                }
     38                return null;
    3339        }
    3440
     
    119125                        this.instance = instance;
    120126
    121                         nodes.add(instance.root);
    122                         Node current = instance.root;
     127                        nodes.add(instance.getRoot());
     128                        Node current = instance.getRoot();
    123129
    124130                        StringBuilder b = new StringBuilder();
     
    254260                return ListUtils.unmodifiableList(nodes);
    255261        }
     262
     263        public void assureResolved() {
     264                if (!isResolved()) {
     265                        throw new FramsticksException().msg("path is not resolved").arg("path", this);
     266                }
     267        }
    256268}
    257269
  • java/main/src/main/java/com/framsticks/dumping/FileInstance.java

    r88 r90  
    77import com.framsticks.params.annotations.ParamAnnotation;
    88import com.framsticks.util.dispatching.Future;
     9import com.framsticks.util.dispatching.RunAt;
    910import com.framsticks.util.io.Encoding;
    1011
     
    1718import java.io.InputStreamReader;
    1819
    19 import javax.annotation.OverridingMethodsMustInvokeSuper;
    2020
    2121/**
     
    2323 */
    2424@FramsClassAnnotation
    25 public class FileInstance extends LocalInstance {
     25public abstract class FileInstance extends LocalInstance {
    2626
    2727        private static final Logger log = Logger.getLogger(Instance.class.getName());
     
    4242
    4343        @Override
    44         @OverridingMethodsMustInvokeSuper
    45         protected void firstTask() {
    46                 assert isActive();
    47                 super.firstTask();
    48                 try {
    49                         LoadStream stream = new LoadStream(this.getRootPath(), new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding.getFramsticksCharset())), this, new Future<Path>() {
    50                                 @Override
    51                                 public void result(Path result, Exception e) {
    52                                         if (e != null) {
    53                                                 log.error("failed to load file instance " + FileInstance.this + ": " + e);
    54                                                 fireRun(e);
    55                                                 return;
    56                                         }
    57                                         log.info("loaded file instance " + FileInstance.this);
    58                                         fireRun(null);
    59                                 }
    60                         });
    61                         stream.load();
    62                 } catch (IOException e) {
    63                         log.error("io failure: " + e);
    64                         fireRun(e);
    65                 }
    66         }
    67 
    68         @Override
    6944        public String toString() {
    7045                return "file@" + file.getName();
    7146        }
    7247
     48        @Override
     49        protected void joinableStart() {
     50                dispatch(new RunAt<Instance>() {
    7351
     52                        @Override
     53                        public void run() {
     54                                assert isActive();
     55
     56                                try {
     57                                        LoadStream stream = new LoadStream(FileInstance.this.getRootPath(), new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding.getFramsticksCharset())), FileInstance.this, new Future<Path>() {
     58                                                @Override
     59                                                public void result(Path result, Exception e) {
     60                                                        if (e != null) {
     61                                                                log.error("failed to load file instance " + FileInstance.this + ": " + e);
     62                                                                fireRun(e);
     63                                                                return;
     64                                                        }
     65                                                        log.info("loaded file instance " + FileInstance.this);
     66                                                        fireRun(null);
     67                                                }
     68                                        });
     69                                        stream.load();
     70                                } catch (IOException e) {
     71                                        log.error("io failure: " + e);
     72                                        fireRun(e);
     73                                }
     74                        }
     75
     76                });
     77                super.joinableStart();
     78        }
    7479
    7580}
  • java/main/src/main/java/com/framsticks/dumping/SaveStream.java

    r85 r90  
    4444        protected void dispatchWrite(final Path path) {
    4545                ++dispatched;
    46                 instance.invokeLater(new RunAt<Instance>() {
     46                instance.dispatch(new RunAt<Instance>() {
    4747                        @Override
    4848                        public void run() {
  • java/main/src/main/java/com/framsticks/gui/Browser.java

    r88 r90  
    6969        public void autoResolvePath(final String path, final Future<Path> future) {
    7070                final Instance i = instances.get("localhost");
    71                 i.invokeLater(new RunAt<Instance>() {
     71                i.dispatch(new RunAt<Instance>() {
    7272                        @Override
    7373                        public void run() {
     
    8080                                                }
    8181                                                if (e == null) {
    82                                                         mainFrame.invokeLater(new RunAt<Frame>() {
     82                                                        mainFrame.dispatch(new RunAt<Frame>() {
    8383                                                                @Override
    8484                                                                public void run() {
     
    100100        }
    101101
    102         protected void firstTask() {
     102        protected void initializeGUI() {
    103103                assert isActive();
    104                 log.info("executing first task");
     104                log.debug("executing first task");
    105105
    106106                try {
     
    129129
    130130                for (final Instance i : instances) {
    131                         i.invokeLater(new RunAt<Instance>() {
     131                        i.dispatch(new RunAt<Instance>() {
    132132                                @Override
    133133                                public void run() {
    134134                                        final Path p = i.getRootPath();
    135                                         invokeLater(new RunAt<Browser>() {
     135                                        dispatch(new RunAt<Browser>() {
    136136                                                @Override
    137137                                                public void run() {
     
    183183                Dispatching.use(instances, this);
    184184
    185                 invokeLater(new RunAt<Browser>() {
     185                dispatch(new RunAt<Browser>() {
    186186                        @Override
    187187                        public void run() {
    188                                 firstTask();
     188                                initializeGUI();
    189189                        }
    190190                });
     
    227227
    228228        @Override
    229         public void invokeLater(RunAt<? extends Browser> runnable) {
    230                 SwingDispatcher.getInstance().invokeLater(runnable);
     229        public void dispatch(RunAt<? extends Browser> runnable) {
     230                SwingDispatcher.getInstance().dispatch(runnable);
    231231        }
    232232
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r88 r90  
    285285
    286286        @Override
    287         public void invokeLater(RunAt<? extends Frame> runnable) {
    288                 SwingDispatcher.getInstance().invokeLater(runnable);
     287        public void dispatch(RunAt<? extends Frame> runnable) {
     288                SwingDispatcher.getInstance().dispatch(runnable);
    289289        }
    290290
     
    427427                super.joinableInterrupt();
    428428
    429                 invokeLater(new RunAt<Frame>() {
     429                dispatch(new RunAt<Frame>() {
    430430                        @Override
    431431                        public void run() {
  • java/main/src/main/java/com/framsticks/gui/Gui.java

    r87 r90  
    1414import com.framsticks.gui.controls.CheckBoxControl;
    1515import com.framsticks.gui.controls.Control;
     16import com.framsticks.gui.controls.ControlOwner;
    1617import com.framsticks.gui.controls.EnumControl;
    1718import com.framsticks.gui.controls.EventControl;
     
    3334import com.framsticks.params.types.StringParam;
    3435import com.framsticks.params.types.UniversalParam;
     36import com.framsticks.util.FramsticksException;
    3537import com.framsticks.util.lang.Strings;
    3638
     
    9294        }
    9395
    94         public static void fillWithControls(JPanel panel, Collection<Param> params, Map<Param, Control> components) {
    95                 for (Param param : params) {
     96        public static <P extends Param, C extends Control> void fillWithControls(ControlOwner owner, Collection<P> params, Map<P, C> components, Class<C> controlType) {
     97                JPanel panel = owner.getPanel();
     98                for (P param : params) {
    9699                        if (param.isUserHidden()) {
    97100                                continue;
    98101                        }
    99102                        assert !(param instanceof CompositeParam);
    100                         Control control = Gui.createSuitable(param);
    101                         if (control == null) {
    102                                 log.error("component for param " + param + " of type " + param.getClass().getSimpleName() + " was not added");
    103                                 continue;
     103                        Control c = Gui.createSuitable(param);
     104
     105                        if (!controlType.isInstance(c)) {
     106                                throw new FramsticksException().msg("created control is not of required type").arg("control", c).arg("type", controlType);
    104107                        }
     108
     109                        C control = controlType.cast(c);
     110
     111                        control.setOwner(owner);
     112
    105113                        log.debug("add component for " + param);
    106114                        JPanel line = new JPanel();
    107115                        line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
    108116                        line.setAlignmentX(JPanel.LEFT_ALIGNMENT);
    109                         JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : "? (" + param.getId() + ")");
     117                        JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : (Strings.notEmpty(param.getId()) ? param.getId() : "?"));
    110118                        label.setToolTipText(control.getToolTipText());
    111119                        label.setHorizontalAlignment(JLabel.RIGHT);
  • java/main/src/main/java/com/framsticks/gui/ImageProvider.java

    r84 r90  
    1515public class ImageProvider {
    1616
    17     private final static Logger log = Logger.getLogger(ImageProvider.class.getName());
     17        private final static Logger log = Logger.getLogger(ImageProvider.class.getName());
    1818
    1919
    20     /**
     20        /**
    2121         * HashMap stores icons. Key is icon path, Value is icon.
    2222         */
     
    8080                        return icons.get(imageName);
    8181                }
    82         String resourceName = "/shared/res/network/" + imageName;
     82                String resourceName = "/shared/res/network/" + imageName;
    8383                try {
    84             ImageIcon icon = new ImageIcon(ImageProvider.class.getResource(resourceName));
     84                        ImageIcon icon = new ImageIcon(ImageProvider.class.getResource(resourceName));
    8585                        icons.put(imageName, icon);
    86             return icon;
     86                        return icon;
    8787                } catch (Exception ignored) {
    88             log.error("failed to read icon: " + resourceName);
     88                        log.error("failed to read icon: " + resourceName);
    8989                }
    9090                return null;
  • java/main/src/main/java/com/framsticks/gui/InstanceAtFrame.java

    r88 r90  
    7272                List<Panel> panels = new ArrayList<Panel>();
    7373
    74                 Panel.Parameters parameters = new Panel.Parameters(this, param,
    75                                 framsClass);
     74                Panel.Parameters parameters = new Panel.Parameters(this, param, framsClass);
    7675                for (PanelProvider pp : frame.browser.panelProviders) {
    7776                        Panel p = pp.providePanel(parameters);
     
    150149                log.trace("fetched " + path);
    151150
    152                 frame.invokeLater(new RunAt<Frame>() {
     151                frame.dispatch(new RunAt<Frame>() {
    153152                        @Override
    154153                        public void run() {
     
    159158                                final TreeNode result = (TreeNode) treePath.getLastPathComponent();
    160159                                // log.trace("found " + result + " == " + path);
    161                                 instance.invokeLater(new RunAt<Instance>() {
     160                                instance.dispatch(new RunAt<Instance>() {
    162161                                        @Override
    163162                                        public void run() {
  • java/main/src/main/java/com/framsticks/gui/ObjectPanel.java

    r85 r90  
    22
    33import com.framsticks.gui.controls.Control;
     4import com.framsticks.gui.controls.ControlOwner;
    45import com.framsticks.gui.controls.ValueControl;
    56import com.framsticks.gui.controls.ValueControlListener;
     
    1112
    1213import javax.swing.*;
     14
    1315import java.util.Collection;
    1416import java.util.HashMap;
     
    1820
    1921@SuppressWarnings("serial")
    20 public class ObjectPanel extends ModifiablePanel {
     22public class ObjectPanel extends ModifiablePanel implements ControlOwner {
    2123
    2224        private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
     
    2830                super(parameters);
    2931
    30                 Gui.fillWithControls(contentPanel, params, components);
     32                Gui.fillWithControls(this, params, components, Control.class);
     33                setName(framsClass.getId());
    3134
    3235                for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
     
    4447                        });
    4548                }
     49
    4650                contentPanel.add(Box.createVerticalGlue());
    4751                this.revalidate();
     
    7478                }
    7579
    76                 frame.invokeLater(new RunAt<Frame>() {
     80                frame.dispatch(new RunAt<Frame>() {
    7781                        @Override
    7882                        public void run() {
     
    97101        }
    98102
     103        @Override
     104        public JPanel getPanel() {
     105                return contentPanel;
     106        }
     107
     108        @Override
     109        public TreeNode getCurrentTreeNode() {
     110                return super.getCurrentTreeNode();
     111        }
    99112
    100113        // public void updateValue() {
    101         //      //assert panel.getFrame().isActive();
     114        //      //assert panel.getFrame().isActive();
    102115
    103         //      final Node n = panel.getCurrentNode();
    104         //      panel.getBrowser().getManager().invokeLater(new Runnable() {
    105         //              @Override
    106         //              public void run() {
    107         //                      Object v = n.getAccess().get(param, Object.class);
    108         //                      if (v == null) {
    109         //                              v = param.getDef(Object.class);
    110         //                      }
    111         //                      final Object fv = v;
    112         //                      panel.getBrowser().invokeLater(new Runnable() {
    113         //                              @Override
    114         //                              public void run() {
    115         //                                      setValueImpl(fv);
    116         //                              }
    117         //                      });
    118         //              }
    119         //      });
     116        //      final Node n = panel.getCurrentNode();
     117        //      panel.getBrowser().getManager().invokeLater(new Runnable() {
     118        //              @Override
     119        //              public void run() {
     120        //                      Object v = n.getAccess().get(param, Object.class);
     121        //                      if (v == null) {
     122        //                              v = param.getDef(Object.class);
     123        //                      }
     124        //                      final Object fv = v;
     125        //                      panel.getBrowser().invokeLater(new Runnable() {
     126        //                              @Override
     127        //                              public void run() {
     128        //                                      setValueImpl(fv);
     129        //                              }
     130        //                      });
     131        //              }
     132        //      });
    120133        // }
    121134
  • java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java

    r85 r90  
    2121
    2222        public SwingDispatcher() {
    23                 invokeLater(new RunAt<C>() {
     23                dispatch(new RunAt<C>() {
    2424                        @Override
    2525                        public void run() {
     
    3535
    3636        @Override
    37         public final void invokeLater(RunAt<? extends C> runnable) {
     37        public final void dispatch(RunAt<? extends C> runnable) {
    3838                assert !(runnable instanceof Task);
    3939                SwingUtilities.invokeLater(runnable);
  • java/main/src/main/java/com/framsticks/gui/TreeNode.java

    r88 r90  
    6262                iconName = TreeCellRenderer.findIconName(name, path.getTextual());
    6363                tooltip = "?";
    64                 path.getInstance().invokeLater(new RunAt<Instance>() {
     64                path.getInstance().dispatch(new RunAt<Instance>() {
    6565                        @Override
    6666                        public void run() {
     
    8585                assert p.getInstance().isActive();
    8686                if (Logging.log(log, "fetch", TreeNode.this, e)) {
    87                         frame.invokeLater(new RunAt<Frame>() {
     87                        frame.dispatch(new RunAt<Frame>() {
    8888                                @Override
    8989                                public void run() {
     
    9595                }
    9696                updateChildren(p);
    97                 frame.invokeLater(new RunAt<Frame>() {
     97                frame.dispatch(new RunAt<Frame>() {
    9898                        @Override
    9999                        public void run() {
     
    107107                assert !frame.isActive();
    108108                /** TODO those two actions could be merged into single closure */
    109                 frame.invokeLater(new RunAt<Frame>() {
     109                frame.dispatch(new RunAt<Frame>() {
    110110                        @Override
    111111                        public void run() {
     
    152152                /**If some child were found, update in frame context.*/
    153153                if (childrenPaths.size() > 0) {
    154                         frame.invokeLater(new RunAt<Frame>() {
     154                        frame.dispatch(new RunAt<Frame>() {
    155155                                @Override
    156156                                public void run() {
     
    189189                final Path p = path;
    190190
    191                 p.getInstance().invokeLater(new RunAt<Instance>() {
     191                p.getInstance().dispatch(new RunAt<Instance>() {
    192192                        @Override
    193193                        public void run() {
     
    249249                final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
    250250
    251                 frame.invokeLater(new RunAt<Frame>() {
     251                frame.dispatch(new RunAt<Frame>() {
    252252                        @Override
    253253                        public void run() {
     
    306306                assert p.isResolved();
    307307                panel.setCurrentTreeNode(this);
    308                 p.getInstance().invokeLater(new RunAt<Instance>() {
     308                p.getInstance().dispatch(new RunAt<Instance>() {
    309309                        @Override
    310310                        public void run() {
     
    312312                                panel.pullValuesFromLocalToUser(access);
    313313
    314                                 frame.invokeLater(new RunAt<Frame>() {
     314                                frame.dispatch(new RunAt<Frame>() {
    315315                                        @Override
    316316                                        public void run() {
     
    344344                final Path p = path;
    345345                log.debug("preparing panel: " + p);
    346                 p.getInstance().invokeLater(new RunAt<Instance>() {
     346                p.getInstance().dispatch(new RunAt<Instance>() {
    347347                        @Override
    348348                        public void run() {
     
    350350                                final CompositeParam param = p.getTop().getParam();
    351351                                final FramsClass framsClass = p.getInstance().getInfoFromCache(param.getContainedTypeName());
    352                                 frame.invokeLater(new RunAt<Frame>() {
     352                                frame.dispatch(new RunAt<Frame>() {
    353353                                        @Override
    354354                                        public void run() {
     
    503503                final Map<ValueControl, Object> changes = localChanges;
    504504                localChanges = null;
    505                 instanceAtFrame.getInstance().invokeLater(new RunAt<Instance>() {
     505                instanceAtFrame.getInstance().dispatch(new RunAt<Instance>() {
    506506                        @Override
    507507                        public void run() {
     
    517517                                                        }
    518518                                                        log.debug("applied changes for: " + p);
    519                                                         frame.invokeLater(new RunAt<Frame>() {
     519                                                        frame.dispatch(new RunAt<Frame>() {
    520520                                                                @Override
    521521                                                                public void run() {
  • java/main/src/main/java/com/framsticks/gui/controls/Control.java

    r86 r90  
    2222        protected Frame frame;
    2323        protected final Param param;
     24        protected ControlOwner owner;
    2425
    2526        public Control(Param param) {
    2627                this.param = param;
     28                setName(param.getId());
    2729
    2830                this.setEnabled(!param.hasFlag(Flags.READONLY));
     
    3840        }
    3941
     42        public void setOwner(ControlOwner owner) {
     43                this.owner = owner;
     44        }
     45
    4046        protected void addAsOnlyChild(JComponent component) {
    4147                this.setLayout(new BorderLayout());
  • java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java

    r84 r90  
    11package com.framsticks.gui.controls;
    22
     3import com.framsticks.core.Instance;
     4import com.framsticks.core.Path;
    35import com.framsticks.gui.Gui;
     6import com.framsticks.gui.TreeNode;
    47import com.framsticks.params.Param;
     8import com.framsticks.params.ValueParam;
    59import com.framsticks.params.types.ProcedureParam;
     10import com.framsticks.util.Logging;
     11import com.framsticks.util.StateFunctor;
     12import com.framsticks.util.dispatching.RunAt;
    613
    714import javax.swing.*;
    815import javax.swing.border.BevelBorder;
     16
     17import org.apache.log4j.Logger;
     18
    919import java.awt.event.ActionEvent;
    1020import java.awt.event.ActionListener;
    1121import java.util.HashMap;
     22import java.util.LinkedList;
     23import java.util.List;
    1224import java.util.Map;
    1325
    1426@SuppressWarnings("serial")
    15 public class ProcedureControl extends Control {
    16         // private static final Logger log = Logger.getLogger(Control.class.getName());
     27public class ProcedureControl extends Control implements ControlOwner {
     28
     29        private static final Logger log = Logger.getLogger(ProcedureControl.class);
    1730
    1831        protected final JButton procedureButton;
    1932
    20         final protected Map<Param, Control> components = new HashMap<Param, Control>();
     33        final protected Map<ValueParam, ValueControl> components = new HashMap<>();
    2134
    2235        public ProcedureControl(ProcedureParam procedureParam) {
     
    2437
    2538                procedureButton = new JButton("Call");
     39                procedureButton.setName("call");
    2640
    2741                this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    2842
    29                 Gui.fillWithControls(this, procedureParam.getArgumentsType(), components);
     43                Gui.fillWithControls(this, procedureParam.getArgumentsType(), components, ValueControl.class);
    3044
    3145                if (components.size() != procedureParam.getArgumentsType().size()) {
     
    3953                        @Override
    4054                        public void actionPerformed(ActionEvent e) {
     55                                TreeNode treeNode = owner.getCurrentTreeNode();
     56                                assert treeNode != null;
    4157
    42 /*
    43                                 Node node = panel.getCurrentNode();
    44                                 if (argumentWindow != null) {
    45                                         argumentWindow.askForArguments();
    46                                         return;
     58                                log.debug("calling " + getParam() + " on " + treeNode);
     59                                final Path path = treeNode.getInstancePath();
     60
     61                                final List<Object> arguments = new LinkedList<Object>();
     62                                for (Param arg : getParam().getArgumentsType()) {
     63                                        arguments.add(((ValueControl) components.get(arg)).getCurrentValue());
    4764                                }
    48                                 node.getConnection().send(new CallQuery().setMethod(param.getId()).setPath(node.getPath()).setCallback(new QueryCallback() {
     65
     66                                path.getInstance().dispatch(new RunAt<Instance>() {
    4967                                        @Override
    50                                         public void call(boolean ok, String comment, SourceInterface content) {
    51                                                 if (!ok) {
    52                                                         log.error("failed to call method: " + param);
    53                                                         return;
    54                                                 }
    55                                                 log.debug("successful call of method: " + param);
     68                                        public void run() {
     69                                                path.getInstance().call(path, getParam(), arguments.toArray(), new StateFunctor() {
     70                                                        @Override
     71                                                        public void call(Exception e) {
     72                                                                Logging.log(log, "call procedure", path, e);
     73                                                        }
     74                                                });
    5675                                        }
    57                                 }));
    58 */
     76                                });
    5977                        }
    6078                });
     
    6381        }
    6482
     83        @Override
     84        public JPanel getPanel() {
     85                return this;
     86        }
     87
     88        @Override
     89        public TreeNode getCurrentTreeNode() {
     90                return owner.getCurrentTreeNode();
     91        }
     92
     93        @Override
     94        public ProcedureParam getParam() {
     95                return (ProcedureParam) param;
     96        }
     97
    6598}
  • java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java

    r87 r90  
    2626                super(valueParam);
    2727                textField = new JTextField();
     28                textField.setName("value");
    2829
    2930                textField.setMinimumSize(new Dimension(0, Control.LINE_HEIGHT));
  • java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java

    r87 r90  
    7878        }
    7979
     80        /** This method is meant as a public interface to obtain current and correct value from control.
     81         *
     82         */
     83        public final Object getCurrentValue() {
     84                return filterValueThroughConstraints(pullValueFromUserInterface());
     85        }
     86
    8087        protected boolean notifyOfChange() {
    8188                if (!programmaticChange) {
     
    8390                                return true;
    8491                        }
    85                         return listener.onChange(filterValueThroughConstraints(pullValueFromUserInterface()));
     92                        return listener.onChange(getCurrentValue());
    8693                }
    8794                return true;
  • java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java

    r84 r90  
    9797                        return ImageProvider.NEURON_DEF_GROUP;
    9898                }
     99                if (nodeName.equals("neuroconns") || path.endsWith("neuroconns")) {
     100                        return ImageProvider.NEURON_DEF_GROUP;
     101                }
    99102                if (nodeName.equals("mechparts") || path.endsWith("mechparts")) {
    100103                        return ImageProvider.MECH_PART_GROUP;
     
    113116                }
    114117                if (path.matches("^.*neurodefs/[0-9]+$")) {
     118                        return ImageProvider.NEURON_DEF;
     119                }
     120                if (path.matches("^.*neuroconns/[0-9]+$")) {
    115121                        return ImageProvider.NEURON_DEF;
    116122                }
     
    139145                        return ImageProvider.EVENT;
    140146                }
    141                 return ImageProvider.SERVER;
     147                return ImageProvider.SIMULATOR;
    142148        }
    143149
  • java/main/src/main/java/com/framsticks/hosting/InstanceClient.java

    r88 r90  
    4343        @Override
    4444        public void handle(final ApplicationRequest request, final ResponseCallback<?> responseCallback) {
    45                 instance.invokeLater(new RunAt<Instance>() {
     45                instance.dispatch(new RunAt<Instance>() {
    4646                        @Override
    4747                        public void run() {
  • java/main/src/main/java/com/framsticks/hosting/ServerInstance.java

    r88 r90  
    1616 * @author Piotr Sniegowski
    1717 */
    18 public class ServerInstance extends LocalInstance implements JoinableParent {
     18public abstract class ServerInstance extends LocalInstance implements JoinableParent {
    1919
    2020        private final static Logger log = Logger.getLogger(ServerInstance.class.getName());
     
    2323
    2424        public ServerInstance() {
    25         }
    26 
    27         @Override
    28         protected void firstTask() {
    29                 super.firstTask();
    30                 assert hosted != null;
    31                 Dispatching.use(hosted, this);
    3225        }
    3326
     
    5346                        return null;
    5447                }
    55                 FramsClass cached = registry.getInfoFromCache(id);
     48                FramsClass cached = registry.getFramsClass(id);
    5649                if (cached != null) {
    5750                        return cached;
     
    6760
    6861                        registry.registerReflectedClass(null, id, nativeClass);
    69                         registry.putInfoIntoCache(framsClass);
     62                        registry.putFramsClass(framsClass);
    7063                        return framsClass;
    7164                } catch (ClassNotFoundException ignored) {
     
    9891        public void childChangedState(Joinable joinable, JoinableState state) {
    9992                proceedToState(state);
     93        }
    10094
     95        @Override
     96        protected void joinableStart() {
     97                super.joinableStart();
     98                assert hosted != null;
     99                Dispatching.use(hosted, this);
    101100        }
    102101
    103102        @Override
    104103        protected void joinableInterrupt() {
     104                super.joinableInterrupt();
    105105                Dispatching.drop(hosted, this);
    106106        }
    107107
    108108        @Override
    109         protected void joinableFinish() {
    110 
     109        protected void joinableJoin() throws InterruptedException {
     110                Dispatching.join(hosted);
     111                super.joinableJoin();
    111112        }
    112113
  • java/main/src/main/java/com/framsticks/model/BasePart.java

    r86 r90  
    1616        public void setPosition(Point3d p) { x = p.x; y = p.y; z = p.z; }
    1717
    18         @ParamAnnotation(id = "m")
    19         public double mass = 0.0;
     18        @ParamAnnotation(id = "m", stringType = "f 0.1 999.0 1.0")
     19        public double mass = 1.0;
    2020
    2121        @ParamAnnotation(id = "s")
  • java/main/src/main/java/com/framsticks/model/Creature.java

    r86 r90  
    154154        public final List<Joint> joints = new ArrayList<Joint>();
    155155        @ParamAnnotation
    156         public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
     156        public final List<NeuroDefinition> neurodefs = new ArrayList<NeuroDefinition>();
    157157
    158158        public final List<Part> getParts() { return parts; }
    159159        public final List<Joint> getJoints() { return joints; }
    160         public final List<NeuroDef> getNeuroDefs() { return neurodefs; }
     160        public final List<NeuroDefinition> getNeuroDefs() { return neurodefs; }
    161161
    162162        @ParamAnnotation
  • java/main/src/main/java/com/framsticks/model/Joint.java

    r86 r90  
    1010 */
    1111@FramsClassAnnotation(id = "j")
    12 public class Joint extends BaseJoint {
     12public class Joint extends BaseJoint implements ModelComponent {
    1313
    1414        @ParamAnnotation(id = "i")
  • java/main/src/main/java/com/framsticks/model/Model.java

    r86 r90  
    33import com.framsticks.params.annotations.FramsClassAnnotation;
    44import com.framsticks.params.annotations.ParamAnnotation;
    5 import com.framsticks.util.lang.Casting;
    65import com.framsticks.util.lang.Containers;
    7 import com.framsticks.util.lang.IterableIterator;
    8 import com.framsticks.util.math.Orientation;
    9 import org.apache.log4j.Logger;
    106
    117import java.util.ArrayList;
    12 import java.util.Iterator;
    138import java.util.List;
    149
     
    1712 */
    1813@FramsClassAnnotation(id = "m")
    19 public class Model {
    20 
    21         private final static Logger log = Logger.getLogger(Model.class);
     14public class Model implements ModelComponent {
    2215
    2316        @ParamAnnotation(id = "se")
     
    3932        public final List<Joint> joints = new ArrayList<Joint>();
    4033
    41         @ParamAnnotation
    42         public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
     34        @ParamAnnotation(id = "neurodefs")
     35        public final List<NeuroDefinition> neuroDefinitions = new ArrayList<NeuroDefinition>();
     36
     37        @ParamAnnotation(id = "neuroconns")
     38        public final List<NeuroConnection> neuroConnections = new ArrayList<NeuroConnection>();
    4339
    4440        //TODO: why those methods returns and accepts doubles?
     
    4844        public double getNumjoints() { return (double)joints.size(); }
    4945        @ParamAnnotation
    50         public double getNumneurons() { return (double)neurodefs.size(); }
     46        public double getNumneurons() { return (double)neuroDefinitions.size(); }
    5147
    5248        //this is impossible to use, because numparts field is marked as readonly
     
    5652        public void setNumjoints(double numjoints) { Containers.resizeList(joints, (int)(double)numjoints); }
    5753        @ParamAnnotation
    58         public void setNumneurons(double numneurons) { Containers.resizeList(neurodefs, (int)(double)numneurons); }
     54        public void setNumneurons(double numneurons) { Containers.resizeList(neuroDefinitions, (int)(double)numneurons); }
    5955
    6056        public List<Part> getParts() { return parts; }
    6157        public List<Joint> getJoints() { return joints; }
    62         public List<NeuroDef> getNeuroDefs() { return neurodefs; }
     58        public List<NeuroDefinition> getNeuroDefinitions() { return neuroDefinitions; }
     59        public List<NeuroConnection> getNeuroConnections() { return neuroConnections; }
    6360
    64         public static Model build(List<Object> objects) {
    65                 Iterator<Object> i = objects.iterator();
    66                 if (!i.hasNext()) {
    67                         return null;
    68                 }
    69                 Model f0Genotype = Casting.tryCast(Model.class, i.next());
    70                 if (f0Genotype == null) {
    71                         log.fatal("first object is not a Model");
    72                         return null;
    73                 }
    74                 for (Object object : new IterableIterator<Object>(i)) {
    75                         if (object instanceof Joint) {
    76                                 f0Genotype.joints.add((Joint)object);
    77                                 continue;
    78                         }
    79                         if (object instanceof Part) {
    80                                 f0Genotype.parts.add((Part)object);
    81                                 continue;
    82                         }
    83                         if (object instanceof NeuroDef) {
    84                                 f0Genotype.neurodefs.add((NeuroDef) object);
    85                                 continue;
    86                         }
    87                         log.error("invalid class: " + object.getClass().getCanonicalName());
    88                 }
    89 
    90                 for (Part p : f0Genotype.getParts()) {
    91                         p.setOrientation(new Orientation().rotate(p.getRotation()));
    92                 }
    93                 for (Joint j : f0Genotype.getJoints()) {
    94                         /** based on c++ Joint::attachToParts*/
    95                         Part p1 = f0Genotype.parts.get(j.part1);
    96                         Part p2 = f0Genotype.parts.get(j.part2);
    97                         assert p1 != null && p2 != null;
    98                         Orientation o = new Orientation().rotate(j.getRotation());
    99                         p2.setOrientation(p1.getOrientation().transform(o));
    100                         p2.setPosition(p2.getOrientation().transform(j.getDelta()).add(p1.getPosition()));
    101                 }
    102                 return f0Genotype;
    103         }
    10461}
  • java/main/src/main/java/com/framsticks/model/Part.java

    r86 r90  
    1010 */
    1111@FramsClassAnnotation(id = "p")
    12 public class Part extends BasePart {
     12public class Part extends BasePart implements ModelComponent {
    1313
    1414        @ParamAnnotation
  • java/main/src/main/java/com/framsticks/model/f0/Schema.java

    r88 r90  
    77import com.framsticks.params.annotations.AutoAppendAnnotation;
    88import com.framsticks.params.annotations.FramsClassAnnotation;
    9 import com.framsticks.parsers.XmlLoader;
    10 import com.framsticks.util.DoubleMap;
    11 import com.framsticks.util.FramsticksException;
     9import com.framsticks.params.annotations.ParamAnnotation;
     10import com.framsticks.util.lang.Casting;
    1211
    13 import com.framsticks.model.Package;
    1412
    1513/**
     
    2725
    2826        /** The neuro classes (classess representing different types of neurons). */
    29         private DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
    30         private DoubleMap<String, NeuroClass> neuroClasses = new DoubleMap<>();
     27        private final Registry framsClasses = new Registry();
     28        private final Registry neuroClasses = new Registry();
     29        // private DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
     30        // private DoubleMap<String, NeuroClass> neuroClasses = new DoubleMap<>();
    3131
    3232        public static InputStream getDefaultDefinitionAsStream() {
     
    3535        }
    3636
    37         public static Schema load(InputStream stream) {
     37        protected static Schema defaultSchema;
    3838
    39                 XmlLoader xmlLoader = new XmlLoader();
    40                 xmlLoader.setUseLowerCase(true);
    41                 xmlLoader.getRegistry()
    42                         .registerAndBuild(Schema.class)
    43                         .registerAndBuild(FramsClassBuilder.class)
    44                         .registerAndBuild(NeuroClassBuilder.class)
    45                         .registerAndBuild(ParamBuilder.class)
    46                         .registerAndBuild(NeuroParamBuilder.class)
    47                         .registerAndBuild(GroupBuilder.class)
    48                         ;
    49 
    50                 Package.register(xmlLoader.getRegistry());
    51 
    52                 Object object = xmlLoader.load(Schema.getDefaultDefinitionAsStream());
    53                 if (!(object instanceof Schema)) {
    54                         throw new FramsticksException().msg("failed to load schema");
     39        public synchronized static Schema getDefaultSchema() {
     40                if (defaultSchema == null) {
     41                        defaultSchema = new SchemaBuilder().stream(getDefaultDefinitionAsStream()).finish();
    5542                }
    56                 return (Schema) object;
     43                return defaultSchema;
    5744        }
    5845
     
    6047        }
    6148
     49        @AutoAppendAnnotation
    6250        public void addClass(FramsClass framsClass) {
    63                 registry.putInfoIntoCache(framsClass);
     51                registry.putFramsClass(framsClass);
    6452                if (framsClass instanceof NeuroClass) {
    65                         neuroClasses.put(framsClass.getId(), framsClass.getName(), (NeuroClass) framsClass);
     53                        neuroClasses.putFramsClass(framsClass);
    6654                        return;
    6755                }
    68                 framsClasses.put(framsClass.getId(), framsClass.getName(), framsClass);
     56                framsClasses.putFramsClass(framsClass);
    6957        }
    7058
     
    7462        }
    7563
    76         public Set<NeuroClass> getNeuroClasses() {
    77                 return neuroClasses.getValues();
     64        public Set<FramsClass> getNeuroClasses() {
     65                return neuroClasses.getFramsClasses();
    7866        }
    7967
    8068        public Set<FramsClass> getFramsClasses() {
    81                 return framsClasses.getValues();
     69                return framsClasses.getFramsClasses();
    8270        }
    8371
    8472        public NeuroClass getNeuroClass(String identifier) {
    85                 return neuroClasses.get(identifier);
     73                return Casting.throwCast(NeuroClass.class, neuroClasses.getFramsClass(identifier));
    8674        }
    8775
    8876        public FramsClass getFramsClass(String identifier) {
    89                 return framsClasses.get(identifier);
     77                return framsClasses.getFramsClass(identifier);
    9078        }
    9179
     80        @ParamAnnotation
    9281        public final Registry getRegistry() {
    9382                return registry;
    9483        }
    9584
     85        @ParamAnnotation
     86        public final Registry getFramsRegistry() {
     87                return framsClasses;
     88        }
     89
     90        @ParamAnnotation
     91        public final Registry getNeurosRegistry() {
     92                return neuroClasses;
     93        }
     94
     95
    9696}
  • java/main/src/main/java/com/framsticks/params/AccessInterface.java

    r87 r90  
    22
    33import java.util.Collection;
     4
     5import com.framsticks.params.types.ProcedureParam;
    46
    57
     
    2022        String getId();
    2123
    22         Param getGroupMember(int gi, int n);
    23 
    2424        int getParamCount();
    2525
    26         // void call(int i, Object args, Object ret);
    27         // TODO: as for now it's not necessary to implement this method
     26        Object call(String id, Object[] arguments);
     27
     28        Object call(ProcedureParam param, Object[] arguments);
    2829
    2930        <T> T get(int i, Class<T> type);
  • java/main/src/main/java/com/framsticks/params/ArrayListAccess.java

    r87 r90  
    3232        public Param getParam(int i) {
    3333                //TODO listAccessParam
    34                 return Param.build().id(Integer.toString(i)).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
     34                return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish();
    3535        }
    3636
  • java/main/src/main/java/com/framsticks/params/FramsClass.java

    r88 r90  
    44import com.framsticks.params.annotations.ParamAnnotation;
    55import com.framsticks.util.FramsticksException;
     6import com.framsticks.util.lang.Containers;
    67// import com.framsticks.util.FramsticksException;
    78
     
    5152        // protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
    5253
    53         public Collection<Param> getParamEntries() {
    54                 return paramList;
     54        @ParamAnnotation(id = "props", name = "props")
     55        public List<Param> getParamEntries() {
     56                return Collections.unmodifiableList(paramList);
    5557        }
    5658
     
    6062                this.name = builder.getName();
    6163                this.description = builder.getDescription();
    62                 this.groups = builder.groups;
     64                this.groups = Containers.build(builder.groupBuilders);
    6365                this.paramList = builder.params;
    6466
    6567                for (Param param : paramList) {
    6668                        paramEntryMap.put(param.getId(), param);
    67                         try {
    68                                 Group group = groups.get(param.getGroup());
    69                                 if (group != null) {
    70                                         group.addProperty(param);
    71                                 }
    72                         } catch (IndexOutOfBoundsException ignored) {
    73 
    74                         }
    7569                }
    7670
     
    8882        }
    8983
    90         /**
    91          * Gets the group member.
    92          *
    93          * @param gi
    94          *            the offset of group
    95          * @param pi
    96          *            the offset of member within a group
    97          * @return the pi-th member of group gi
    98          */
    99         public Param getGroupMember(int gi, int pi) {
    100                 if (gi < 0 || pi < 0 || gi >= groups.size()) {
    101                         return null;
    102                 }
    103                 Group group = groups.get(gi);
    104                 return (group != null ? group.getProperty(pi) : null);
     84        public Group getGroup(int groupNumber) {
     85                return Containers.getFromList(groups, groupNumber, "group", this);
    10586        }
    10687
    107         /**
    108          * Gets the group name.
    109          *
    110          * @param gi
    111          *            the offset of group
    112          * @return the group name
    113          */
    114         public String getGroupName(int gi) {
    115                 if (gi < 0 || gi >= groups.size())
    116                         return null;
    117                 return groups.get(gi).name;
    118         }
     88        // /**
     89        //  * Gets the group member.
     90        //  *
     91        //  * @param gi
     92        //  *            the offset of group
     93        //  * @param pi
     94        //  *            the offset of member within a group
     95        //  * @return the pi-th member of group gi
     96        //  */
     97        // public Param getGroupMember(int gi, int pi) {
     98        //      if (gi < 0 || pi < 0 || gi >= groups.size()) {
     99        //              return null;
     100        //      }
     101        //      Group group = groups.get(gi);
     102        //      return (group != null ? group.getProperty(pi) : null);
     103        // }
     104
     105        // /**
     106        //  * Gets the group name.
     107        //  *
     108        //  * @param gi
     109        //  *            the offset of group
     110        //  * @return the group name
     111        //  */
     112        // public String getGroupName(int gi) {
     113        //      if (gi < 0 || gi >= groups.size())
     114        //              return null;
     115        //      return groups.get(gi).name;
     116        // }
    119117
    120118        @ParamAnnotation
  • java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java

    r88 r90  
    2222import com.framsticks.parsers.Loaders;
    2323import com.framsticks.util.Builder;
    24 import com.framsticks.util.FramsticksException;
     24import com.framsticks.util.lang.Containers;
    2525import com.framsticks.util.lang.Strings;
    2626
     
    3838        }
    3939
    40         public static String getParamTypeForNativeType(Type type) {
     40        public static ParamBuilder induceParamType(ParamBuilder builder, Type type) {
     41
    4142                if (type instanceof ParameterizedType) {
    4243                        ParameterizedType p = (ParameterizedType) type;
     
    5253                        }
    5354                        if (!(containedType instanceof Class)) {
    54                                 return null;
     55                                return builder;
    5556                        }
    5657                        Class<?> containedClass = (Class<?>) containedType;
     
    6061                        if (fca == null) {
    6162                                log.error("the class is not annotated: " + containedClass);
    62                                 return null;
     63                                return builder;
    6364                        }
    6465                        b.append(getName(fca, containedClass));
     
    6768                        }
    6869
    69                         return b.toString();
     70                        builder.type(b.toString());
     71                        return builder;
    7072                }
    7173
     
    8789                        // }
    8890                        if (cl.equals(Integer.class) || cl.equals(int.class)) {
    89                                 return "d";
     91                                builder.type("d");
     92                                return builder;
    9093                        }
    9194                        if (cl.equals(String.class)) {
    92                                 return "s";
     95                                builder.type("s");
     96                                return builder;
    9397                        }
    9498                        if (cl.equals(Double.class) || cl.equals(double.class)) {
    95                                 return "f";
     99                                builder.type("f");
     100                                return builder;
    96101                        }
    97102                        if (cl.equals(Boolean.class) || cl.equals(boolean.class)) {
    98                                 return "d 0 1";
     103                                builder.type( "d 0 1");
     104                                return builder;
    99105                        }
    100106                        if (cl.equals(Object.class)) {
    101                                 return "x";
    102                         }
    103 
    104                         return "o " + ((Class<?>) type).getCanonicalName();
     107                                builder.type("x");
     108                                return builder;
     109                        }
     110
     111                        // builder.type("o " + (cl).getCanonicalName());
     112                        builder.type("o " + cl.getSimpleName());
     113                        builder.fillStorageType(cl);
     114                        return builder;
    105115                }
    106116
    107117                throw new ConstructionException().msg("failed to find framsticks for native type").arg("type", type);
     118        }
     119
     120
     121        public static ParamBuilder induceParamType(ParamBuilder builder, ParamCandidate candidate) {
     122                Method method = candidate.getCaller();
     123                if (method == null) {
     124                        return induceParamType(builder, candidate.getType());
     125                }
     126
     127                builder.resultType(induceParamType(Param.build(), method.getGenericReturnType()).finish(ValueParam.class));
     128
     129                List<ValueParam> arguments = new ArrayList<>();
     130                int number = 0;
     131                for (Type arg : method.getGenericParameterTypes()) {
     132                        arguments.add(induceParamType(Param.build(), arg).idAndName("arg" + (number++)).finish(ValueParam.class));
     133                }
     134                builder.argumentsType(arguments);
     135
     136                return builder;
    108137        }
    109138
     
    183212                name(getName(fca, javaClass));
    184213
    185                 Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(javaClass);
    186 
    187                 for (ParamCandidate pc : candidates.values()) {
    188                         String type = getParamTypeForNativeType(pc.getType());
    189                         if (type == null) {
    190                                 throw new FramsticksException().msg("failed to find type for param candidate").arg("candidate", pc);
    191                         }
    192                         param(Param.build().id(pc.getId()).name(pc.getName()).type(type).flags(pc.getFlags()));
     214                for (ParamCandidate pc : ParamCandidate.getAllCandidates(javaClass).getOrder()) {
     215                        ParamBuilder builder = Param.build().id(pc.getId()).name(pc.getName()).flags(pc.getFlags());
     216
     217                        induceParamType(builder, pc);
     218
     219                        for (ParamAnnotation pa : pc.getAnnotations()) {
     220                                if (!"".equals(pa.def())) {
     221                                        builder.def(pa.def());
     222                                }
     223                                if (!"".equals(pa.help())) {
     224                                        builder.help(pa.help());
     225                                }
     226                                if (!"".equals(pa.min())) {
     227                                        builder.min(pa.min());
     228                                }
     229                                if (!"".equals(pa.max())) {
     230                                        builder.max(pa.max());
     231                                }
     232                                builder.extra(pa.extra());
     233                                if (!"".equals(pa.stringType())) {
     234                                        builder.type(pa.stringType());
     235                                }
     236                                if (!pa.paramType().equals(Param.class)) {
     237                                        builder.type(pa.paramType());
     238                                }
     239                        }
     240                        param(builder);
    193241                }
    194242
     
    209257        protected final List<Param> params = new LinkedList<>();
    210258
    211         protected List<Group> groups = new ArrayList<Group>();
     259        protected List<GroupBuilder> groupBuilders = new ArrayList<GroupBuilder>();
    212260
    213261        @ParamAnnotation
     
    242290        }
    243291
    244         public FramsClassBuilder append(Param param) {
    245                 params.add(param);
    246                 return this;
    247         }
    248 
    249292        @AutoAppendAnnotation
    250293        public FramsClassBuilder param(ParamBuilder builder) {
    251                 return append(builder.finish());
     294                Param param = builder.finish();
     295
     296                Integer group = param.getGroup();
     297                if (group != null) {
     298                        Containers.getFromList(groupBuilders, group, "group", this).addParam(param);
     299                }
     300
     301                params.add(param);
     302                return this;
    252303        }
    253304
    254305        @AutoAppendAnnotation
    255306        public FramsClassBuilder group(GroupBuilder builder) {
    256                 return group(builder.finish());
    257         }
    258 
    259         @AutoAppendAnnotation
    260         public FramsClassBuilder group(Group group) {
    261                 groups.add(group);
     307                groupBuilders.add(builder);
    262308                return this;
    263309        }
     
    288334
    289335        public FramsClassBuilder group(String group) {
    290                 return group(new Group(group));
    291         }
    292 
    293         public ParamBuilder param(String id) {
    294                 return new ParamBuilder(this).id(id);
    295         }
     336                return group(new GroupBuilder().name(group));
     337        }
     338
    296339
    297340}
  • java/main/src/main/java/com/framsticks/params/Group.java

    r87 r90  
    11package com.framsticks.params;
    22
    3 import java.util.ArrayList;
    43import java.util.List;
     4
     5import javax.annotation.concurrent.Immutable;
    56
    67import com.framsticks.params.annotations.FramsClassAnnotation;
    78import com.framsticks.params.annotations.ParamAnnotation;
     9import com.framsticks.util.lang.Containers;
    810
    911/**
     
    1113 */
    1214@FramsClassAnnotation
     15@Immutable
    1316public class Group {
    1417
    1518        @ParamAnnotation
    16         protected String name;
     19        protected final String name;
    1720
    1821        /**
    1922         * Group members.
    2023         */
    21         List<Param> params = new ArrayList<Param>();
     24        protected final List<Param> params;
    2225
    23         public Group(String name) {
    24                 this.name = name;
    25         }
    26 
    27         /**
    28          * Adds new group member.
    29          *
    30          * @param p the new group member
    31          */
    32         void addProperty(Param p) {
    33                 params.add(p);
     26        public Group(GroupBuilder builder) {
     27                this.name = builder.getName();
     28                this.params = builder.getParams();
    3429        }
    3530
     
    4035         * @return the property
    4136         */
    42         Param getProperty(int i) {
    43                 if (i < 0 || i >= params.size())
    44                         return null;
    45                 return params.get(i);
     37        public Param getParam(int number) {
     38                return Containers.getFromList(params, number, "param", this);
    4639        }
    4740
    4841        @Override
    4942        public String toString() {
    50                 return name;
     43                return "group" + name;
    5144        }
    5245
     
    5952        }
    6053
     54        public int getCount() {
     55                return params.size();
     56        }
     57
    6158}
  • java/main/src/main/java/com/framsticks/params/GroupBuilder.java

    r88 r90  
    11package com.framsticks.params;
     2
     3import java.util.ArrayList;
     4import java.util.List;
    25
    36import com.framsticks.params.annotations.FramsClassAnnotation;
    47import com.framsticks.params.annotations.ParamAnnotation;
     8import com.framsticks.util.Builder;
    59
    610@FramsClassAnnotation(id = "group", name = "group")
    7 public class GroupBuilder {
     11public class GroupBuilder implements Builder<Group> {
    812
    913        @ParamAnnotation
    1014        protected String name;
     15
     16        protected final List<Param> params = new ArrayList<Param>();
    1117
    1218        public GroupBuilder() {
     
    1925        }
    2026
     27        /**
     28         * @return the name
     29         */
     30        public String getName() {
     31                return name;
     32        }
     33
     34        /**
     35         * @return the params
     36         */
     37        public List<Param> getParams() {
     38                return params;
     39        }
     40
    2141        public Group finish() {
    22                 return new Group(name);
     42                return new Group(this);
     43        }
     44
     45        public void addParam(Param param) {
     46                params.add(param);
    2347        }
    2448
  • java/main/src/main/java/com/framsticks/params/ListAccess.java

    r87 r90  
    44
    55import static com.framsticks.util.lang.Containers.filterInstanceof;
     6
     7import com.framsticks.params.types.ProcedureParam;
    68
    79/**
     
    1618        }
    1719
    18         @Override
    19         public Param getGroupMember(int gi, int n) {
    20                 return null;
    21         }
     20        // @Override
     21        // public Param getGroupMember(int gi, int n) {
     22        //      return null;
     23        // }
    2224
    2325        @Override
     
    8183        }
    8284
     85        @Override
     86        public Object call(String id, Object[] arguments) {
     87                throw new InvalidOperationException().msg("list access does not support calling methods").arg("id", id);
     88        }
     89
     90        @Override
     91        public Object call(ProcedureParam param, Object[] arguments) {
     92                throw new InvalidOperationException().msg("list access does not support calling methods").arg("param", param);
     93        }
     94
    8395};
  • java/main/src/main/java/com/framsticks/params/Param.java

    r88 r90  
    2323        protected final String id;
    2424
    25         //TODO
    26         /**
    27          * The parameter internal id. It's set by a user to use user's own getId in
    28          * code
    29          */
    30         protected final String internalId;
    31 
    3225        /** The parameter name. */
    3326        protected final String name;
     
    4841        public Param(ParamBuilder builder) {
    4942                id = builder.getId();
    50                 internalId = builder.getInternalId();
    5143                name = builder.getName();
    5244                help = builder.getHelp();
     
    5951        public String getId() {
    6052                return id;
    61         }
    62 
    63         public String getInternalId() {
    64                 return internalId;
    6553        }
    6654
     
    8775        public abstract String getFramsTypeName();
    8876
    89 
    90         public String getEffectiveId() {
    91                 return (internalId != null) ? internalId : id;
    92         }
    93 
    94 
     77        @ParamAnnotation
    9578        public Integer getExtra() {
    9679                return extra;
  • java/main/src/main/java/com/framsticks/params/ParamBuilder.java

    r88 r90  
    1111
    1212import java.lang.reflect.InvocationTargetException;
     13import java.util.ArrayList;
    1314import java.util.Arrays;
    1415import java.util.List;
     16import java.util.regex.Matcher;
     17import java.util.regex.Pattern;
     18
     19import javax.annotation.Nonnull;
    1520
    1621/**
     
    3742        private String id;
    3843
    39         /**
    40          * The parameter internal id. It's set by a user to use user's own id in
    41          * code
    42          */
    43         private String internalId;
    44 
    4544        /** The number of group, that parameter belongs to. */
    46         private Integer group = 0;
     45        private Integer group;
    4746
    4847        /** The flags stored as a bit sum. */
     
    7675        }
    7776
     77        protected ValueParam resultType;
     78
     79        protected List<ValueParam> argumentsType;
    7880
    7981        /**
     
    114116
    115117        /**
     118         * @return the resultType
     119         */
     120        public ValueParam getResultType() {
     121                return resultType;
     122        }
     123
     124
     125        /**
     126         * @param resultType the resultType to set
     127         */
     128        public ParamBuilder resultType(ValueParam resultType) {
     129                this.resultType = resultType;
     130                return this;
     131        }
     132
     133        /**
     134         * @return the argumentsType
     135         */
     136        public List<ValueParam> getArgumentsType() {
     137                return argumentsType;
     138        }
     139
     140
     141        /**
     142         * @param argumentsType the argumentsType to set
     143         */
     144        public ParamBuilder argumentsType(List<ValueParam> argumentsType) {
     145                this.argumentsType = argumentsType;
     146                return this;
     147        }
     148
     149        /**
    116150         * @return the enumValues
    117151         */
     
    121155
    122156        /**
    123          * @return the procedureSignature
    124          */
    125         public String getProcedureSignature() {
    126                 return procedureSignature;
    127         }
    128 
    129         /**
    130157         * @return the uid
    131158         */
    132159        public String getUid() {
    133160                return uid;
     161        }
     162
     163        public @Nonnull <T extends Param> T finish(Class<T> requested) {
     164                Param param = finish();
     165                if (!requested.isInstance(param)) {
     166                        throw new FramsticksException().msg("param is of wrong type").arg("requested", requested).arg("actual", param.getClass());
     167                }
     168                return requested.cast(param);
    134169        }
    135170
     
    141176         *             when Param getType is not defined
    142177         */
    143         public Param finish() {
     178        public @Nonnull Param finish() {
    144179                try {
    145180                        if (paramType == null) {
    146181                                throw new FramsticksException().msg("trying to finish incomplete param");
    147182                        }
    148 
    149183                        return paramType.getConstructor(ParamBuilder.class).newInstance(this);
    150184                } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | FramsticksException e) {
     
    165199        }
    166200
    167         // public <T extends Param> ParamBuilder type(T param) {
    168         //      return internalSetType(param.getClass(), param);
    169         // }
    170 
    171 
    172201        /**
    173202         * @return the id
     
    178207        }
    179208
    180         /**
    181          * @return the internalId
    182          */
    183         public String getInternalId() {
    184                 return internalId;
    185         }
    186 
    187         public ParamBuilder setInternalId(String internalId) {
    188                 this.internalId = internalId;
    189                 return this;
    190         }
    191 
    192209        @ParamAnnotation
    193210        public ParamBuilder group(Integer group) {
     
    208225        }
    209226
    210         protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third) {
     227        protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third, String fourth) {
    211228                if (second != null) {
    212229                        min = second;
     
    214231                if (third != null) {
    215232                        max = third;
     233                }
     234                if (fourth != null) {
     235                        def = fourth;
    216236                }
    217237        }
     
    223243                return type(EnumParam.class);
    224244        }
    225 
    226         protected String procedureSignature;
    227245
    228246        protected String uid;
     
    239257                String second = typeSplitted.length > 1 ? typeSplitted[1] : null;
    240258                String third = typeSplitted.length > 2 ? typeSplitted[2] : null;
     259                String fourth = typeSplitted.length > 3 ? typeSplitted[3] : null;
    241260
    242261                switch (first.charAt(0)) {
     
    247266                        }
    248267                        case 'p': {
    249                                 procedureSignature = type.substring(1);
    250268                                type(ProcedureParam.class);
     269                                signature(type.substring(1));
    251270                                break;
    252271                        }
     
    281300                                }
    282301                                if (DecimalParam.class.isAssignableFrom(this.paramType)) {
    283                                         parseMinMaxDefNumber(Integer.class, second, third);
     302                                        parseMinMaxDefNumber(Integer.class, second, third, fourth);
    284303                                }
    285304                                break;
     
    287306                        case 'f': {
    288307                                type(FloatParam.class);
    289                                 parseMinMaxDefNumber(Double.class, second, third);
     308                                parseMinMaxDefNumber(Double.class, second, third, fourth);
    290309                                break;
    291310                        }
     
    472491        }
    473492
    474 
    475493        public Class<?> getStorageType() {
    476494                return storageType;
    477495        }
     496
     497        public ParamBuilder forAccess(AccessInterface access) {
     498                return name(access.getId()).type("o " + access.getId());
     499        }
     500
     501        protected static ValueParam parseProcedureTypePart(String type, String name) {
     502                return Param.build().type(type).name(name).id(name).finish(ValueParam.class);
     503        }
     504
     505        private static Pattern addressPattern = Pattern.compile("^([^\\(]+)?\\(([^\\)]*)\\)$");
     506
     507        public ParamBuilder signature(String signature) {
     508                argumentsType = new ArrayList<>();
     509
     510                if (!Strings.notEmpty(signature)) {
     511                        resultType = null;
     512                        return this;
     513                }
     514                Matcher matcher = addressPattern.matcher(signature);
     515                if (!matcher.matches()) {
     516                        throw new FramsticksException().msg("invalid signature");
     517                }
     518                String result = Strings.collapse(matcher.group(1));
     519                resultType = (result != null) ? parseProcedureTypePart(result, null) : null;
     520                String arguments = matcher.group(2);
     521                if (!Strings.notEmpty(arguments)) {
     522                        return this;
     523                }
     524                int number = 0;
     525                for (String a : arguments.split(",")) {
     526                        int space = a.indexOf(' ');
     527                        String type;
     528                        String name;
     529                        if (space == -1) {
     530                                type = a;
     531                                name = "arg" + number;
     532                        } else {
     533                                type = a.substring(0, space);
     534                                name = a.substring(space + 1);
     535                        }
     536                        argumentsType.add(parseProcedureTypePart(type, name));
     537                        ++number;
     538                }
     539                return this;
     540        }
     541
     542
     543        public ParamBuilder idAndName(String name) {
     544                id(name);
     545                name(name);
     546                return this;
     547        }
    478548}
    479549
  • java/main/src/main/java/com/framsticks/params/ParamCandidate.java

    r88 r90  
    1010import java.lang.reflect.ParameterizedType;
    1111import java.lang.reflect.Type;
     12import java.util.Arrays;
    1213import java.util.Collection;
     14import java.util.Collections;
     15import java.util.Comparator;
    1316import java.util.HashMap;
     17import java.util.LinkedList;
     18import java.util.List;
    1419import java.util.Map;
    1520
     21import com.framsticks.params.annotations.FramsClassAnnotation;
    1622import com.framsticks.params.annotations.ParamAnnotation;
     23import com.framsticks.params.types.ProcedureParam;
    1724
    1825public class ParamCandidate {
     
    6572        protected final OneTime<Method> setter = new OneTime<>("setter");
    6673        protected final OneTime<Method> getter = new OneTime<>("getter");
     74        protected final OneTime<Method> caller = new OneTime<>("caller");
     75
     76        protected final List<ParamAnnotation> annotations = new LinkedList<>();
    6777
    6878        /**
     
    124134        }
    125135
     136        /**
     137         * @return the getter
     138         */
     139        public Method getCaller() {
     140                return caller.get();
     141        }
     142
     143        /**
     144         * @return the annotations
     145         */
     146        public List<ParamAnnotation> getAnnotations() {
     147                return Collections.unmodifiableList(annotations);
     148        }
     149
    126150        void validate() throws ConstructionException {
    127151                try {
     152                        if (caller.has()) {
     153                                if (!isPublic(caller)) {
     154                                        throw new ConstructionException().msg("method is not public");
     155                                }
     156                                if (getter.has() || setter.has()) {
     157                                        throw new ConstructionException().msg("getter or setter coexist with caller");
     158                                }
     159                                return;
     160                        }
    128161                        if (isPublic(field)) {
    129162                                if (getter.has()) {
     
    147180
    148181        boolean isFinal() {
     182                if (caller.has()) {
     183                        return false;
     184                }
    149185                if (Collection.class.isAssignableFrom(getRawType())) {
    150186                        return false;
     
    160196
    161197        boolean isReadOnly() {
     198                if (caller.has()) {
     199                        return false;
     200                }
    162201                if (Collection.class.isAssignableFrom(getRawType())) {
    163202                        return false;
     
    172211        }
    173212
    174         void add(Member member, String name) {
     213        void add(ParamAnnotation paramAnnotation, Member member, String name) {
    175214                this.name.set(name);
     215                annotations.add(paramAnnotation);
    176216                if (member instanceof Field) {
    177                         this.field.set((Field) member);
     217                        field.set((Field) member);
    178218                        setType(field.get().getGenericType());
    179219                        return;
     
    181221                if (member instanceof Method) {
    182222                        Method m = (Method) member;
     223                        if (!paramAnnotation.paramType().equals(Param.class)) {
     224                                if (paramAnnotation.paramType().equals(ProcedureParam.class)) {
     225                                        caller.set(m);
     226                                        return;
     227                                }
     228                                throw new ConstructionException().msg("explicit set of paramType different than ProcedureParam is not yet supported").arg("name", name).arg("method", m).arg("in", this);
     229                        }
    183230                        Type[] ps = m.getGenericParameterTypes();
    184231                        if (ps.length == 0) {
     
    222269        }
    223270
    224         public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Map<String, ParamCandidate> params, M[] members) {
     271        public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Set set, M[] members) {
    225272                for (M m : members) {
    226273                        ParamAnnotation pa = m.getAnnotation(ParamAnnotation.class);
     
    228275                                continue;
    229276                        }
    230                         // if (!isPublic(m)) {
    231                         //      throw new ConstructionException().msg("field is not public").arg("field", m);
    232                         // }
    233277                        String id = FramsClassBuilder.getId(pa, m);
    234278                        ParamCandidate pc = null;
    235                         if (params.containsKey(id)) {
    236                                 pc = params.get(id);
     279                        if (set.getCandidates().containsKey(id)) {
     280                                pc = set.getCandidates().get(id);
    237281                        } else {
    238282                                pc = new ParamCandidate(id);
    239                                 params.put(id, pc);
    240                         }
    241                         pc.add(m, FramsClassBuilder.getName(pa, m));
    242 
    243                 }
    244         }
    245 
    246         public static Map<String, ParamCandidate> getAllCandidates(Class<?> javaClass) throws ConstructionException {
    247                 Map<String, ParamCandidate> candidates = new HashMap<>();
    248 
     283                                set.getCandidates().put(id, pc);
     284                                set.getOrder().add(pc);
     285                        }
     286                        pc.add(pa, m, FramsClassBuilder.getName(pa, m));
     287                }
     288        }
     289
     290        public static class Set {
     291                protected final Map<String, ParamCandidate> candidates;
     292                protected final List<ParamCandidate> order;
     293
     294                /**
     295                 * @param candidates
     296                 * @param order
     297                 */
     298                public Set(Map<String, ParamCandidate> candidates, List<ParamCandidate> order) {
     299                        this.candidates = candidates;
     300                        this.order = order;
     301                }
     302
     303                /**
     304                 * @return the candidates
     305                 */
     306                public Map<String, ParamCandidate> getCandidates() {
     307                        return candidates;
     308                }
     309
     310                /**
     311                 * @return the order
     312                 */
     313                public List<ParamCandidate> getOrder() {
     314                        return order;
     315                }
     316        }
     317
     318        public static Set getAllCandidates(Class<?> javaClass) throws ConstructionException {
     319
     320                List<Class<?>> javaClasses = new LinkedList<>();
    249321                while (javaClass != null) {
    250                         filterParamsCandidates(candidates, javaClass.getDeclaredFields());
    251                         filterParamsCandidates(candidates, javaClass.getDeclaredMethods());
    252 
     322                        javaClasses.add(0, javaClass);
    253323                        javaClass = javaClass.getSuperclass();
    254324                }
    255325
    256                 for (ParamCandidate pc : candidates.values()) {
     326                Set resultSet = new Set(new HashMap<String, ParamCandidate>(), new LinkedList<ParamCandidate>());
     327
     328                for (Class<?> j : javaClasses) {
     329                        Set set = new Set(resultSet.getCandidates(), new LinkedList<ParamCandidate>());
     330                        filterParamsCandidates(set, j.getDeclaredFields());
     331                        filterParamsCandidates(set, j.getDeclaredMethods());
     332
     333                        FramsClassAnnotation fa = j.getAnnotation(FramsClassAnnotation.class);
     334                        if (fa != null) {
     335                                final List<String> order = Arrays.asList(fa.order());
     336                                Collections.sort(set.getOrder(), new Comparator<ParamCandidate>() {
     337                                        @Override
     338                                        public int compare(ParamCandidate pc0, ParamCandidate pc1) {
     339                                                int u0 = order.indexOf(pc0.getId());
     340                                                int u1 = order.indexOf(pc1.getId());
     341                                                if (u0 == -1 || u1 == -1) {
     342                                                        return 0;
     343                                                }
     344                                                return u0 - u1;
     345                                        }
     346                                });
     347                        }
     348                        resultSet.getOrder().addAll(0, set.getOrder());
     349                }
     350
     351                for (ParamCandidate pc : resultSet.getOrder()) {
    257352                        pc.validate();
    258353                }
    259354
    260                 return candidates;
     355                return resultSet;
    261356        }
    262357
    263358        public static Class<?> getRawClass(final Type type) {
     359                if (type == null) {
     360                        throw new IllegalArgumentException();
     361                }
    264362                if (Class.class.isInstance(type)) {
    265363                        return Class.class.cast(type);
  • java/main/src/main/java/com/framsticks/params/PrimitiveParam.java

    r88 r90  
    9696                return tryCastAndReturn(def, type);
    9797        }
     98
    9899}
  • java/main/src/main/java/com/framsticks/params/PropertiesAccess.java

    r87 r90  
    33import java.util.HashMap;
    44import java.util.Map;
     5
     6import com.framsticks.params.types.ProcedureParam;
    57
    68
     
    9395        }
    9496
     97        @Override
     98        public Object call(String id, Object[] arguments) {
     99                throw new InvalidOperationException().msg("list access does not support calling methods").arg("id", id);
     100        }
     101
     102        @Override
     103        public Object call(ProcedureParam param, Object[] arguments) {
     104                throw new InvalidOperationException().msg("list access does not support calling methods").arg("param", param);
     105        }
     106
    95107}
  • java/main/src/main/java/com/framsticks/params/ReflectionAccess.java

    r88 r90  
    44import java.lang.reflect.InvocationTargetException;
    55import java.lang.reflect.Method;
     6import java.util.ArrayList;
    67import java.util.Collections;
     8import java.util.Comparator;
    79import java.util.HashMap;
    8 import java.util.LinkedList;
    910import java.util.List;
    1011import java.util.Map;
     
    1516
    1617import com.framsticks.params.annotations.AutoAppendAnnotation;
     18import com.framsticks.params.types.ProcedureParam;
    1719import com.framsticks.util.FramsticksException;
    1820import com.framsticks.util.lang.Pair;
     
    3133        private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
    3234
    33         protected final Class<?> reflectedClass;
     35        protected final Class<?> javaClass;
    3436        protected final Backend backend;
    3537
     
    4143                protected static final Map<Pair<Class<?>, FramsClass>, Backend> synchronizedCache = Collections.synchronizedMap(new HashMap<Pair<Class<?>, FramsClass>, Backend>());
    4244
    43                 public static class ReflectedValueParam {
    44                         public ReflectedSetter setter;
    45                         public ReflectedGetter getter;
     45
     46                public interface ReflectedGetter {
     47                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    4648                }
    4749
     
    5052                }
    5153
    52                 public interface ReflectedGetter {
    53                         public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    54                 }
    55 
    56                 protected final Map<ValueParam, ReflectedValueParam> params;
    57                 protected final List<Method> autoAppendMethods;
     54                public interface ReflectedCaller {
     55                        public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     56                }
     57
     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<>();
     61                protected final List<Method> autoAppendMethods = new ArrayList<>();
    5862
    5963                /**
    6064                 * @param params
    6165                 */
    62                 public Backend(Map<ValueParam, ReflectedValueParam> params, List<Method> autoAppendMethods) {
    63                         // this.params = Collections.unmodifiableMap(params);
    64                         this.params = params;
    65                         this.autoAppendMethods = autoAppendMethods;
     66                public Backend() {
    6667                }
    6768
     
    7576
    7677                        log.debug("constructing backend for " + id);
    77                         final Map<ValueParam, ReflectedValueParam> params = new HashMap<>();
    78 
    79                         Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
    80 
    81                         try {
     78                        backend = new Backend();
     79
     80                        Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass).getCandidates();
     81
     82                        try {
     83                                for (final ProcedureParam pp : filterInstanceof(framsClass.getParamEntries(), ProcedureParam.class)) {
     84                                        if (!candidates.containsKey(pp.getId())) {
     85                                                log.trace("java class does implement method " + pp);
     86                                                continue;
     87                                        }
     88                                        ParamCandidate pc = candidates.get(pp.getId());
     89                                        final Method method = pc.getCaller();
     90
     91                                        backend.callers.put(pp, new ReflectedCaller() {
     92
     93                                                @Override
     94                                                public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     95                                                        return method.invoke(object, arguments);
     96                                                }
     97                                        });
     98
     99                                }
     100
    82101                                for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
    83102                                        if (!candidates.containsKey(vp.getId())) {
     
    92111                                        }
    93112
    94                                         ReflectedValueParam rvp = new ReflectedValueParam();
    95                                         params.put(vp, rvp);
    96113                                        final boolean primitive = pc.isPrimitive();
    97114                                        if (pc.getField() != null) {
    98115                                                final Field f = pc.getField();
    99                                                 rvp.getter = new ReflectedGetter() {
     116                                                backend.getters.put(vp, new ReflectedGetter() {
    100117                                                        @Override
    101118                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
    102119                                                                return type.cast(f.get(object));
    103120                                                        }
    104                                                 };
     121                                                });
    105122                                                if (!pc.isFinal()) {
    106                                                         rvp.setter = new ReflectedSetter() {
     123                                                        backend.setters.put(vp, new ReflectedSetter() {
    107124                                                                @Override
    108125                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
     
    112129                                                                        f.set(object, value);
    113130                                                                }
    114                                                         };
     131                                                        });
    115132                                                }
    116133                                        } else {
    117134                                                final Method g = pc.getGetter();
    118135
    119                                                 rvp.getter = new ReflectedGetter() {
     136                                                backend.getters.put(vp, new ReflectedGetter() {
    120137                                                        @Override
    121138                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    122139                                                                return type.cast(g.invoke(object));
    123140                                                        }
    124                                                 };
     141                                                });
    125142
    126143                                                if (!pc.isFinal()) {
    127144                                                        final Method s = pc.getSetter();
    128                                                         rvp.setter = new ReflectedSetter() {
     145                                                        backend.setters.put(vp, new ReflectedSetter() {
    129146                                                                @Override
    130147                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     
    134151                                                                        s.invoke(object, value);
    135152                                                                }
    136                                                         };
     153                                                        });
    137154                                                }
    138155                                        }
     
    141158                                throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
    142159                        }
    143 
    144                         List<Method> autoAppendMethods = new LinkedList<>();
    145160
    146161                        Class<?> javaClass = reflectedClass;
     
    156171                                                throw new ConstructionException().msg("invalid number of arguments in AutoAppend marked method").arg("method", m).arg("arguments", args.length);
    157172                                        }
    158                                         autoAppendMethods.add(m);
     173                                        backend.autoAppendMethods.add(m);
    159174                                }
    160175
     
    162177                        }
    163178
    164                         backend = new Backend(params, autoAppendMethods);
     179                        Collections.sort(backend.autoAppendMethods, new Comparator<Method>() {
     180
     181                                @Override
     182                                public int compare(Method m0, Method m1) {
     183                                        Class<?> arg0 = m0.getParameterTypes()[0];
     184                                        Class<?> arg1 = m1.getParameterTypes()[0];
     185                                        if (arg0.isAssignableFrom(arg1)) {
     186                                                return 1;
     187                                        }
     188                                        if (arg1.isAssignableFrom(arg0)) {
     189                                                return -1;
     190                                        }
     191                                        return 0;
     192                                }
     193                        });
     194
    165195                        synchronizedCache.put(id, backend);
    166196                        return backend;
     
    194224        public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
    195225                super(framsClass);
    196                 this.reflectedClass = reflectedClass;
     226                this.javaClass = reflectedClass;
    197227                this.backend = Backend.getOrCreateFor(reflectedClass, framsClass);
    198                 // log.info("created ReflectionAccess " + this);
    199         }
    200 
    201         // private static String accessorName(boolean get, String id) {
    202         //      return (get ? "get" : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
    203         // }
     228        }
     229
    204230
    205231        @Override
     
    211237                                }
    212238
    213                                 return backend.params.get(param).getter.get(object, type);
     239                                return backend.getters.get(param).get(object, type);
    214240                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    215241                                throw new FramsticksException().msg("failed to get").cause(e);
     
    231257                                        throw new FramsticksException().msg("no object set");
    232258                                }
    233                                 Backend.ReflectedSetter s = backend.params.get(param).setter;
     259                                Backend.ReflectedSetter s = backend.setters.get(param);
    234260                                if (s == null) {
    235                                         throw new FramsticksException().msg("trying to set final");
     261                                        throw new FramsticksException().msg("trying to set unsettable");
    236262                                }
    237263                                s.set(object, value);
     
    241267                } catch (FramsticksException e) {
    242268                        throw e.arg("param", param).arg("value", value).arg("access", this);
     269                }
     270        }
     271
     272        @Override
     273        public Object call(String id, Object[] arguments) {
     274                return call(framsClass.getParamEntry(id, ProcedureParam.class), arguments);
     275        }
     276
     277        @Override
     278        public Object call(ProcedureParam param, Object[] arguments) {
     279                try {
     280                        try {
     281                                if (object == null) {
     282                                        throw new FramsticksException().msg("no object set");
     283                                }
     284                                Backend.ReflectedCaller c = backend.callers.get(param);
     285                                if (c == null) {
     286                                        throw new FramsticksException().msg("method is not bound");
     287                                }
     288                                return c.call(object, arguments);
     289                        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
     290                                throw new FramsticksException().msg("failed to call").cause(e);
     291                        }
     292                } catch (FramsticksException e) {
     293                        throw e.arg("param", param).arg("access", this);
    243294                }
    244295        }
     
    273324        @Override
    274325        public ReflectionAccess select(Object object) {
    275                 assert object == null || reflectedClass.isInstance(object);
     326                assert object == null || javaClass.isInstance(object);
    276327                this.object = object;
    277328                return this;
     
    302353        @Override
    303354        public ReflectionAccess cloneAccess() throws ConstructionException {
    304                 return new ReflectionAccess(reflectedClass, framsClass);
     355                return new ReflectionAccess(javaClass, framsClass);
    305356        }
    306357
     
    308359        public Object createAccessee() {
    309360                try {
    310                         return reflectedClass.newInstance();
     361                        return javaClass.newInstance();
    311362                } catch (InstantiationException | IllegalAccessException e) {
    312363                        e.printStackTrace();
    313364                }
    314                 log.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
     365                log.fatal("failed to create reflected object of class " + javaClass.getCanonicalName() + " for frams type " + framsClass.getId());
    315366                return null;
    316367        }
     
    332383                        if (m.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
    333384                                try {
     385                                        log.trace("auto appending with value " + value + " with method " + m);
    334386                                        m.invoke(object, value);
    335387                                        return true;
     
    341393                return false;
    342394        }
     395
    343396}
    344397
  • java/main/src/main/java/com/framsticks/params/Registry.java

    r88 r90  
    44
    55import com.framsticks.params.annotations.FramsClassAnnotation;
     6import com.framsticks.params.annotations.ParamAnnotation;
    67import com.framsticks.util.DoubleMap;
    78import com.framsticks.util.FramsticksException;
    89
     10import java.util.HashMap;
     11import java.util.Map;
    912import java.util.Set;
     13
     14import javax.annotation.Nonnull;
    1015
    1116/**
    1217 * Author: Piotr Śniegowski
    1318 */
     19@FramsClassAnnotation
    1420public class Registry {
    1521        private static final Logger log = Logger.getLogger(Registry.class.getName());
    1622
    17         // protected void internalRegisterClass(FramsClass framsClass, @Nullable Class<?> javaClass) {
    18         //      assert framsClass.getName() != null;
    19         //      assert framsClass.getId() != null;
    20         //      infoCacheByName.put(framsClass.getName(), framsClass);
    21         //      infoCacheById.put(framsClass.getId(), framsClass);
    22 
    23         //      if (javaClass != null) {
    24         //              reflectedClasses.put(framsClass, javaClass);
    25         //              infoCacheByJavaName.put(javaClass.getCanonicalName(), framsClass);
    26         //      }
    27         // }
    2823        protected final DoubleMap<String, Class<?>> javaClasses = new DoubleMap<>();
    2924        protected final DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
     25        protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new HashMap<>();
    3026
    31         public void registerReflectedClass(String name, String id, Class<?> reflectedClass) {
    32                 javaClasses.put(id, name, reflectedClass);
     27        /**
     28         *
     29         */
     30        public Registry() {
     31                // registerAndBuild(Registry.class);
     32                // registerAndBuild(FramsClass.class);
     33                // registerAndBuild(Param.class);
    3334        }
    3435
    35         public Registry registerAndBuild(Class<?> reflectedClass) {
    36                 register(reflectedClass);
    37                 putInfoIntoCache(FramsClass.build().forClass(reflectedClass));
     36        public void registerReflectedClass(String name, String id, Class<?> javaClass) {
     37                javaClasses.put(id, name, javaClass);
     38        }
     39
     40        public void associate(Class<?> javaClass, FramsClass framsClass) {
     41                javaToFramsAssociation.put(javaClass, framsClass);
     42        }
     43
     44        public Registry registerAndBuild(Class<?> javaClass) {
     45                register(javaClass);
     46                associate(javaClass, putFramsClass(FramsClass.build().forClass(javaClass)));
    3847                return this;
    3948        }
    4049
    41         public Registry register(Class<?> reflectedClass) {
    42                 FramsClassAnnotation a = reflectedClass.getAnnotation(FramsClassAnnotation.class);
     50        public Registry register(Class<?> javaClass) {
     51                FramsClassAnnotation a = javaClass.getAnnotation(FramsClassAnnotation.class);
    4352                if (a == null) {
    44                         throw new FramsticksException().msg("class is not annotated").arg("class", reflectedClass);
     53                        throw new FramsticksException().msg("class is not annotated").arg("class", javaClass);
    4554                }
    4655
    47                 registerReflectedClass(FramsClassBuilder.getName(a, reflectedClass), FramsClassBuilder.getId(a, reflectedClass), reflectedClass);
     56                registerReflectedClass(FramsClassBuilder.getName(a, javaClass), FramsClassBuilder.getId(a, javaClass), javaClass);
    4857                return this;
    4958        }
    5059
    51         public AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
     60        public @Nonnull ReflectionAccess createAccess(Class<?> javaClass) throws ConstructionException {
     61                try {
     62                        if (!javaClasses.containsValue(javaClass)) {
     63                                throw new FramsticksException().msg("java class is not registered");
     64                        }
     65                        if (!javaToFramsAssociation.containsKey(javaClass)) {
     66                                throw new FramsticksException().msg("java class is not associated with any frams class");
     67                        }
     68                        return new ReflectionAccess(javaClass, javaToFramsAssociation.get(javaClass));
     69                }
     70                catch (FramsticksException e) {
     71                        throw new FramsticksException().msg("failed to create access for java class").arg("class", javaClass).cause(e);
     72                }
     73        }
     74
     75        public @Nonnull AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
    5276                // assert framsClasses.containsValue(framsClass);
    5377                if (javaClasses.containsKey(name)) {
     
    5781        }
    5882
    59         public void putInfoIntoCache(FramsClass framsClass) {
     83        public FramsClass putFramsClass(FramsClass framsClass) {
    6084                log.debug("caching info for " + framsClass);
    6185                framsClasses.put(framsClass.getId(), framsClass.getName(), framsClass);
     86                return framsClass;
    6287        }
    6388
    64         public FramsClass getInfoFromCache(String identifier) {
    65                 if (identifier == null) {
    66                         return null;
    67                 }
     89        public FramsClass getFramsClass(@Nonnull String identifier) {
    6890                return framsClasses.get(identifier);
    6991        }
    7092
    71         public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
    72                 if (access == null) {
    73                         return null;
    74                 }
     93        public static @Nonnull AccessInterface wrapAccessWithListIfNeeded(@Nonnull CompositeParam param, @Nonnull AccessInterface access) {
    7594                return param.prepareAccessInterface(access);
    7695        }
    7796
    78         public AccessInterface prepareAccess(CompositeParam param) throws ConstructionException {
     97        public @Nonnull AccessInterface prepareAccess(CompositeParam param) throws ConstructionException {
    7998                return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
    8099        }
    81100
    82         public AccessInterface createAccess(String name) throws ConstructionException {
    83                 if (name == null) {
    84                         return null;
     101        public @Nonnull AccessInterface createAccess(@Nonnull String name) throws ConstructionException {
     102                try {
     103                        FramsClass framsClass = getFramsClass(name);
     104                        if (framsClass == null) {
     105                                throw new ConstructionException().msg("framsclass is missing");
     106                        }
     107
     108                        return createAccess(name, framsClass);
    85109                }
    86                 FramsClass framsClass = getInfoFromCache(name);
    87                 if (framsClass == null) {
    88                         return null;
     110                catch (FramsticksException e) {
     111                        throw new FramsticksException().msg("failed to create access for name").arg("name", name).cause(e);
    89112                }
    90 
    91                 return createAccess(name, framsClass);
    92113        }
    93114
     
    96117        }
    97118
    98         public Set<FramsClass> getInfoCache() {
     119        public Set<FramsClass> getFramsClasses() {
    99120                return framsClasses.getValues();
    100121        }
    101122
     123        @ParamAnnotation
     124        public Map<String, FramsClass> getFramsClassesById() {
     125                return framsClasses.getValuesById();
     126        }
     127
     128        public void takeAllFrom(Registry source) {
     129                for (Class<?> javaClass : source.getReflectedClasses()) {
     130                        register(javaClass);
     131                }
     132                for (FramsClass framsClass : source.getFramsClasses()) {
     133                        putFramsClass(framsClass);
     134                }
     135
     136        }
     137
    102138}
  • java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java

    r87 r90  
    7878        }
    7979
    80         @Override
    81         public Param getGroupMember(int gi, int n) {
    82                 return framsClass.getGroupMember(gi, n);
    83         }
     80        // @Override
     81        // public Param getGroupMember(int gi, int n) {
     82        //      return framsClass.getGroupMember(gi, n);
     83        // }
    8484
    8585        @Override
  • java/main/src/main/java/com/framsticks/params/UniqueListAccess.java

    r87 r90  
    4545                }
    4646                //TODO list access here
    47                 return Param.build().id(id).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
     47                return Param.build().id(id).forAccess(elementAccess).finish();
    4848        }
    4949
  • java/main/src/main/java/com/framsticks/params/Util.java

    r86 r90  
    33import java.util.ArrayList;
    44import java.util.List;
     5
     6import com.framsticks.util.FramsticksException;
    57
    68
     
    2224        }
    2325
    24         public static List<Object> stripAccessInterface(List<AccessInterface> accesses) {
    25                 List<Object> result = new ArrayList<Object>();
     26        public static <T> List<T> stripAccessInterface(List<AccessInterface> accesses, Class<T> type) {
     27                List<T> result = new ArrayList<T>();
    2628                for (AccessInterface a : accesses) {
    27                         result.add(a.getSelected());
     29                        Object object = a.getSelected();
     30                        if (!type.isInstance(object)) {
     31                                throw new FramsticksException().msg("extracted object is of invalid type").arg("object", object).arg("desired", type).arg("actual", object.getClass()).arg("framsclass", a.getFramsClass());
     32                        }
     33                        result.add(type.cast(object));
    2834                }
    2935                return result;
  • java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java

    r86 r90  
    1111        String name() default "";
    1212        String id() default "";
     13
     14        String[] order() default {};
    1315}
  • java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java

    r86 r90  
    66import java.lang.annotation.Target;
    77
     8import com.framsticks.params.Param;
     9
    810@Retention(RetentionPolicy.RUNTIME)
    911@Target({ElementType.FIELD, ElementType.METHOD})
     
    1113        String name() default "";
    1214        String id() default "";
     15
     16        Class<? extends Param> paramType() default Param.class;
     17        String stringType() default "";
     18
     19        String def() default "";
     20        String min() default "";
     21        String max() default "";
     22
     23        String help() default "";
     24        // int flags() default 0;
     25        int extra() default 0;
     26        // String group() default "";
    1327}
    1428
  • java/main/src/main/java/com/framsticks/params/types/ObjectParam.java

    r87 r90  
    1515public class ObjectParam extends CompositeParam {
    1616
     17        protected final Class<?> storageType;
     18
    1719        public ObjectParam(ParamBuilder builder) {
    18                 super(builder);
     20                super(builder.fillStorageType(Object.class));
     21                storageType = builder.getStorageType();
    1922        }
    2023
     
    2629        @Override
    2730        public Class<?> getStorageType() {
    28                 return Object.class;
     31                return storageType;
    2932        }
    3033
    3134        @Override
    3235        public ReassignResult<Object> reassign(Object newValue, Object oldValue) throws CastFailure {
     36                if (newValue != null && !storageType.isInstance(newValue)) {
     37                        throw new CastFailure();
     38                }
    3339                return ReassignResult.create(newValue);
    3440        }
  • java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java

    r87 r90  
    33import com.framsticks.params.Param;
    44import com.framsticks.params.ParamBuilder;
    5 import com.framsticks.util.FramsticksException;
    6 import com.framsticks.util.lang.Strings;
     5import com.framsticks.params.ValueParam;
    76
    8 import java.util.ArrayList;
    97import java.util.List;
    10 import java.util.regex.Matcher;
    11 import java.util.regex.Pattern;
    128
    139import javax.annotation.concurrent.Immutable;
     
    1814@Immutable
    1915public class ProcedureParam extends Param {
    20         private final Param resultType;
    21         private final List<Param> argumentsType = new ArrayList<Param>();
    22 
    23         private static Pattern addressPattern = Pattern.compile("^([^\\(]+)?\\(([^\\)]*)\\)$");
     16        private final ValueParam resultType;
     17        private final List<ValueParam> argumentsType;
    2418
    2519        /**
     
    2822        public ProcedureParam(ParamBuilder builder) {
    2923                super(builder);
    30                 String signature = builder.getProcedureSignature();
    31                 if (Strings.notEmpty(signature)) {
    32                         Matcher matcher = addressPattern.matcher(signature);
    33                         if (!matcher.matches()) {
    34                                 throw new FramsticksException().msg("invalid signature");
    35                         }
    36                         String result = Strings.collapse(matcher.group(1));
    37                         resultType = (result != null) ? parseType(result, null) : null;
    38                         String arguments = matcher.group(2);
    39                         if (!Strings.notEmpty(arguments)) {
    40                                 return;
    41                         }
    42                         for (String a : arguments.split(",")) {
    43                                 int space = a.indexOf(' ');
    44                                 String type;
    45                                 String name;
    46                                 if (space == -1) {
    47                                         type = a;
    48                                         name = null;
    49                                 } else {
    50                                         type = a.substring(0, space);
    51                                         name = a.substring(space + 1);
    52                                 }
    53                                 argumentsType.add(parseType(type, name));
    54                         }
    55                 } else {
    56                         resultType = null;
    57                 }
    58         }
    59 
    60         protected static Param parseType(String type, String name) {
    61                 return Param.build().type(type).name(name).finish();
     24                resultType = builder.getResultType();
     25                argumentsType = builder.getArgumentsType();
     26                assert argumentsType != null;
    6227        }
    6328
     
    6732        }
    6833
    69         public Param getResultType() {
     34        public ValueParam getResultType() {
    7035                return resultType;
    7136        }
    7237
    73         public List<Param> getArgumentsType() {
     38        public List<ValueParam> getArgumentsType() {
    7439                return argumentsType;
    7540        }
  • java/main/src/main/java/com/framsticks/parsers/F0Parser.java

    r88 r90  
    1818import com.framsticks.params.Param;
    1919import com.framsticks.params.PrimitiveParam;
     20import com.framsticks.util.FramsticksException;
    2021import com.framsticks.util.lang.Containers;
    2122import com.framsticks.util.lang.Pair;
     
    8283         *             the parse exception
    8384         */
    84         public List<AccessInterface> parse() throws IOException,
    85                         ParseException {
     85        public List<AccessInterface> parse() {
    8686
    8787                try (InputStreamReader reader = new InputStreamReader(is, "UTF-8")) {
     
    114114                                result.add(0, processLine("m:"));
    115115                        }
     116                } catch (IOException e) {
     117                        throw new FramsticksException().msg("failed to parse f0").arg("parser", this).arg("schema", schema).cause(e);
    116118                }
    117119
  • java/main/src/main/java/com/framsticks/parsers/F0Writer.java

    r88 r90  
    4444                for (ValueParam param : filterInstanceof(access.getParams(), ValueParam.class)) {
    4545                        if (param instanceof CompositeParam) {
    46                                 AccessInterface a = schema.getRegistry().prepareAccess((CompositeParam)param);
     46                                AccessInterface a = schema.getRegistry().prepareAccess((CompositeParam) param);
    4747                                a.select(access.get((ValueParam) param, Object.class));
    4848                                write(a);
     
    7878                sink.print(line).breakLine();
    7979        }
     80
    8081        public void write() {
    8182                AccessInterface access = schema.getRegistry().createAccess("m");
  • java/main/src/main/java/com/framsticks/parsers/XmlLoader.java

    r88 r90  
    22
    33import java.io.InputStream;
     4import java.util.LinkedList;
     5import java.util.List;
    46
    57import javax.xml.parsers.DocumentBuilder;
     
    1517import com.framsticks.params.AccessInterface;
    1618import com.framsticks.params.Registry;
     19import com.framsticks.util.AutoBuilder;
    1720import com.framsticks.util.FramsticksException;
    1821
     
    8689                        }
    8790
    88                         if (!access.tryAutoAppend(childObject)) {
    89                                 throw new FramsticksException().msg("failed to auto append").arg("child", childObject).arg("parent", object);
     91                        List<Object> childrenObjects = new LinkedList<>();
     92
     93                        if (childObject instanceof AutoBuilder) {
     94                                childrenObjects.addAll(((AutoBuilder) childObject).autoFinish());
     95                        } else {
     96                                childrenObjects.add(childObject);
     97                        }
     98
     99                        for (Object child : childrenObjects) {
     100                                if (!access.tryAutoAppend(child)) {
     101                                        throw new FramsticksException().msg("failed to auto append").arg("child", child).arg("parent", object);
     102                                }
    90103                        }
    91104                }
     
    112125        }
    113126
    114         public <T> T load(InputStream stream, Class<T> type) {
     127        public <T> T load(Class<T> type, InputStream stream) {
    115128                registry.registerAndBuild(type);
    116129
  • java/main/src/main/java/com/framsticks/portals/Portal.java

    r88 r90  
    5858                                }
    5959                                final String path = "/simulator/genepools/groups/0/genotypes";
    60                                 instance.invokeLater(new RunAt<Instance>() {
     60                                instance.dispatch(new RunAt<Instance>() {
    6161                                        @Override
    6262                                        public void run() {
  • java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java

    r85 r90  
    5252                                if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
    5353                                        ++dispatched;
    54                                         instance.invokeLater(new RunAt<Instance>() {
     54                                        instance.dispatch(new RunAt<Instance>() {
    5555                                                @Override
    5656                                                public void run() {
  • java/main/src/main/java/com/framsticks/remote/RemoteInstance.java

    r88 r90  
    1212import com.framsticks.params.annotations.ParamAnnotation;
    1313import com.framsticks.params.types.EventParam;
     14import com.framsticks.params.types.ProcedureParam;
    1415import com.framsticks.parsers.MultiParamLoader;
    1516import com.framsticks.core.Instance;
     
    8283                                                }
    8384
    84                                                 invokeLater(new RunAt<Instance>() {
     85                                                dispatch(new RunAt<Instance>() {
    8586                                                        @Override
    8687                                                        public void run() {
     
    103104                                                                                        @Override
    104105                                                                                        public void call(List<File> files) {
    105                                                                                                 invokeLater(new RunAt<Instance>() {
     106                                                                                                dispatch(new RunAt<Instance>() {
    106107                                                                                                        @Override
    107108                                                                                                        public void run() {
     
    361362                                log.debug("subscribed for change event for " + path);
    362363                                // subscription.setDispatcher(RemoteInstance.this);
    363                                 RemoteInstance.this.invokeLater(new RunAt<Instance>() {
     364                                RemoteInstance.this.dispatch(new RunAt<Instance>() {
    364365                                        @Override
    365366                                        public void run() {
     
    497498        }
    498499
    499 
    500500        @Override
    501501        public void childChangedState(Joinable joinable, JoinableState state) {
     
    503503        }
    504504
     505        @Override
     506        public void call(Path path, ProcedureParam param, Object[] arguments, StateFunctor stateFunctor) {
     507                throw new UnimplementedException();
     508        }
    505509
    506510}
  • java/main/src/main/java/com/framsticks/running/ExternalProcess.java

    r88 r90  
    1515
    1616import com.framsticks.core.Entity;
     17import com.framsticks.params.annotations.AutoAppendAnnotation;
    1718import com.framsticks.params.annotations.FramsClassAnnotation;
    1819import com.framsticks.params.annotations.ParamAnnotation;
    1920import com.framsticks.util.FramsticksException;
    2021import com.framsticks.util.Misc;
     22import com.framsticks.util.dispatching.AbstractJoinable;
     23import com.framsticks.util.dispatching.Dispatching;
     24import com.framsticks.util.dispatching.Joinable;
     25import com.framsticks.util.dispatching.JoinableParent;
     26import com.framsticks.util.dispatching.JoinableState;
     27import com.framsticks.util.dispatching.RunAt;
    2128import com.framsticks.util.dispatching.Thread;
    2229import com.framsticks.util.io.Encoding;
    2330
    2431@FramsClassAnnotation
    25 public class ExternalProcess extends Thread<ExternalProcess> implements Entity {
     32public class ExternalProcess extends AbstractJoinable implements JoinableParent, Entity {
    2633        private static final Logger log = Logger.getLogger(ExternalProcess.class);
    2734
    2835        protected List<String> arguments = new ArrayList<>();
    2936        protected Process process;
    30         protected ProcessBuilder builder = new ProcessBuilder();
    31         protected Thread<ExternalProcess> readerThread;
     37        protected final ProcessBuilder builder = new ProcessBuilder();
     38        protected Thread<ExternalProcess> readerThread = new Thread<ExternalProcess>();
    3239
    3340        protected PrintWriter input;
     
    3744        protected final List<OutputListener> listeners = new LinkedList<>();
    3845
     46        @AutoAppendAnnotation
    3947        public void addListener(OutputListener listener) {
    4048                synchronized (listeners) {
     
    5058                setName("process");
    5159                arguments.add(null);
     60                builder.redirectErrorStream(true);
    5261        }
    5362
     
    6877        }
    6978
    70         @Override
    71         protected void routine() {
     79        protected void readerTask() {
    7280
    7381                String line;
     
    9199                        }
    92100                        log.debug("process ended " + this);
    93                         process = null;
     101                        // process = null;
    94102                } catch (FramsticksException e) {
    95103                        log.error("exception caught in process " + this, e);
    96104                }
    97105                interrupt();
     106                // finish();
    98107        }
    99 
    100 
    101108
    102109        @ParamAnnotation
     
    111118
    112119        @Override
    113         public void joinableStart() {
    114                 builder = new ProcessBuilder();
     120        protected void joinableStart() {
    115121                log.debug("running process with arguments: " + arguments);
    116122                builder.command(arguments);
     
    119125                        input = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), Encoding.getDefaultCharset()));
    120126                        output = new BufferedReader(new InputStreamReader(process.getInputStream(), Encoding.getDefaultCharset()));
     127
    121128                } catch (IOException e) {
    122129                        throw new FramsticksException().msg("failed to start process").cause(e);
    123130                }
    124                 super.joinableStart();
    125131
     132                readerThread.dispatch(new RunAt<ExternalProcess>() {
     133
     134                        @Override
     135                        public void run() {
     136                                readerTask();
     137                        }
     138
     139                });
     140                Dispatching.use(readerThread, this);
    126141        }
    127142
    128143        @Override
    129144        public String toString() {
    130                 return super.toString() + "[" + Misc.returnNotNull(getCommand(), "?") + "]";
     145                return getName() + "[" + Misc.returnNotNull(getCommand(), "?") + "]";
    131146        }
    132147
     
    140155        @Override
    141156        protected void joinableInterrupt() {
    142                 super.joinableInterrupt();
    143                 finish();
     157                process.destroy();
     158                Dispatching.drop(readerThread, this);
     159                // finish();
    144160        }
    145161
     162        @Override
     163        @ParamAnnotation
     164        public String getName() {
     165                return readerThread.getName();
     166        }
     167
     168        /**
     169         * @param name the name to set
     170         */
     171        @ParamAnnotation
     172        public void setName(String name) {
     173                readerThread.setName(name);
     174        }
     175
     176        @Override
     177        protected void joinableFinish() {
     178
     179        }
     180
     181        @Override
     182        protected void joinableJoin() throws InterruptedException {
     183                Dispatching.join(readerThread);
     184        }
     185
     186        @Override
     187        public void childChangedState(Joinable joinable, JoinableState state) {
     188                proceedToState(state);
     189        }
     190
     191
     192
    146193}
  • java/main/src/main/java/com/framsticks/running/FramsServer.java

    r88 r90  
    88
    99        protected Integer port;
     10        protected String path;
    1011
    1112        /**
     
    1415        public FramsServer() {
    1516                super();
    16                 setCommand("/home/psniegowski/mgr/Framsticks32rc5/frams.linux");
    17                 setDirectory("/home/psniegowski/mgr/Framsticks32rc5");
     17                setPath(System.getProperties().get("user.home") + "/opt/framsticks");
    1818                setName("frams");
    1919        }
     20
    2021
    2122        /**
     
    3536        }
    3637
     38        /**
     39         * @return the path
     40         */
     41        @ParamAnnotation
     42        public String getPath() {
     43                return path;
     44        }
     45
     46        /**
     47         * @param path the path to set
     48         */
     49        @ParamAnnotation
     50        public void setPath(String path) {
     51                this.path = path;
     52                setCommand(path + "/frams.linux");
     53                setDirectory(path);
     54        }
     55
    3756        @Override
    38         public void joinableStart() {
     57        protected void joinableStart() {
    3958                if (port != null) {
     59                        arguments.add("-n");
    4060                        arguments.add("-p" + port);
    4161                }
  • java/main/src/main/java/com/framsticks/util/DoubleMap.java

    r88 r90  
    5050        }
    5151
     52        public Map<K, V> getValuesById() {
     53                return Collections.unmodifiableMap(byId);
     54        }
     55
    5256}
  • java/main/src/main/java/com/framsticks/util/Logging.java

    r77 r90  
    77 */
    88public abstract class Logging {
    9     public static boolean log(Logger logger, String action, Object subject, Exception e) {
    10         if (e != null) {
    11             logger.error("failed to " + action + " " + subject + ": " + e);
    12             return true;
    13         }
    14         if (logger.isDebugEnabled()) {
    15             logger.debug("done: " + action + " " + subject);
    16         }
    17         return false;
    18     }
     9        public static boolean log(Logger logger, String action, Object subject, Exception e) {
     10                if (e != null) {
     11                        logger.error("failed to " + action + " " + subject + ": ", e);
     12                        return true;
     13                }
     14                if (logger.isDebugEnabled()) {
     15                        logger.debug("done: " + action + " " + subject);
     16                }
     17                return false;
     18        }
    1919}
  • java/main/src/main/java/com/framsticks/util/PeriodicTask.java

    r85 r90  
    1616                this.period = period;
    1717                this.dispatcher = dispatcher;
    18                 dispatcher.invokeLater(this);
     18                dispatcher.dispatch(this);
    1919        }
    2020
    2121
    2222        public void again() {
    23                 dispatcher.invokeLater(new Task<C>(System.currentTimeMillis() + period) {
     23                dispatcher.dispatch(new Task<C>(System.currentTimeMillis() + period) {
    2424                        @Override
    2525                        public void run() {
  • java/main/src/main/java/com/framsticks/util/dispatching/AbstractJoinable.java

    r88 r90  
    6464                                }
    6565                        }
     66                        this.notifyAll();
    6667                }
    6768                report();
  • java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java

    r88 r90  
    2020
    2121        @Override
    22         public final void invokeLater(RunAt<? extends C> runnable) {
     22        public final void dispatch(RunAt<? extends C> runnable) {
    2323                runnable.run();
    2424        }
  • java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java

    r88 r90  
    66public interface Dispatcher<C> {
    77        public boolean isActive();
    8         public void invokeLater(RunAt<? extends C> runnable);
     8        public void dispatch(RunAt<? extends C> runnable);
    99
    1010}
  • java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java

    r88 r90  
    1515        }
    1616
    17         public static <C> void invokeLaterOrNow(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
     17        public static <C> void dispatchIfNotActive(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
    1818                if (dispatcher.isActive()) {
    1919                        runnable.run();
    2020                        return;
    2121                }
    22                 dispatcher.invokeLater(runnable);
     22                dispatcher.dispatch(runnable);
    2323        }
    2424
    2525        //TODO RunAt StateFunctor
    2626        public static <C> void dispatchOk(Dispatcher<C> dispatcher, final StateFunctor stateFunctor) {
    27                 dispatcher.invokeLater(new RunAt<C>() {
     27                dispatcher.dispatch(new RunAt<C>() {
    2828                        @Override
    2929                        public void run() {
     
    3939
    4040        public static <P, C> void invokeDispatch(Dispatcher<P> dispatcher, final Dispatcher<C> finalDispatcher, final RunAt<C> runnable) {
    41                 dispatcher.invokeLater(new RunAt<P>() {
     41                dispatcher.dispatch(new RunAt<P>() {
    4242                        @Override
    4343                        public void run() {
    44                                 finalDispatcher.invokeLater(runnable);
     44                                finalDispatcher.dispatch(runnable);
    4545                        }
    4646                });
    4747        }
    4848
    49         public static void sleep(int milliseconds) {
     49        public static void sleep(double seconds) {
    5050                try {
    51                         java.lang.Thread.sleep(milliseconds, 0);
     51                        java.lang.Thread.sleep((long) (seconds * 1000));
    5252                } catch (InterruptedException e) {
    5353
     
    5858        public static void dispatcherGuardedInvoke(Joinable joinable, RunAt<?> runnable) {
    5959                if (joinable instanceof Dispatcher) {
    60                         invokeLaterOrNow(Dispatcher.class.cast(joinable), runnable);
     60                        dispatchIfNotActive(Dispatcher.class.cast(joinable), runnable);
    6161                        return;
    6262                }
     
    7272                }
    7373        }
    74 
    7574
    7675        public static void drop(final Joinable joinable, final JoinableParent owner) {
     
    106105        public static void wait(Object object, long millis) {
    107106                try {
    108                         object.wait(millis);
     107                        synchronized (object) {
     108                                object.wait(millis);
     109                        }
    109110                } catch (InterruptedException e) {
    110111                }
     
    112113
    113114        public static void joinAbsolutely(Joinable joinable) {
    114                 log.info("joining absolutely " + joinable);
     115                log.debug("joining absolutely " + joinable);
    115116                while (true) {
    116117                        try {
     
    120121                                // throw new FramsticksException().msg("failed to join").arg("dispatcher", dispatcher).cause(e);
    121122                        }
    122                         log.info("waiting for " + joinable);
    123                         sleep(500);
     123                        log.debug("waiting for " + joinable);
     124                        wait(joinable, 500);
    124125                }
     126        }
     127
     128        public interface Query<T> {
     129                T get();
     130        }
     131
     132        public static class QueryRunner<T, C> extends RunAt<C> {
     133                protected final Query<T> query;
     134                T result;
     135                boolean ready = false;
     136
     137                /**
     138                 * @param query
     139                 */
     140                public QueryRunner(Query<T> query) {
     141                        this.query = query;
     142                }
     143
     144                @Override
     145                public void run() {
     146                        result = query.get();
     147                        synchronized (this) {
     148                                ready = true;
     149                                this.notifyAll();
     150                        }
     151                }
     152
     153                public T get() {
     154                        synchronized (this) {
     155                                while (!ready) {
     156                                        try {
     157                                                this.wait(100);
     158                                        } catch (InterruptedException e) {
     159                                        }
     160                                }
     161                        }
     162                        return result;
     163                }
     164        }
     165
     166        public static <T, C> T get(Dispatcher<C> dispatcher, Query<T> query) {
     167                QueryRunner<T, C> runner = new QueryRunner<T, C>(query);
     168                dispatcher.dispatch(runner);
     169                return runner.get();
    125170        }
    126171
    127172
    128173
    129 
    130174}
  • java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java

    r85 r90  
    77
    88        public RunAt(Dispatcher<? super C> dispatcher) {
    9                 dispatcher.invokeLater(this);
     9                dispatcher.dispatch(this);
    1010        }
    1111}
  • java/main/src/main/java/com/framsticks/util/dispatching/Thread.java

    r88 r90  
    66import java.util.ListIterator;
    77
    8 import javax.annotation.OverridingMethodsMustInvokeSuper;
    98
    109import com.framsticks.params.annotations.ParamAnnotation;
     
    3130        }
    3231
    33         @OverridingMethodsMustInvokeSuper
    34         protected void firstTask() {
    35         }
    3632
    3733        public Thread(java.lang.Thread thread) {
     
    5147        protected void routine() {
    5248                log.debug("starting thread " + this);
    53                 firstTask();
    5449                while (!java.lang.Thread.interrupted()) {
    5550                        Task<? extends C> task;
     
    7873                                task.run();
    7974                        } catch (Exception e) {
    80                                 log.error("error in thread: " + e);
     75                                log.error("error in thread: ", e);
    8176                        }
    8277                }
     
    115110
    116111        @Override
    117         public void invokeLater(final RunAt<? extends C> runnable) {
     112        public void dispatch(final RunAt<? extends C> runnable) {
    118113                if (!(runnable instanceof Task)) {
    119114                        enqueueTask(new Task<C>() {
  • java/main/src/main/java/com/framsticks/util/lang/Containers.java

    r86 r90  
    11package com.framsticks.util.lang;
    22
     3import java.util.ArrayList;
    34import java.util.Collection;
    45import java.util.Iterator;
     
    89import org.apache.commons.collections.functors.NotPredicate;
    910import org.apache.commons.collections.iterators.FilterIterator;
     11
     12import com.framsticks.util.Builder;
     13import com.framsticks.util.FramsticksException;
    1014
    1115/**
     
    3741                return new IterableIterator<T>(new FilterIterator(c.iterator(), new NotPredicate(new InstanceofPredicate(type))));
    3842        }
     43
     44        public static <T> T getFromList(List<T> list, int number, String name, Object context) {
     45                if (number < 0 || number >= list.size()) {
     46                        throw new FramsticksException().msg("invalid " + name + " number").arg("number", number).arg("in", context);
     47                }
     48                return list.get(number);
     49        }
     50
     51        public static <T> List<T> build(List<? extends Builder<T>> builders) {
     52                List<T> result = new ArrayList<T>();
     53                for (Builder<T> builder : builders) {
     54                        result.add(builder.finish());
     55                }
     56                return result;
     57        }
    3958}
  • java/main/src/main/resources/configs/framsticks.xml

    r88 r90  
    33        <import class="com.framsticks.gui.Browser" />
    44        <import class="com.framsticks.remote.RemoteInstance" />
     5        <import class="com.framsticks.model.ModelPackage" />
     6        <import class="com.framsticks.model.ModelBuilder" />
     7        <import class="com.framsticks.model.f0.SchemaBuilder" />
     8        <import class="com.framsticks.core.ObjectInstance" />
     9        <import class="com.framsticks.test.TestClass" />
    510        <Browser>
    6                 <RemoteInstance name="localhost:9009" address="localhost:9009" />
     11                <RemoteInstance name="localhost:9009" address="localhost:9009">
     12                        <ModelPackage />
     13                </RemoteInstance>
     14                <ObjectInstance name="model">
     15                        <ModelBuilder resource="/examples/f0_example.txt" />
     16                </ObjectInstance>
     17                <ObjectInstance name="f0schema">
     18                        <SchemaBuilder />
     19                </ObjectInstance>
     20                <ObjectInstance name="test">
     21                        <TestClass />
     22                </ObjectInstance>
    723        </Browser>
    8         <!-- <Browser name="other"> -->
    9         <!--    <RemoteInstance name="localhost:9009" address="localhost:9009" /> -->
    10         <!-- </Browser> -->
    1124</Framsticks>
  • java/main/src/main/resources/configs/log4j.properties

    r88 r90  
    2929
    3030log4j.logger.com.framsticks=INFO
     31# log4j.logger.com.framsticks.core.ObjectInstance=DEBUG
     32# log4j.logger.com.framsticks.core.Instance=DEBUG
     33log4j.logger.com.framsticks.gui.controls.ProcedureControl=DEBUG
     34# log4j.logger.com.framsticks.params.ReflectionAccess=TRACE
    3135# log4j.logger.com.framsticks.util.dispatching.Dispatching=DEBUG
    3236# log4j.logger.com.framsticks.util.dispatching.AbstractJoinable=DEBUG
  • java/main/src/main/resources/examples/f0_example.txt

    r78 r90  
    1212n:j=0,d=@:p=0.25
    1313n:p=1,d=Nu
    14 #c:0,2
    15 #c:0,2,5.4
    16 #c:1,0
    17 #c:2,0,3.4
    18 #c:0,1,4.5
    19 #c:1,0,5.6
    20 #c:2,1
     14c:0,2
     15c:0,2,5.4
     16c:1,0
     17c:2,0,3.4
     18c:0,1,4.5
     19c:1,0,5.6
     20c:2,1
  • java/main/src/main/resources/parsers/f0def.xml

    r78 r90  
    1111  <PROP ID="joints" NAME="joints" GROUP="2" FLAGS="0" TYPE="l Joint" />
    1212  <PROP ID="neurodefs" NAME="neurodefs" GROUP="2" FLAGS="0" TYPE="l NeuroDef" />
     13  <PROP ID="neuroconns" NAME="neuroconns" GROUP="2" FLAGS="0" TYPE="l NeuroConn" />
    1314 </CLASS>
    1415
     
    158159  <NEUROPROP ID="noDim" NAME="number of degrees of freedom" TYPE="d" MIN="" MAX="" DEF="" />
    159160  <NEUROPROP ID="params" NAME="parameters" TYPE="s" MIN="" MAX="" DEF="" />
    160  </NEUROCLASS> 
     161 </NEUROCLASS>
    161162
    162163 <NEUROCLASS ID="Sti" NAME="Sticky [EXPERIMENTAL!]" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="1"  VISUALHINTS="16"  >
  • java/main/src/test/java/com/framsticks/gui/BrowserTest.java

    r88 r90  
    11package com.framsticks.gui;
    22
    3 import javax.swing.JFrame;
     3import static org.fest.assertions.Assertions.assertThat;
     4import static org.fest.swing.edt.GuiActionRunner.execute;
     5
    46
    57import org.apache.log4j.Logger;
    6 import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
    7 import org.fest.swing.edt.GuiActionRunner;
    8 import org.fest.swing.edt.GuiQuery;
    98import org.fest.swing.edt.GuiTask;
    10 import org.fest.swing.fixture.FrameFixture;
    11 import org.fest.swing.fixture.JTreeFixture;
    12 // import static org.fest.swing.edt.GuiActionRunner.*;
    13 import org.testng.annotations.*;
     9import org.testng.annotations.Test;
    1410
     11import com.framsticks.model.ModelPackage;
    1512import com.framsticks.remote.RemoteInstance;
    16 import com.framsticks.test.TestConfiguration;
    17 import com.framsticks.util.dispatching.Dispatching;
    18 import com.framsticks.util.dispatching.JoinableMonitor;
    19 // import com.framsticks.util.dispatching.Dispatching;
    2013
    21 import static org.fest.assertions.Assertions.*;
    22 import static org.fest.swing.core.BasicRobot.robotWithNewAwtHierarchy;
    23 import static org.fest.swing.edt.GuiActionRunner.*;
    24 import org.fest.swing.core.Robot;
     14public class BrowserTest extends BrowserBaseTest {
    2515
    26 public class BrowserTest extends TestConfiguration {
    2716        private static final Logger log = Logger.getLogger(BrowserTest.class);
    2817
    29         JoinableMonitor monitor;
    30         Browser browser;
    31         Robot robot;
    32         FrameFixture frame;
     18        RemoteInstance localhost;
    3319
    34         @BeforeClass
    35         public void setUp() {
    36                 FailOnThreadViolationRepaintManager.install();
    37                 assertThat(executeInEDT()).isTrue();
     20        @Override
     21        protected void configureBrowser() {
     22                browser = new Browser();
    3823
    39                 robot = robotWithNewAwtHierarchy();
    40 
    41                 browser = new Browser();
    42                 monitor = new JoinableMonitor(browser);
    43 
    44                 RemoteInstance localhost = new RemoteInstance();
     24                localhost = new RemoteInstance();
    4525                localhost.setName("localhost");
    4626                localhost.setAddress("localhost:9009");
     27                localhost.usePackage(new ModelPackage());
    4728
    4829                browser.addInstance(localhost);
    4930
    50                 monitor.use();
    51                 // robot.waitForIdle();
    52                 frame = new FrameFixture(robot,
    53                                 GuiActionRunner.execute(new GuiQuery<JFrame>() {
    54                                         @Override
    55                                         protected JFrame executeInEDT() throws Throwable {
    56                                                 return browser.getMainFrame().getSwing();
    57                                         }
    58                                 }));
    59 
    60                 log.info("frame fixture done");
    61                 // frame.show();
    62                 // log.info("frame fixture shown");
    6331        }
    6432
    65         public void clickAndExpandPath(JTreeFixture tree, String path) {
    66                 tree.clickPath(path).expandPath(path);
    67                 robot.waitForIdle();
    68         }
    69 
    70         @Test
     33        @Test(timeOut = 10000)
    7134        public void testShow() {
    7235                log.info("testing");
    73                 JTreeFixture tree = frame.tree("tree");
    7436                tree.clickRow(0).expandRow(0);
    7537                robot.waitForIdle();
     
    8143                        @Override
    8244                        protected void executeInEDT() throws Throwable {
    83                                 assertThat(frame.panel("o Simulator").component().isVisible())
    84                                                 .isTrue();
     45                                assertThat(frame.panel("Simulator").component().isVisible()).isTrue();
    8546                        }
    8647                });
    8748
    88                 clickAndExpandPath(tree, "localhost/simulator/genepools");
    89                 clickAndExpandPath(tree, "localhost/simulator/genepools/groups");
    90                 clickAndExpandPath(tree, "localhost/simulator/genepools/groups/Genotypes");
     49                clickAndExpandPath("localhost/simulator/genepools");
     50                clickAndExpandPath("localhost/simulator/genepools/groups");
     51                clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes");
     52        }
    9153
    9254
    9355
    94 
    95 
    96 
    97                 // tree.clickPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
    98                 // robot.waitForIdle();
    99                 // sleep(2);
    100                 // tree.expandPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
    101 
    102                 // tree.expandRow(tree.component().getLeadSelectionRow() + 1);
    103                 // robot.waitForIdle();
    104 
    105                 // sleep(2);
    106         }
    107 
    108 
    109         @AfterClass
    110         public void tearDown() {
    111                 log.info("before close");
    112 
    113                 monitor.drop();
    114 
    115                 Dispatching.joinAbsolutely(browser);
    116                 // frame.cleanUp();
    117                 // log.info("before close");
    118                 // browser.interrupt();
    119 
    120                 // try {
    121                 //      // frame.close();
    122                 // } catch (Throwable t) {
    123                 //      log.error("caught ", t);
    124                 // }
    125                 // log.info("after close");
    126                 // // frame.close();
    127                 // // frame.cleanUp();
    128 
    129 
    130 
    131                 // Dispatching.join(browser);
    132         }
    133 
    13456}
  • java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java

    r88 r90  
    33import org.testng.annotations.*;
    44
     5import com.framsticks.params.FramsClass;
    56import com.framsticks.params.types.FloatParam;
    67import com.framsticks.test.TestConfiguration;
     
    1516        @Test
    1617        public void loadSchemaWithXmlLoader() {
    17                 Schema schema = Schema.load(Schema.getDefaultDefinitionAsStream());
     18                Schema schema = new SchemaBuilder().stream(Schema.getDefaultDefinitionAsStream()).finish();
    1819                assertThat(schema.getFramsClasses().size()).isEqualTo(5);
    1920                assertThat(schema.getNeuroClasses().size()).isEqualTo(21);
     
    2324                assertThat(schema.getNeuroClass("VEye").getParamEntry("p", FloatParam.class).getMax(Double.class)).isEqualTo(10.0, delta(0.0));
    2425
    25                 assertThat(schema.getFramsClass("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
     26                FramsClass partClass = schema.getFramsClass("p");
     27                assertThat(partClass).isNotNull();
     28                assertThat(partClass.getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
     29                assertThat(partClass.getGroupCount()).isEqualTo(3);
     30                assertThat(partClass.getGroup(1).getName()).isEqualTo("Other properties");
     31                assertThat(partClass.getGroup(1).getCount()).isEqualTo(7);
     32                assertThat(partClass.getGroup(1).getParam(2)).isEqualTo(partClass.getParam("dn"));
    2633        }
    2734
  • java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java

    r88 r90  
    44
    55import com.framsticks.model.*;
    6 import com.framsticks.model.Package;
    76import com.framsticks.model.f0.Schema;
     7import com.framsticks.model.f0.SchemaBuilder;
    88import com.framsticks.params.*;
    99import com.framsticks.params.types.FloatParam;
     
    2525        private Schema schema;
    2626        private List<AccessInterface> accesses;
    27         private List<Object> objects;
     27        private List<ModelComponent> components;
    2828        private Model model;
    2929
    3030        @BeforeClass
    3131        public void setUp() throws Exception {
    32                 schema = Schema.load(Schema.getDefaultDefinitionAsStream());
    33                 Package.register(schema.getRegistry());
     32                schema = new SchemaBuilder().stream(Schema.getDefaultDefinitionAsStream()).finish();
    3433        }
    3534
    3635        @Test
     36        public void checkFramsClasses() {
     37                FramsClass modelClass = schema.getRegistry().getFramsClass("Model");
     38                assertThat(modelClass).isNotNull();
     39                assertThat(modelClass.getParam("se")).isInstanceOf(FloatParam.class);
     40                // assertThat(modelClass.getParam("energ0")).isInstanceOf(FloatParam.class);
     41                assertThat(modelClass.getParam("Vstyle")).isInstanceOf(StringParam.class);
     42                assertThat(modelClass.getParamCount()).isEqualTo(6);
     43                // assertThat();
     44
     45        }
     46
     47        @Test(dependsOnMethods = "checkFramsClasses")
    3748        public void primitiveParam() {
    3849                FramsClass joint = schema.getFramsClass("j");
     
    4354                assertThat(dx.getMin(Double.class)).isEqualTo(-2.0, delta(0.0));
    4455
    45                 assertThat(schema.getRegistry().getInfoFromCache("n").getParamEntry("d", StringParam.class).getDef(String.class)).isEqualTo("N");
     56                assertThat(schema.getRegistry().getFramsClass("n").getParamEntry("d", StringParam.class).getDef(String.class)).isEqualTo("N");
    4657        }
    4758
    48         @Test
     59        @Test(dependsOnMethods = "primitiveParam")
    4960        public void readF0() throws IOException, ParseException {
    5061                assertThat(schema.getFramsClass("p")).isInstanceOf(FramsClass.class);
    51                 assertThat(schema.getRegistry().getInfoFromCache("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
     62                assertThat(schema.getRegistry().getFramsClass("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
    5263
    5364                accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
    5465
    55                 assertThat(accesses.size()).isEqualTo(12);
     66                assertThat(accesses.size()).isEqualTo(19);
    5667                assertThat(accesses.get(0).getSelected()).isInstanceOf(Model.class);
    5768                assertThat(accesses.get(5).get("i", String.class)).isEqualTo("1,2,3,\"dsadsa,,,,");
     
    6273        @Test(dependsOnMethods = {"readF0"})
    6374        public void stripAccessInterface() {
    64                 objects = Util.stripAccessInterface(accesses);
     75                components = Util.stripAccessInterface(accesses, ModelComponent.class);
    6576
    66                 assertThat(objects.get(1)).isInstanceOf(Part.class);
    67                 assertThat(objects.get(4)).isInstanceOf(Joint.class);
    68                 assertThat(objects.get(6)).isInstanceOf(NeuroDef.class);
     77                assertThat(components.get(1)).isInstanceOf(Part.class);
     78                assertThat(components.get(4)).isInstanceOf(Joint.class);
     79                assertThat(components.get(6)).isInstanceOf(NeuroDefinition.class);
     80                assertThat(components.get(12)).isInstanceOf(NeuroConnection.class);
    6981        }
    7082
    7183        @Test(dependsOnMethods = {"stripAccessInterface"})
    7284        public void buildModel() {
    73                 model = Model.build(objects);
     85                model = new ModelBuilder().addComponents(components).finish();
    7486
    7587                assertThat(model.getParts().size()).isEqualTo(3);
    76                 assertThat(model.getNeuroDefs().size()).isEqualTo(6);
     88                assertThat(model.getNeuroDefinitions().size()).isEqualTo(6);
    7789                assertThat(model.getJoints().size()).isEqualTo(2);
    78 
    79                 assertThat(model.getJoints().get(0).part1).isEqualTo(0);
    80                 assertThat(model.getJoints().get(0).part2).isEqualTo(1);
    81                 assertThat(model.getNeuroDefs().size()).isEqualTo(6);
    82                 assertThat(model.getNeuroDefs().get(0).part).isEqualTo(1);
    83                 assertThat(model.getNeuroDefs().get(0).joint).isEqualTo(-1);
    84                 assertThat(model.getNeuroDefs().get(1).details).isEqualTo("|:p=0.25,r=1");
    85                 assertThat(model.getNeuroDefs().get(3).details).isEqualTo("N");
    86                 assertThat(model.getNeuroDefs().get(4).part).isEqualTo(-1);
     90                assertThat(model.getNeuroConnections().size()).isEqualTo(7);
    8791
    8892                assertThat(model.getParts().get(1).getPosition().x).isEqualTo(2.0, delta(0.0));
    8993                assertThat(model.getParts().get(2).getPosition().sub(new Point3d(2.27236, -0.0792596, -0.958924)).length()).isLessThan(0.0001);
    9094                assertThat(model.getParts().get(2).getOrientation().y.sub(new Point3d(0.870277, -0.404792, 0.280644)).length()).isLessThan(0.0001);
     95
     96                assertThat(model.getJoints().get(0).part1).isEqualTo(0);
     97                assertThat(model.getJoints().get(0).part2).isEqualTo(1);
     98
     99                assertThat(model.getNeuroDefinitions().get(0).part).isEqualTo(1);
     100                assertThat(model.getNeuroDefinitions().get(0).joint).isEqualTo(-1);
     101                assertThat(model.getNeuroDefinitions().get(1).details).isEqualTo("|:p=0.25,r=1");
     102                assertThat(model.getNeuroDefinitions().get(3).details).isEqualTo("N");
     103                assertThat(model.getNeuroDefinitions().get(4).part).isEqualTo(-1);
     104
     105                assertThat(model.getNeuroConnections().get(2).connectedNeuro).isEqualTo(0);
     106                assertThat(model.getNeuroConnections().get(5).weight).isEqualTo(5.6, delta(0.0));
     107
    91108        }
    92109
     
    94111        public void print() throws Exception {
    95112                ListSink sink = new ListSink();
    96 
    97113
    98114                new F0Writer(schema, model, sink).write();
     
    110126                        "n:j=0,d=@:p=0.25",
    111127                        "n:p=1,d=Nu",
     128                        "c:0,2",
     129                        "c:0,2,5.4",
     130                        "c:1,0",
     131                        "c:2,0,3.4",
     132                        "c:0,1,4.5",
     133                        "c:1,0,5.6",
     134                        "c:2,1",
    112135                        "m:"
    113136                );
  • java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java

    r88 r90  
    1010
    1111import com.framsticks.test.TestConfiguration;
    12 import com.framsticks.util.dispatching.JoinableMonitor;
     12import com.framsticks.util.dispatching.Monitor;
    1313
    1414import static org.fest.assertions.Assertions.*;
     
    1717public class ExternalProcessTest extends TestConfiguration {
    1818
    19         @Test
     19        @Test(timeOut = 1000)
    2020        public void runBash() throws InterruptedException {
    2121                final ExternalProcess process = new ExternalProcess();
     
    3131                        }
    3232                });
    33                 JoinableMonitor monitor = new JoinableMonitor(process);
     33                Monitor monitor = new Monitor(process);
    3434                monitor.use();
    3535
  • java/main/src/test/java/com/framsticks/running/FramsServerTest.java

    r88 r90  
    44
    55import com.framsticks.core.Framsticks;
    6 import com.framsticks.remote.RemoteInstance;
    76import com.framsticks.test.TestConfiguration;
     7import com.framsticks.util.dispatching.Monitor;
    88
    99import static org.fest.assertions.Assertions.*;
     
    1212public class FramsServerTest extends TestConfiguration {
    1313
    14         @Test
     14        @Test(timeOut = 3000)
    1515        public void runServer() {
    1616                Framsticks framsticks = Framsticks.loadConfiguration(FramsServerTest.class.getResourceAsStream("/configs/FramsServerTest.xml"));
    1717
    18                 assertThat(framsticks.getObservables().size()).isEqualTo(2);
     18                assertThat(framsticks.getObservables().size()).isEqualTo(1);
    1919                assertThat(framsticks.getObservables().get("frams")).isInstanceOf(FramsServer.class);
    20                 assertThat(framsticks.getObservables().get("remote")).isInstanceOf(RemoteInstance.class);
     20                // assertThat(framsticks.getObservables().get("remote")).isInstanceOf(RemoteInstance.class);
     21
     22                new Monitor(framsticks).use().useFor(1.0).drop().join();
     23
     24                // monitor.use();
     25
     26                // Dispatching.sleep(1000);
     27
     28                // // monitor.waitFor();
     29                // monitor.drop();
     30                // monitor.join();
    2131
    2232                // framsticks.start();
  • java/main/src/test/java/com/framsticks/test/TestConfiguration.java

    r88 r90  
    11package com.framsticks.test;
     2
     3import java.util.LinkedList;
     4import java.util.List;
    25
    36import org.apache.log4j.Logger;
     
    58import org.testng.annotations.*;
    69
     10import com.framsticks.util.dispatching.Dispatcher;
     11import com.framsticks.util.dispatching.RunAt;
     12
    713public class TestConfiguration {
    814
    9         private static final Logger log =
    10                 Logger.getLogger(TestConfiguration.class);
     15        private static final Logger log = Logger.getLogger(TestConfiguration.class);
    1116
    1217        @BeforeClass
     
    1621        }
    1722
     23        private final List<AsyncAssert<?>> asyncAssertions = new LinkedList<AsyncAssert<?>>();
     24
     25        public class AsyncAssert<C> extends RunAt<C> {
     26                final RunAt<? extends C> runnable;
     27                boolean done = false;
     28                AssertionError assertion;
     29
     30                /**
     31                 * @param runnable
     32                 */
     33                public AsyncAssert(RunAt<? extends C> runnable) {
     34                        this.runnable = runnable;
     35                }
     36
     37                @Override
     38                public void run() {
     39                        try {
     40                                runnable.run();
     41                        } catch (AssertionError e) {
     42                                assertion = e;
     43                        }
     44                        synchronized (this) {
     45                                done = true;
     46                                this.notifyAll();
     47                        }
     48                }
     49        }
     50
     51        public <C> void assertDispatch(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
     52                AsyncAssert<C> assertion = new AsyncAssert<C>(runnable);
     53                synchronized (asyncAssertions) {
     54                        asyncAssertions.add(assertion);
     55                }
     56                dispatcher.dispatch(assertion);
     57        }
     58
     59        @BeforeMethod
     60        public void clearAsyncAsserts() {
     61                synchronized (asyncAssertions) {
     62                        asyncAssertions.clear();
     63                }
     64        }
     65
     66        @AfterMethod(timeOut = 5000)
     67        public void waitForAsyncAsserts() {
     68                while (true) {
     69                        AsyncAssert<?> assertion;
     70                        synchronized (asyncAssertions) {
     71                                if (asyncAssertions.isEmpty()) {
     72                                        return;
     73                                }
     74                                assertion = asyncAssertions.get(0);
     75                                asyncAssertions.remove(0);
     76                        }
     77                        synchronized (assertion) {
     78                                while (!assertion.done) {
     79                                        try {
     80                                                assertion.wait();
     81                                        } catch (InterruptedException ignored) {
     82                                        }
     83                                }
     84                                if (assertion.assertion != null) {
     85                                        throw assertion.assertion;
     86                                }
     87                        }
     88                }
     89        }
    1890}
  • java/main/src/test/resources/configs/FramsServerTest.xml

    r88 r90  
    33        <import class="com.framsticks.running.FramsServer" />
    44        <import class="com.framsticks.remote.RemoteInstance" />
    5         <FramsServer name="frams" port="9008" />
    6         <RemoteInstance name="remote" address="localhost:9008" />
     5        <import class="com.framsticks.running.LoggingOutputListener" />
     6        <FramsServer name="frams" port="9008">
     7                <LoggingOutputListener />
     8        </FramsServer>
     9        <!-- <RemoteInstance name="remote" address="localhost:9008" /> -->
    710</Framsticks>
  • java/main/src/test/resources/info/Part.info

    r86 r90  
    33
    44prop:
     5id:x
    56name:position.x
    6 id:x
    77type:f
    88flags:1024
    99
    1010prop:
     11id:y
    1112name:position.y
    12 id:y
    1313type:f
    1414flags:1024
    1515
    1616prop:
     17id:z
    1718name:position.z
    18 id:z
    1919type:f
    2020flags:1024
    2121
    2222prop:
     23id:m
    2324name:mass
    24 id:m
    25 type:f
    26 flags:0
     25type:f 0.1 999.0 1.0
    2726
    2827prop:
     28id:s
    2929name:size
    30 id:s
    31 type:f
    32 flags:0
     30type:f 0.1 10.0 1.0
    3331
    3432prop:
     33id:dn
    3534name:density
    36 id:dn
    37 type:f
    38 flags:0
     35type:f 0.2 5.0 1.0
    3936
    4037prop:
     38id:fr
    4139name:friction