How does Action Pin work in simulation of an Activity Diagram in Enterprise Architect? - enterprise-architect

I am going through the tutorial for Model simulation of Enterprise Architect. In the Dynamic Simulations, under section of CreateObject, it says that the Output action pin stores the created object and can be passed via an object flow to another action. The attributes of the created object can be then accessed in the destination action. See EA Help and
Breakpoint 1: A CreateObject Action creates an Object ´cb´ and the local variable
Breakpoint 2: The created object passed to Action3 via an object flow in action pins, the control is passed with control flow.
However, as you can see that the object cb is nowhere to be seen in Action3. I would really appreciate if someone can help me in this and explain how it works.

So, I tried a lot of things to do this. And I somehow figured out a way to do part of it. So here is the answer.
Pre-Requisite: A class with a few attributes and operation. Along with the behavior of the operation to be performed. Like in the below example, following is the behavior defined for add operation.
this.x=x;
this.y=y;
return x+y;
Steps:
Create a CreateObject Action Element (Toolbar (space) > Action > Create Object).
In element properties (docked) set the Classifier. (Properties > Element tab > CreateObjectAction section > Classifier > {Class, Actor, Activity}).
The CreateObject has a 'result' ActionPin. Drag the ActionPin to the diagram from the browser on the CreateObjectAction Element.
Assign the ActionPin(result) of type as the classifier object from Element Properties of ActionPin.
Add an object flow to a new action or the destination action, on which the object is being passed.
Follow step 4 for the new action pin generated.
Add the control flow from the create object to a destination action(might be same or different than the action of Step 5).
Drag the Class to the activity diagram and create it's instance with a unique name. (IT'S STRANGE THAT WE NEED TO DO THIS, BUT IT DOESN'T WORK WITHOUT THIS)
Finally after completion of diagram. We can perform simulation. The newly created object can be seen in the Local window as UID.
This is the created object which can be used to access the operation and the attributes of instance. In order to do this, copy this name and use it in the effect field of action.
this.result = DFB9AEAD91_990D_4cec_AE54_93A8A3BC684F.add(7,7);
The output then can be seen in the local window.
NOTE: The object "cb" is still nowhere to be seen. However, an object is definitely created with a unique id as shown in the above code snippet. A part of the question still remains unanswered is the role of action pins.

Related

Accessibility of main from agent's statechart

May I know if main is accessible to all elements in the model?
The reason I ask is that I have created a simple M/M/n model with one resource type created through ResourcePool. The behaviour of the resource type is implemented using a statechart. I write a simple code in the action of a transition in the statechart, i.e.
if (agent_variable < main.my_parameter) { /* do something */ }
The code does not compile and give an error message "main cannot be resolved to a variable". I cannot figure out why the statechart cannot recognise main.
Thanks
Welcome to SOF, Stephan.
First, always use code-complete (Ctrl+space). You will then see what is and what is not possible to access from where you are. In your case, main would not even be an option :-)
Now, your model root (typically that is main) is always accessible via getModelRootAgent() but you will need to cast it to your Main class, i.e. ((Main)getModelRootAgent())
Otherwise, Main is accessible to all agents that are somehow embedded into Main. This is classic OOP principles. Your Resource agents are not actually an embedded population so no direct access to Main. (You can make that happen in the ResourcePool properties, though)

Anylogic: Declare parameter of type ArrayList

