Enterprise Architect: Refering to An Instantiated Class's Attribute in a State Transition - enterprise-architect

In Enterprise Architect, I have a class defined with an attribute which is an enum. Is it possible to create a transition in a state machine based on a test of that enum's value? How?
I find the only way to create transitions with triggers or signals very limited.
My intent is to export the state machine to a requirements document. Although, I would think this should work with simulation.

A trigger is what causes a token to flow along a state transition. Take for example this state transition:
When you open the properties of the transition you see
Now you can add a trigger by clicking the ellipsis right to Name:. Here you either select an existing trigger or you create a new one on the fly.
The trigger type can be selected from the drop down:
Signal is the default and you can choose one from the ellipsis right to the Specification:. You can model the signal like this:
and you would describe in it's note that (e.g.) it fires whenever the enumeration changes.
The diagram does not show the use of the signal, but it's hidden in the connector's properties. To visualize that you could add appropriate notes and link them up to connector and elements:
Note: state machines are modeled for classes (and you usually put them inside the class). If you instantiate that class the instance will also have that state machine which can run as some kind of code inside the instance.

Related

Dynamically access state while integrating (python)

I am integrating a system using scipy's odeint.
I would like to access the state during integration, and use it in the next step in the integration to modify the state accordingly.
More specifically, I want to take a dot product of the previous state and current state, and if it satisfies a certain condition I may want to alter the current state. This has effect on the next step of the integration, etc...
I am not sure how I can do this. That is, I want to dynamically access my state during the integration routine and modify it accordingly.
EDIT: In MATLAB there is an argument "outputFcn" which might be useful. I am essentially looking for an outputFcn type solution in Python.

Enterprise Architect: Setting run state from initial attribute values when creating instance

I am on Enterprise Architect 13.5, creating a deployment diagram. I am defining our servers as nodes, and using attributes on them so that I can specify their details, such as Disk Controller = RAID 5 or Disks = 4 x 80 GB.
When dragging instances of these nodes onto a diagram, I can select "Set Run State" on them and set values for all attributes I have defined - just like it is done in the deployment diagram in the EAExample project:
Since our design will have several servers using the same configuration, my plan was to use the "initial value" column in the attribute definition on the node to specify the default configuration so that all instances I create automatically come up with reasonable values, and when the default changes, I would only change the Initial Values on the original node instead of having to go to all instances:
My problem is that even though I define initial values, all instances I create do not show any values when I drag them onto the diagram. Only by setting the Run State on each instance, I can get them to show the values I want:
Is this expected behavior? Btw, I can reproduce the same using classes and instances of them, so this is not merely a deployment diagram issue.
Any ideas are greatly appreciated! I'm also thankful if you can describe a better way to achieve the same result with EA, in case I am doing it wrong.
What you could do is to either write a script to assist with it or even create an add-in to bring in more automation. Scripting is easier to implement but you need to run the script manually (which however can add the values in a batch for newly created diagram objects). Using an add-in could do this on element creation if you hook to EA_OnPostNewElement.
What you need to do is to first get the classifier of the object. Using
Repository.GetElementByID(object.ClassifierID)
will return that. You then can check the attributes of that class and make a list of those with an initial value. Finally you add the run states of the object by assigning object.RunState with a crude string. E.g. for a != 33 it would be
#VAR;Variable=a;Value=33;Op=!=;#ENDVAR;
Just join as many as you need for multiple run states.

Execution of triggers for initial state in state machines in MDriven

I am defining a state machine and would like to have the machine to "run" when the object is created. With that in mind I left out the triggers on all the transitions (and only defined guards). It seems though that a created object stays in the first state if not triggered further? How can I avoid having to call the trigger explicitly? If I do execute a trigger, all subsequent states are passed by that (one) trigger call? Is there something "special" with the first state?
The first state is special in not needing a trigger. The transition from start-state is executed on object creation.
To mimic the behavior you are looking for you can use the same trigger method on all other transitions. These transitions are guarded so that only 1 transition is valid at a time. But you will need to actually execute this single trigger to make anything happen.
You can now check if triggering is possible and if so trigger by this pseudo code:
if self.trigger? then self.trigger

