Delegate Classes

There are many different ways to create a delegate, depending on the level of custom functionality you want to implement. In fact, if you do not provide any code at all, Moxie will attempt to implement the following behaviors for you when you run your simulation:

  • Java Property methods to represent the state of SysML object properties in the simulation
  • Assignments for slot values provided in an Instance Specification by using wire-up initialization
  • Implementations for operations that do not perform actions and return default values
  • Support for call events resulting from executing operations

If this is good enough for your simulation, you do not need to write a single delegate. As a matter of fact, you do not even need a delegate module. Moxie will handle everything for you as is, right out of the box. Please see Auto-Implementation to learn more.

If you are using an analysis tool, you will want to create some custom delegates to interact with it. You can do as much or as little as you need, and Moxie will attempt to fill in the gaps for you with appropriate defaults.

To get started writing a delegate, the first thing you need to do is create a Java class or interface to represent the block that owns the properties and operations to be implemented. Often, creating interfaces that represent only the elements that exist in the SysML block can be useful to maintain the abstraction between the formal model and the code executing it. An interface also helps cases where there is more than one implementation for a particular block. Different implementations may be used and maintained for different simulations or analysis tools.

Let's take a look at Figure 1 and Figure 2, which show the properties and operations of the balloon operator from the hot air balloon ride example.

Figure 1: The balloon operator properties

Figure 2: The balloon operator operations

The names of the properties and operations contained in the interface or class for your delegate must align with those in the corresponding block. Fortunately, you do not have to do this by hand. Moxie provides a utility to generate interfaces and classes for you that you will simply need to implement. See Delegate Code Generation .

Figure 3 shows the interface representing BalloonOperator.

package com.agi.moxie.samples.balloonride.structure;

import com.agi.moxie.api.annotations.DelegateFor;
import com.agi.moxie.api.models.Property;
import com.agi.moxie.delegates.base.FixedDuration;
import com.agi.moxie.delegates.base.Thing;
import com.agi.moxie.delegates.core.FixedScalarValue;

import java.lang.Boolean;

@DelegateFor("Structure::BalloonOperator")
public interface BalloonOperator extends Thing {
  Property<FixedDuration> maxFlightDurationProperty();

  Property<FixedScalarValue> targetAltitudeProperty();

  Property<FixedScalarValue> launchPadAltitudeProperty();

  Property<Boolean> isOperatingProperty();

  Property<Passenger> passengerProperty();

  Property<Balloon> balloonProperty();

  void sendLandedSignal();

  Passenger getNextPassenger();

  void launch();

  void land();

  void sendBuckleUpSignal(Passenger target);

  void sendReadyForPhotoSignal(Passenger target);
}

Figure 3: The balloon operator delegate interface

In Figure 3, take note of the @DelegateFor annotation on the interface. There you will see the qualified name of the block represented by this interface. Next, you will notice the interface extends Thing, which corresponds to the block's generalization of Moxie-Base::Structure::Thing from the Moxie model libraries. Finally, take a look at the Java methods and compare them to the properties and operations in Figure 1 and Figure 2. You will notice that all of the SysML properties are represented in Java with their name followed by "Property" as a convention to indicate they represent a model property. Aside from the "Property" suffix, the properties in the interface are spelled exactly the same as they are in the block. However, if there are any characters that are illegal for Java identifiers, they will be replaced with an underscore. Operations do not have a prefix or suffix, and their spelling and casing in the interface are identical to the block. For more details on properties and operations, see Properties and Operations.

Now let's look at the implementation of the BalloonOperator interface in Figure 4, namely BalloonOperatorDelegate.

package com.agi.moxie.samples.balloonride.structure.impl;

import com.agi.moxie.api.StateMachineRemoteControl;
import com.agi.moxie.api.annotations.AutoDelegateImplementation;
import com.agi.moxie.api.annotations.DefaultDelegate;
import com.agi.moxie.api.annotations.InjectByName;
import com.agi.moxie.samples.balloonride.structure.BalloonOperator;
import com.agi.moxie.samples.balloonride.structure.Passenger;

@AutoDelegateImplementation
@DefaultDelegate
public abstract class BalloonOperatorDelegate implements BalloonOperator {

    private final StateMachineRemoteControl mStateMachineRemoteControl;

    public BalloonOperatorDelegate(@InjectByName("stateMachineRemoteControl") StateMachineRemoteControl stateMachineRemoteControl) {
        mStateMachineRemoteControl = stateMachineRemoteControl;
    }

    @Override
    public void sendLandedSignal() {
        this.land();
        mStateMachineRemoteControl.sendSignalEventToSelf("Structure::BalloonOperator::Landed");
    }

    @Override
    public void sendReadyForPhotoSignal(Passenger target) {
        mStateMachineRemoteControl.sendSignalEvent("Structure::Passenger::ReadyForPhoto", target);
    }

    @Override
    public void sendBuckleUpSignal(Passenger target) {
        mStateMachineRemoteControl.sendSignalEvent("Structure::Passenger::BuckleUp", target);
    }

}

Figure 4: The balloon operator delegate class

As you can see in Figure 4 above, a Java delegate class contains several key components:

  • Java Annotations - These provide Moxie with instructions on how to instantiate and configure simulation runtime instances. If the class does not include the @DelegateFor annotation, it should at least implement an interface or another base class that does.
  • Injection constructor - This is the constructor on a Java delegate. The injection constructor is responsible for injecting instance specification slot values and runtime dependencies into a delegate runtime instance's private fields.
  • Java Property methods - These correspond to block properties.
  • Java methods - These correspond to block operations.

See the following topics for more detail about these components: