With boost::msm eUML, if I give attributes_ << to the state machine or state, how do I (re)set them? - boost-msm

If I add attributes to an event, I know I can then use the event name like a function...
BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(*someEvent*, *someAttributeList*)
someStateMachine.process_event(
someEvent (
valueOfSomeAttribute1, // sets the attribute value here
valueOfSomeAttribute2))
and that inside an action I can this back by writing
evt.get_attribute(someAttribute1); // retrieve the attribute value
Now, if I set an attribute for an entire machine, like so:
BOOST_MSM_EUML_DECLARE_STATE_MACHINE((transition_table,
init_ << initState,
Entry_Action,
Exit_Action,
attributes_ << someAttribute1 << someAttribute2,
configure_<< someConfigurationStuff ),
newStateMachineType)
How do I go about setting a value for someAttribute1?
Same question for states:
BOOST_MSM_EUML_STATE(
(someEntryAction,
someExitAction,
attributes_ << someAttribute1,
configure_<< someConfigurationStuff)
,newStateName)
How do I go about setting a value for someAttribute1?
Finally,
Is there a way to change the attributes after the object is created?
For instance, I'd like to have an attribute for the state machine, and in one of my states, remember some piece of information that I can store in the state machine. (In this case, I want to store a socket.)
Thanks.

How do I go about setting a value for someAttribute1?
You can:
change the reference you just got (get_attribute returns a reference): ++evt.get_attribute(someAttribute1).
use the functors to write the attribute in your table directly. For example, following action is possible: /++fsm_(someAttribute1)
For states, you can do the same. And for state machines, well, ditto.
Again, you can either use the Fsm template parameter in your actions, or the functors (fsm_, event_, etc.)
You can find good example of all in the examples or tests (for example test/CompositeEuml.cpp or test/AnonymousEuml.cpp).
HTH,
Christophe

Related

CAPL on sysvar_change procedure with sysvar of custom struct data type

according to the manual,
The procedure on sysVar is called only when the value of the variable
changes. It can also be written as on sysVar_change. If you want to be
notified of value updates to the variable which don’t change the
value, you should use on sysVar_update instead.
In my example scenario, I have a system variable s::sysv of custom Struct Data Type X, where X has two fields: A and B.
In my CAPL script I put the following:
on sysvar_change s::sysv.A
{
// do stuff
}
Expected output is to do stuff only when s::sysv.A changes. However, since s::sysv.B is often updated when my simulation is running, then the procedure on sysvar_change s::sysv.A is called a lot more times than I expect, even if A doesn't change its value.
I don't understand why, and I'm putting a lot of workaround in place to avoid this, can anybody help?
Edit:
according to one reply, the event handler is not the struct element, but still the variable. However, the keyword this is now pointing to the struct element and not to the variable.
This bit of the manual is also relevant:
You can also react in the same way to value changes of specific
elements of a system variable of type struct or generic array. For
this, add the element to the name of the variable.
I have tried this functionality in the latest CANoe and it works as expected. The following is my code.
on key 'a'
{
#sysvar::Var_Struct1.StructMem1++;
}
on key 'b'
{
#sysvar::Var_Struct1.StructMem2++;
}
on sysvar_change Var_Struct1.StructMem1
{
write("StructMem1 value changed");
}
on sysvar_change Var_Struct1.StructMem2
{
write("StructMem2 value changed");
}
Whenever I press the key 'a' or 'b', the corresponding event is triggered.
Your variable is s::sysv. The event handler is called whenever the value of the variable changes. No matter whether A or B changes.
There is no way to restrict it only to certain changes of the value.
This is similar to the fact that you can also not be notified when, e.g. only the 3rd bit of an integer changes.
To me, it seems best to reconsider your setup and ask yourself, whether using the struct is the right approach, or whether it might be better to use two separate system variables A and B.

DOORS DXL issue looping through a filtered dataset

I have a script in which I filter the data in a module by a certain attribute value. When I then loop through these objects, for now, I am displaying the absolute number of the objects in an infoBox. However, the script is displaying absolute numbers of objects that are not in the dataset. Upon further investigation, I found that the extra absolute numbers were for each table within the entire module. I can't figure out why the script would include these tables when they are not in the filtered module data. I have even tried manually filtering the module on this attribute value then use the "Tools -> Edit DXL" to loop through the resulting items and it still displays the numbers for the tables that are not included. Why would it do this?
Here's my code:
bm2 = moduleVar
Filter fltr = contains(attribute "RCR_numbers", sRCRNum, false);
filtering on;
set(bm2, fltr);
for oObj in document(bm2) do {
absNum = oObj."Absolute Number";
infoBox("Object #" absNum ".");
}
I have also tried removing the document cast so it says "for oObj in bm2 do" instead, but this doesn't change the output. Why is the code giving me objects that are not in the filter? Any help would be greatly appreciated since this is a high priority issue for my project and I'm out of ideas myself.
Chris
In the DOORS 9.6.1 DXL Reference Manual you can see that:
for object in document
Assigns the variable o to be each successive
object in module. It is equivalent to the for object in module loop,
except that it includes table header objects, but not the row header
objects nor cells.
So, you must either use for object in module or, within your existing loop, test the hidden attribute TableType - this will be set to TableNone for anything that is not part of a table, table headers included.

How to link Dynpro screen elements to program variables?

I am trying to use the elements I made in Screen Painter in my source code but I am not quite sure how to link them. Can you provide steps how I can link my elements in Screen Painter with ABAP variables?
The connection is established via the name.
If you declare a variable in your report like this:
DATA foo TYPE c.
Then you can view it on your screen by adding a field called foo.
A useful feature of the screen painter is choosing dictionary/program fields. You can access it by pressing F6.
The reference is made by the name of global variables.
You may - as already mentioned - use a DATA matnr TYPE MATNR. to create a global variable matnr.
If you use DDIC-structures or tables you may also define them as
TABLES: MARA.
In screen painter you can reference the fields of the table/structure MARA.
(You can replace MARA with any table/structure).
Depending on the complexity of your program you may define your own structure, just as a interface between the report code and the screen-painter.
The variables used in screen painter should be declared in a TOP in order to be accessed from the includes in the program.
For example, in my screen I request for a Business Partner name and map it to GT_NAME. GT_NAME should be declared in the TOP with something like the code below:
DATA: GT_NAME type bu_first.
That automatically creates the link between the global variables and the input parameters in the screen.

How do I pass a can.compute into a can.Component?

How can I pass computes into components, such that changing the value in selected in one component will affect a value in a different component.
Example
http://jsbin.com/feleko/1/edit?html,js,console,output
I'm trying to set it up so that selecting a value in the first select changes the options available in the second. I think listening for dom change events should be straightforward, but I don't seem to be getting a compute I can update, or have access to the parent scope in order to use an attribute name to update it. Likewise the max value isn't an active object that receives updates.
I've found an obtrusive way. can.mustache provides a data helper that puts the current context on the element's data.
<select {{data 'context'}} value="a">
Then in the init event I can capture the element data and assign it to the scope so it's available to scope functions.
events: {
init: function(el, opt) {
opt.scope.context = el.data('context')
}
}
Looking up values is then possible if awkward.
this.context[this.attr('value')]

In Local Datastore chapter, fromPin and fromlocaldatastore

Just like as title, I want to ask what difference between
fromPin()
and
fromLocalDatastore()
By the way, Pin and datastore two terminologies. What difference between two of them ?
Thanks.
There is a slight difference and you can see it from the docs and from the decompiled code of the Parse library (okay, this last one is more complicated...).
The docs says:
fromLocalDatastore(): Change the source of this query to all pinned objects.
fromPin(): Change the source of this query to the default group of pinned objects.
Here you can see that, interally on Parse, there is a way to get all the objects from the entire set of pinned data, without filters, but also from a so-called "default group". This group is defined in the Parse code with the following string: _default (o'rly?).
When you pin something using pinInBackground, you can do it in different ways:
pinInBackground() [without arguments]: Stores the object and every object it points to in the local datastore.
This is what the docs say, but if you look at the code you'll discover that the pin will be actually performed to the... _default group!
public Task<Void> pinInBackground() {
return pinAllInBackground("_default", Arrays.asList(new ParseObject[] { this }));
}
On the other hand, you can always call pinInBackground(String group) to specify a precise group.
Conclusion: every time you pin an object, it's guaranteed to be pinned to a certain group. The group is "_default" if you don't specify anything in the parameters. If you pin an object to your custom group "G", then a query using fromPin() will not find it! Because you didn't put it on "_default", but "G".
Instead, using fromLocalDatastore(), the query is guaranteed to find your object because it will search into "_default", "G" and so on.

Resources