I have a State machine workflow. State Machine workflow requires EventDriven activity ,
This state needs to wait for set of two event, that is Either event (A1 or A2) And event (B1 or B2). In total there are four event handlers
In any combination, but my state should wait for at least two to be raised. I thought of using ParallelActvivity, but I cant use it directly inside state machine.
Any pointers to achieve this?
The most practical way of doing this would be to add 4 boolean variables, lets call them A1Fired, A2Fired, B1Fires and B2Fires. Now in each EventDrivenActivity set the appropriate variable and use a SetStateActivity to reactivate the same state. Finally add a StateInitialization event and check which of the variables are set and if so do whatever you need to do like switch to a next state.
Related
I want to know if there is a way to queue up accessibility readouts or element focus events one after another.
If I use either: UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, "My Error Message")
or:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.continueButton)
The second call will interrupt the readout that is currently being read.
And obviously, if you use Dispatch with Delay, it's not robust, because different languages have different lengths of content, and also the user has a different readout speed set, which may be set to very slow. So how can I "queue up" multiple focus/read out events and ensure that only one of them gets read out at a time in sequence?
After you post your first announcement you need to wait for UIAccessibilityAnnouncementDidFinishNotification (see more here) before you post the 2nd one.
So build a queue (a set could do it) and whenever UIAccessibilityAnnouncementDidFinishNotification is triggered by the system just pop the first notification in your set (if present) and fire it away.
I have a working JavaFX application. It has three main parts:
A list of signals visible globally to the entire application. Each signal has a String value property that is observable. This list is instantiated before the JavaFX scene is constructed, the signal list constructor is run in the Application FX thread.
A JavaFX table implemented as an Observable Array List so that as signal values change they are automatically updated on the GUI.
A simulation engine that runs a loop that changes signal values. This loop is run in a worker thread.
I am fully aware that GUI elements like selection lists, text in boxes, etc. can only be updated in the Application FX thread. I use Platform.runLater(someRunnableThing) to do that. However, what blindsided me was that even changing a signal value, which changes the value of the observable String property, must be done in the FX thread or not-in-Application-FX-thread exceptions will be thrown.
Curiously the application still works fine despite these exceptions, because eventually (instantaneously to a human observer) the changed value is picked up and displayed. I only noticed this when doing final checks of run-time behavior before release.
It is a very common thing for a worker thread to be changing variables in the background while a GUI is displaying information based on the changing variables. Platform.runLater() is expensive and somewhat non-deterministic. Since the worker thread is not touching the GUI and the application FX thread can choose to grab updates whenever it wants it seems draconian to me for Java to force this behavior.
Have I missed something about modifying observed properties? Any thoughts and ideas appreciated.
There are no rules about updating JavaFX properties from background threads. The only rule is that you cannot update nodes that are part of a scene graph from a background thread, and there are no plans (and likely never will be) to relax that rule.
You didn't post any code, so we can only make educated guesses as to what the actual problem is. What is likely happening is that you have a listener or a binding on one of the properties (or observable collections) that is being changed from your background thread, where the listener/binding is updating the UI. Listeners with observables (including listeners created and registered by bindings) are, of course, invoked on the same thread on which the observable is changed.
So if you have something like
someApplicationProperty.addListener((obs, oldValue, newValue) -> {
someUIElement.setSomeValue(...);
});
or perhaps
someUIElement.someProperty().bind(someApplicationProperty);
just replace it with
someApplicationProperty.addListener((obs, oldValue, newValue) -> {
Platform.runLater(() -> someUIElement.setSomeValue(...));
});
In other words, you can continue to update your application properties from the background thread, as long as your listener updates the UI from the FX Application Thread.
In the case where the listener is registered by the UI component itself, you must ensure that the observable with which the listener is registered is changed on the UI thread. This is the case in the example you allude to, for example updating the backing list for a ListView or TableView. You can do this either by directly invoking Platform.runLater(), or by placing a layer in between the model and the UI. For the latter approach, see Correct Way to update Observable List from background thread
Also maybe see http://www.oracle.com/technetwork/articles/java/javafxinteg-2062777.html
I am maintaining a project for a PLC written in ST. To implement a new feature I need to let cyclic program A know when an event happened in cyclic program B.
How is this generally done in ST? Do I simply use global variables or is there a different method? If I use global variables, how are these then protected from concurrent modification?
I use the X20 PLCs from B&R Automation.
Asynchronous communication is tricky.
So imagine a global A_DONE initialized to false, with B inspecting it occasionally. A runs, and sets A_DONE. B can react to this event... but what does it do if it needs to handle another event?
If you believe that the event that tells A to signal A_DONE occurs only long after B sees A_DONE, B can simply reset A_DONE to false (assuming this always happens before the next A_DONE event) and the cycle can repeat.
If A_DONE can occur "again" while B is handling the results of seeing A_DONE, B cannot just reset A_DONE: you might get a timing splinter in which B reads A_DONE, A sets A_DONE again and B then clears A_DONE; now you've lost an event. If that event is controlling your reactor emergency rods, this could be pretty bad because poof, B missed it.
In this case you will likely need a handshake from A to B and back. We add a signal from B back to A, call it A_DONE_SEEN, to let B tell A that it has processed the event. Then A sets A_DONE, waits for A_DONE_SEEN; A clears A_DONE, waits for A_DONE_SEEN to go false, and continues its business. If A_DONE needs to be set while A_DONE is already set, or A_DONE_SEEN is set, we know we missed an event and some disaster recovery procedure can be run. B watches for A_DONE, handles the A_DONE action, sets A_DONE_SEEN, watches for A_DONE going false, and sets A_DONE_SEEN_FALSE.
I don't know about your specific PLCs, but in many systems there are atomic operations that increment counts, etc. You could use this instead of the handshake.
Yes, you need to declare a variable that has a shared scope to both cyclic programs.
You can do this by using the existing global.var file or you can create a new variable file, and limit what programs can read or write to it by placing it within a "package" (folder in your project).
To create a new var declaration file...
-right click within the logical view
-add object
-select "file" category, and choose new file
-name, and change to "save as *.var" in the drop down
By default, the new variable declaration visibility will be limited to the package it is contained within. To verify this, right click the file and go to properties. Select the details tab.
There is no way to protect from concurrent modification, but you can use the cross reference tool to see where a selected variable is being written and read within your project. First build a cross reference, and then use the tab at the bottom.
Good luck!
I need to add an Action to a Schedule object that is being created through the API. There are documented interfaces to set almost all the options except the Action. How are Actions attached to these Objects?
When I attempt to programmatically add a new event, read from a separate configuration file, to a Schedule object I get errors stating that the Schedule has already been initialized and that I must construct a new object and add its configuration manually. I can do most of that using the available Schedule API. I can set up everything about the Schedule except the Action code.
The Schedule is used in a Process Model. Looking at the model in the Java editor, I see the code I'm trying to replicate via the API in a function that looks like this:
#Override
#AnyLogicInternalCodegenAPI
public void executeActionOf( EventTimeout _e ) {
if ( _e == _fuelDeliverySchedule_Action_xjal ) {
Schedule<Integer> self = this.fuelDeliverySchedule;
Integer value = fuelDeliverySchedule.getValue();
logger.info("{} received {} pounds of fuel", this.getName(), this.fuelDeliverySchedule.getValue());
this.fuelAvailablePounds += fuelDeliverySchedule.getValue();
;
_fuelDeliverySchedule_Action_xjal.restartTo( fuelDeliverySchedule.getTimeOfNextValue() );
return;
}
super.executeActionOf( _e );
}
Maybe I can use something like this to create my own action function, but I'm not sure how to make the Scheduled event use it.
Thanks,
Thom
[Edited (expanded/rewrote) 03.11.2014 after more user detail on the context.]
You clarified the context with
When I attempt to programatically add "a thing that happens", read
from a separate configuration file, to a Schedule object I get errors
stating that the Schedule has already been initialized and that I must
construct a new object and add its configuration manually. I can do
most of that using the available Schedule API. I can set up everything
about the Schedule except the Action code.
(You might want to edit that into the question... In general, it's always good to explain the context for why you're trying to do the thing.)
I think I understand now. I presume that your config file contains scheduling details and, when you say you were trying to "add a thing that happens" (which errored), you meant that you were trying to change the scheduling 'pattern' in the Schedule. So your problem is that, since you couldn't adjust a pre-existing schedule, you had to instantiate (create) your own programmatically, but the Schedule API doesn't allow you to set the action code (as seen on the GUI schedule element).
This is a fairly involved solution so bear with me. I give a brief 'tl;dr'
summary before diving into the detail.
Summary
You can't programmatically code an AnyLogic action (for any element) because that would amount to
dynamically creating a Java class. Solving your problem requires recognising
that the schedule GUI element creates both a Schedule instance and a
timeout event (EventTimeout) instance to trigger the action. You can therefore create these two elements explicitly yourself (the former dynamically). The trick is to reset the timeout event when you replace the Schedule instance (to trigger at the next 'flip' point of the new Schedule).
[Actually, from your wording, I suspect that the action is always the same but, for generality, I show how you could handle it if your config file details might want to change the nature of the action as well as those of the scheduling pattern.]
Detail
The issue is that the GUI element (confusingly) isn't just a Schedule instance
in terms of the code it generates. There is one (with the same name as that of
the GUI element), which just contains the schedule 'pattern' and, as in the API,
has methods to determine when the next on/off period (for an on/off schedule) occurs. (So
it is kind of fancy calendar functionality.) But AnyLogic also generates a
timeout event to actually perform the action; if you look further in the code
generated, you'll see stuff similar to the below (assuming your GUI schedule is called
fuelSchedule, with Java comments added by
me):
// Definition of the timeout event
#AnyLogicInternalCodegenAPI
public EventTimeout _fuelSchedule_Action_xjal = new EventTimeout(this);
// First occurrence time of the event as the next schedule on/off change
// time
#Override
#AnyLogicInternalCodegenAPI
public double getFirstOccurrenceTime( EventTimeout _e ) {
if ( _e == _fuelSchedule_Action_xjal ) return fuelSchedule.getTimeOfValue() == time() ? time() : fuelSchedule.getTimeOfNextValue();
return super.getFirstOccurrenceTime( _e );
}
// After your user action code, the event is rescheduled for the next
// schedule on/off change time
_fuelSchedule_Action_xjal.restartTo( fuelSchedule.getTimeOfNextValue() );
i.e., this creates an event which triggers each time the schedule 'flips', and performs the action specified in the GUI schedule element.
So there is no action to change on the Schedule instance; it's actually related to the EventTimeout instance. However, you can't programmatically change it there (or create a new one dynamically) for the same reason that you can't change the action of any AnyLogic element:
this would effectively be programmatically
creating a Java class definition, which isn't possible without very specialised
Java code. (You can create Java source code in a string and
dynamically run a Java compiler on it to generate a class. However, this is very
'advanced' Java, has lots of potential pitfalls, and I would definitely not
recommend going that route. You would also have to be creating source for a user subclass
of EventTimeout, since you don't know the correct source code for AnyLogic's proprietary EventTimeout class, and this might change per release in any case.)
But you shouldn't need to: there should be a strict set of possible actions that your config file can contain. (They can't be arbitrary Java code snippets, since they have to 'fit in' with the simulation.) So you can do what you want by programmatically creating the Schedule but with a GUI-created timeout event that you adjust accordingly(assuming an off/on schedule here and that there is
only one schedule active at once; obviously tweak this skeleton to your needs
and I haven't completely tested this in AnyLogic):
1. Have an AnyLogic variable activeAction which specifies the current active
action. (I take this as an int here for simplicity, but it's better to use a
Java enum which is the same as an AnyLogic 7 Option List, and can just be
created in raw Java in AnyLogic 6.)
2. Create a variable in the GUI, say called fuelSchedule, of type Schedule but with initial value null. Create a separate timeout event, say called fuelScheduleTrigger, in User Control mode, with action as:
// Perform the appropriate action (dependent on activeAction)
doAppropriateScheduleAction();
// Set the event to retrigger at the next schedule on/off switch time
fuelScheduleTrigger.restartTo(fuelSchedule.getTimeOfNextValue());
(Being in User Control mode, this event isn't yet triggered to initially fire, which is what we want.)
3. Code a set of functions for each of the different action alternatives; let's say
there are only 2 (fuelAction1 and fuelAction2) here as an example. Code
doAppropriateScheduleAction as:
if (activeAction == 1) {
fuelAction1();
}
else if (activeAction == 2) {
fuelAction2();
}
4. In your code which reads the config file and gets updated schedule info.
(presumably run from a cyclic timeout event or similar), have this replace
fuelSchedule with a new instance with the revised schedule pattern (as you've
been doing), set activeAction appropriately, and then reset the timeout event to
the new fuelSchedule.getTimeOfValue() time:
[set up fuelSchedule and activeAction]
// Reset schedule action to match revised schedule
fuelScheduleTrigger.restartTo(fuelSchedule.getTimeOfNextValue());
I think this works OK in the edge case when the new Schedule had its next 'flip' at the time
you set it up. (If you restart an event to the current time, I think it schedules an event OK at the current time which will occur next if there are no other events also scheduled for the current time; actually, it will definitely occur next if you are using a LIFO simultaneous-time-scheduling regime---see my blog post.)
Alternative & AnyLogic Enhancement
An alternative is to create a 'full' schedule in the GUI with action as earlier. Your config file reading code can replace the underlying Schedule instance and then reset the internal AnyLogic-generated timeout event. However, this is less preferable because you are relying on an internally-named AnyLogic event (which might also change in future AnyLogic releases, breaking your code).
AnyLogic could help this situation by adding a method to the Schedule API that gets the related timeout event; e.g., getActionTriggeringEventTimeout(). Then you would be able to 'properly' restart it and the Schedule API would make much clearer that the Schedule was always associated with an EventTimeout that did the triggering for the action.
Of course, AnyLogic could also go further by changing Schedule to allow scheduling details to be changed dynamically (and internally handling the required updates to the timeout event if it continued to be designed like that), but that's a lot more work and there may be deeper technical reasons why they wanted the schedule pattern to be fixed once the Schedule is initialised.
Any AnyLogic support staff reading?
I have two input fields which i would like to sync with each other.
Unfortunately, when I add a ChangeListener to each of the TextFields they will trigger each other,
and so create an andless loop.
Ofcourse I could unregister the Listeners, on every change and them put them back,
but is there any Java native approach?
Maybe something with bindings?
From general reasoning (i.e. not knowing swt or java): you can add a boolean flag (probably your class member) m_enteredChangeListener, temporary setting it to true in one of your handlers (not both), making the same handler do nothing if it's reentered recursively.