Code documentation

Development tools

Code Structure

Techniques and Standards

How To

Functional Info

Background Info

JMRI Code: Multi-connection Update

This page is a list of hints for adapting systems (jmri.jmrix subdirectories) to the new multi-system format.
It's clearly a work in progress!

Basically, you have to get all the static variables and instance() methods out of the code. In their place, you put references to methods of a specific SystemConnectionMemo object that carries the references that used to be static.

At the same time, we're doing the Swing pattern update, and a couple other minor cleanups on the code.

In primary system directory

Create a specific subclass of SystemConnectionMemo. This will eventually do all the manager initialization, and carry any object references that used to be through instance variables.

Add all that stuff.

For each connection method (e.g. each subdirectory)

Edit the ConnectionConfig class to take and record a reference to a SerialPortAdapter object, and to return it from the getAdapter() method. Also, remove the instance() method and its implementation.

    protected void setInstance() { 
        if (adapter == null) {
            adapter = new PR3Adapter();
        }
    }

Edit the adapter class (e.g. PR3Adapter) to remove the instance() method and its implementation.

The configurexml/ConnectionConfigXml class needs to have a method added:

    protected void getInstance(Object object) {
        adapter = ((ConnectionConfig)object).getAdapter();
    }
We should probably refactor this later, but this is the current form to make sure the correct ConnectionConfig class is used. We're leaving it unchanged for now to avoid competition with the serial/network refactoring.

Also, change this

    protected void getInstance() {
        adapter = LnHexFilePort.instance();
    }
to this
    protected void getInstance() {
        adapter = new LnHexFilePort();
    }

Managers and Beans

For each manager and bean combination, you have to update them to no longer use an instance() method to access the TrafficController. Passing the SystemConectionMemo in to the Manager at construction time is the recommended approach, then if need be passing it through to the newly created Beans. That passes the prefix string, user name for tbe connection, etc.

The manager must also use the system prefix instead of a fixed, single system letter. Using e.g. '.startsWith(getSystemPrefix()+"T")' is a good approach. Don't just check that the name starts with the prefix because e.g. "L" and "L2" are not unambiguous then.

Menu

Create a swing subdirectory, if it doesn't exist already.

Put the code for making the menu there, if need be leaving a migration subclass behind. (c.f. jmri.jmrix.loconet.LocoNetMenu and jmri.jmrix.loconet.swing.LocoNetMenu for a template)

Create a ComponentFactory factory class in the swing subpackage that can e.g. create the menu, and eventually the trees, etc.

Edit jmri.jmrix.ActiveSystemsMenu to remove the class; menu creation is automatic from now on. (Every time you create and register a *SystemConnectionMemo, you also register the ComponentFactory)

Keep startup actions working

To keep things working, it's best to convert to JmriPane subclasses. Temporarily, the system connection is then created via the use of internal classes, like jmri.jmrix.loconet.locomon.LocoMonPane$Default

This does require people to reset their preferences for startup actions, buttons, etc. We're not going to migrate those for them.

To make startup actions work with more than one connection of their type, they should implement the jmri.jmrix.SystemConnectionAction interface. This will connected them to their specific SystemConnectionMemo.