Pass complex object through controllers (core data)

I am completely lost.
The problem is passing data through viewcontrollers in my wizard.
My project contains 4 viewcontrollers:
Step1ViewController, possibility to fill in name
Step2ViewController, possibility to fill in nickname
Step3ViewController, possibility to fill in emailaddress,
Step4ViewController, possibility to fill in interests, finish
All viewcontrollers are pushed to a navigation controller. It's possible to go to the next step by clicking the bar button on the navigationtoolbar. What I want to achieve is to collect all the data in the steps and create save a NSManagedobject in the last step (by clicking the finish button). So when an user quits in step 2 and he restarts the app, there should be no saved object. So he will restart the wizard. When there is a personobject in core data then another view is loaded (this is a condition in the delegate class)
I know when you have a simple model schema passing data can be easily done to the controllers by using the prepareForSegue method. Collect all variables and create and save a core data object. For passing data back to the previous step I can use protocols.
But in my application my model schema is way more complex. My wizard contains about 18 steps and there are a lot of assiociated models for the Person model (like trainingsplan, interests, etc.) so I think collecting all data in variables and combine them all in the last step is really not a good approach.
What is the best way to do this?
I uploaded a wizard sample application with a couple of steps and 2 models (Person and interests (one-2-many)). Hopefully this will make it more clear. Feel free to modify the code: https://github.com/stalkert/WizardPrototype
Two ideas come to mind - each has their own pros and cons. Both use the concept of a mutable dictionary that will hold all the various data that you need at the end. In addition, you will add a key='step' with an NSNumber object.
1) Assuming that all the view controllers do not exist initially, he first controller creates the dictionary, adds the data it should supply to it, and sets the 'step' to two. It then creates and runs a new viewController, passing the dictionary off to it in a property. The second verifies the step is correct, adds what it should, then passes it to another controller. The 'step' here acts as a test that in fact the dictionary is at the stage it should be.
2) Assuming the view controllers are already instantiated then use the same 'step' concept as above, but use notifications. When the first step is complete, either store the dictionary in defaults, a class or singleton object, or the appDelegate (in a property). Send out a notification - and add a userInfo that is either the full dictionary or a number providing the next step. The controller that should do step 3 can see that its turn is up so it should become active (switch a UITabBarController tab automatically etc).
In either case, when the last step is complete, send the dictionary to the class managing the repository or do it directly.

How to make an InArgument's value dependant upon the value of another InArgument at design time

I have a requirement to allow a user to specify the value of an InArgument / property from a list of valid values (e.g. a combobox). The list of valid values is determined by the value of another InArgument (the value of which will be set by an expression).
For instance, at design time:
User enters a file path into workflow variable FilePath
The DependedUpon InArgument is set to the value of FilePath
The file is queried and a list of valid values is displayed to the user to select the appropriate value (presumably via a custom PropertyValueEditor).
Is this possible?
Considering this is being done at design time, I'd strongly suggest you provide for all this logic within the designer, rather than in the Activity itself.
Design-time logic shouldn't be contained within your Activity. Your Activity should be able to run independent of any designer. Think about it this way...
You sit down and design your workflow using Activities and their designers. Once done, you install/xcopy the workflows to a server somewhere else. When the server loads that Activity prior to executing it, what happens when your design logic executes in CacheMetadata? Either it is skipped using some heuristic to determine that you are not running in design time, or you include extra logic to skip this code when it is unable to locate that file. Either way, why is a server executing this design time code? The answer is that it shouldn't be executing it; that code belongs with the designers.
This is why, if you look at the framework, you'll see that Activities and their designers exist in different assemblies. Your code should be the same way--design-centric code should be delivered in separate assemblies from your Activities, so that you may deliver both to designers, and only the Activity assemblies to your application servers.
When do you want to validate this, at design time or run time?
Design time is limited because the user can use an expression that depends on another variable and you can't read the value from there at design time. You can however look at the expression and possibly deduce an invalid combination that way. In this case you need to add code to the CacheMetadata function.
At run time you can get the actual values and validate them in the Execute function.