I'm building a class (sorry - Agent) that will work with a set of Tank objects (Fluid Library) - doing things like monitoring individual levels or total level of all tanks, reporting on levels and initiating actions based on levels - things of that nature. For argument's sake let's call it a "TankMonitor" agent.
Ideally I'd like to be able to define a Parameter in my "TankMonitor" agent that allows me to define the tanks of interest when I place a TankMonitor in main. I have tried to define the type of the parameter as Other - ArrayList<Tank> however I don't know how to set up the next step to allow me to populate the ArrayList of Tanks when I put an instance of this agent in main. My preference would be to have a list type control to populate the ArrayList - much like the way the AnyLogic Seize block allows you to specify multiple resource pools to choose from.
Has anyone attempted this before and been successful?
This is possible as follows:
Change the type to "Other" and then 'Tank[]' , i.e. an Array of Tanks
Change the control type to "one-dimensional array"
Example below. Now you have the same UI to pre-define tanks at design time for your agent instance.
In addition to Benjamin's perfect answer, I'd just add the manual workaround, which is not needed here but can be useful when the parameter in question has a more complicated structure than covered by the pre-made controls, say a list of lists, a map, or similar.
In such a case, the Control Type is still Text, and populating it in an instance happens by pointing it to a new object of the parameter's type. E.g. for an ArrayList<Tank> parameter, you might instantiate a new ArrayList object, which you fill with a list of objects like so:
new ArrayList<Tank>(Arrays.asList(tankA, tankB))
In the Java code, whatever is written into that text box will end up on the right side of a parameter assignment statement in the embedded Agent instance's auto-generated parameter setup function. Therefore, multi-statement code won't work in this spot. Instead, if the process of building the parameter value doesn't fit neatly into a single expression, you can hide the code in a function which returns the desired object, and call that from the parameter's text box.

Implement the Lead conversion using custom button

I will need to create a Custom Button "convert lead" that will perform the same functionality as Standard Button "Convert" when the button is clicked.
What is the best approach to do it..?
That's a very broad question. What exactly you need, what have you tried so far? Do you really need just a button that opens the conversion page or something more?
If you want to somehow recreate it with Apex... Core of the coded solution would be the Database.convertLead method. You don't pass to it whole leads (like to Database.insert for example) but instead just their IDs + bunch of control flags to make it do exactly what you need. Read up about LeadConvert object. And similarly you can get Account/Contact/Opportunity ID from the result object if it succeeded.
I don't think there's programmatic way to access field names & mappings defined by administrator for lead conversion. Maybe you'd need to store this info somehow (in helper object? custom metadata?). So then you'd query the field names from metadata, then query the lead fields and finally display table of fields & mappings to the user.

Does UI5 Remember's previous entity

I am building simple crud for an entity. Initial state is read on particular entity(key) using view>form.bindElement('/entity(key)').
when I click on new button I clear the form and when the cancel button is clicked during the new/create process(without performing the save), how to go back to the previous entity. Is there some place ui5 stores, the previous entity or should I have some variable and assign it to the controller.previousEntity = oldsPath?
what are the different members in the oModel,it start with
a(aBindings)
b(bUseBatch)
m(mContexts)
o(oHeaders)
p(pCallAsync)
s(sPathUrl).
Is there a naming convention in these?
From what I can see, there are following things you need to notice and work upon.
Its generally not a good idea if you use the same form to display and to create/update also. A simpler approach would be to
use a new popover to show the form for create and in that case, the view binding would not be changed when you cancel the operation.
However, if you still want to use the same form, yes you would have to bind the view/form again on cancel operation. You can have a variable declared in the Component.js to store the path for you. In UI5, the model captures the current state to ensure the back the binding concept by default.
You can check all properties and their definitions here: oData Model
Yes, there is a naming convention followed here.
a - Array, s-String, b- Boolean etc.
Read more about Hungarian notations for naming conventions
The previous entity is still there in the cache (ODataModel.oData), but you'll need to re-bind it. For that purpose, as you have written, you'll need to store the path to the entity yourself. Once you bind the control, I don't think the previous binding context is stored somewhere (why should it).

Accessing om.next sub-component state

I'm just picking up om.next and have run into a situation where I've got some form inputs realized as components which hold on to local state, e.g. validation state, actual input value, etc--this state is updated and accessed via om.next/update-state! and om.next/get-state. The trouble with this seems to be when I wrap the inputs in a form in a parent component I'm unsure how to get the state held by the input components. Is it better to pass along the parent component as a property of the input component? What about situations where there is no parent component?
It seems to me that there are 2 options for the use case you want to achieve:
pass the parent component as an argument as you said
have an entry in the global app-state that represents the current form being edited, which you can update via transact! irregardless of the component corresponding to the input. This way every component that represents an input knows where in the app-state to update itself (which key in the current form) — probably captured succintly in one mutation function.
1) is probably the easiest to implement given the code you have currently, but I always like to go for 2) because it doesn't deviate from the "single source of truth" opinion that Om Next recommends (and tries to enforce). Form data is in fact business data, which might not be desirable to have scattered in components. Testability is just one advantage that I immediately see from such approach.