In the documentation of Ember.StateManager it's said that : "Inside of an action method the given state should delegate goToState calls on its StateManager". Does it mean that if I send an action message, I necessarily need to transit to another state. Is it possible to stay in the same state but doing some task by sending an action ? For example, I'm in a state "loading" and I run two actions "preprocess" and "display".
Very simply: an action message may but does not have to transition to another state.
Something you didn't ask, but is related and important: it is a bad idea and bad design to call goToState in an enter or exit method.
When dealing with statecharts in general, you can do whatever you want. It's not mandatory to switch states in an event handler. A common case would be an event handler that shows a cancel/save dialog. You can easily put the dialog on the page in the event handler, and proceed accordingly depending on which button is pressed.
A separate question is should every event handler basically just go to another state. In the above scenario, you can certainly go to a "confirm" state, the state-enter method will show the dialog, and there would be two handlers, one for each button. Those handler would in turn go to other states.
Both design choices I think are equally valid, at least in that scenario. If you choose to implement a separate state for every action, you will end up with a lot of small but concise states. If you choose to do stuff in the event handlers themselves, your states will be bigger, but there will be less of them.
One thing I will say is if an event handler is getting complicated, you are probably better of with a new state. Also, be consistent.
For you specific scenario, if I'm reading it right, you want to load data and then change the display to show the data, based on an event. In this case, I would use new states.
So you press a button that starts the process
In the event handler, go to some sort of 'MyDataSection' state
Initial substate is 'loadData'
Enter state method of 'loadData' starts the loading process
Event handler 'dataLoaded' in 'loadData' to handle when the data loads; this means you need to fire an event when the data loads
'dataLoaded' event goes to the 'show' state
show state shows the view (or removes activity indicator etc) and handles any events that come from the display.
What's good here is that if you have multiple ways to get to this section of the app, all actions that lead to this section only need to go to this state, and everything will always happen the same. Also note that since the view event handlers are on the show state, if the user hits a button while the data is loading, nothing will happen.
Related
My application supports the IE (InternetExplorer) browser. When the back/forward buttons are clicked and there is nothing to go back or forward to, Webbrowser.GoBack() and Webbrowser.GoForward() are causing a crash.
Is there any way to know if I can go back before I actually call GoBack()? I took a look at the CWebBrowser2 class functions, but I couldn't find anything as such.
Is there any API to help on this, or any alternative approach to handle this?
Is there any way to know if I can go back before I actually call GoBack()?
Per the IWebBrowser2::GoBack() documentation:
Use the DWebBrowserEvents2::CommandStateChange event to check the enabled state of backward navigation. If the event's CSC_NAVIGATEBACK command is disabled, the beginning of the history list has been reached, and the IWebBrowser2::GoBack method should not be used.
And likewise in the IWebBrowser2::GoForward documentation:
Use the DWebBrowserEvents2::CommandStateChange event to check the enabled state of forward navigation. If the event's CSC_NAVIGATEFORWARD command is disabled, the end of the history list has been reached, and the IWebBrowser2::GoForward method should not be used.
And per this discussion thread:
Create a couple of BOOL member variables in the class that processes the
ON_UPDATE_COMMAND_UI notifications for the 'back' and 'forward' toolbar
buttons -- one for each button state. Initialize them both to FALSE in
the ctor. Handle the OnCommandStateChange event, and watch for the
CSC_NAVIGATEBACK and CSC_NAVIGATEFORWARD values in the 'nCommand'
parameter. When you get the CSC_NAVIGATEBACK value store the 'Enable'
parameter value into your BOOL member variable for the 'back' button
state. Do the same thing for the 'forward' button state variable when
you get CSC_NAVIGATEFORWARD value. In your OnUpdateButtonForward and
OnUpdateButtonBack handlers, call pCmdUI->Enable using the corresponding
button state member variable.
So, use the browser's CSC_NAVIGATE... state changes to know when it is safe to call GoBack()/GoForward()`. These are the same events that IE uses to enable/disable its own Back/Forward UI toolbar buttons.
I have two functions: myCode1() and myCode2(). I have very little control over what is in myCode1() (will be implemented by other party), it can be almost anything, within some sane limits, of course. I need to call first myCode1() and only after it is "finished" I need to call myCode2(), which implementation I have in full control. By "finished" I mean when all synchronous code is done and event loop is done processing all events which were created as the result of myCode1().
My first try was trivial:
myCode1();
myCode2();
But there is a trouble that when myCode1() opens dialog with its own event loop (QDialog::exec()), then myCode2() is called only after the dialog is closed, which is not what I need. I need to call myCode2() after the dialog gets open and is waiting for users interaction.
So my second try:
QTimer::singleShot(0, []{ myCode2(); });
myCode1();
This is slightly better because it schedules myCode2() to be processed by event loop after myCode1() does its synchronous work, i.e. after the potential dialog with blocking event loop gets opened.
But there is yet another problem. myCode1() can create lots of posted events in event queue and I need them to be processed before actually before calling myCode2(). But with the way show above, these events are queued after scheduled myCode2().
So what I would actually need is to schedule myCode2 after ALL events are done including posted events, i.e. when the event loop is empty. And it should work also in the presence of blocking dialogs etc.
I also tried QCoreApplication::processEvents() but these events can post more events and enqueue them at the end of the queue... Moreover QCodeApplication::hasPendingEvents() is marked as deprecated so it cannot help to check whether event queue is empty. Otherwise my implementation would look like this:
void myCode2()
{
while (QCoreApplication::hasPendingEvents())
{
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
}
doMyCode2(); // this would do the actual code
}
And I would schedule it with the QTimer as above. But as I wrote, hasPendingEvents() is deprecated... so I am in bad luck.
Any ideas how to achieve what I need to achieve? I hope there is some simple solution which I just overlooked.
PS: To clarify the purpose - myCode2() should inform about the state of the application. And I need to inform about "final" or "stable" state. Which means that if there are yet more events to be processed, the state is not finished nor stable. Therefore I need to process all events first, including events which were created by previous events.
I'm using ag-grid and I'd like to save the layout/state of the user. Pretty much something like this
This solution forces the user to click on the button to save the preferences ("Save state"). There is some other way/event to detect that the user changed the state of the table (in order, to me to save and avoid to force the user to click on a button for that)?
I was hopping to find some method here but i didn't..
I initially had code that listened to all of the applicable events from the grid, but ultimately, I found it easier to just save the entire grid state in the component's onDestroy method, regardless of whether anything has actually changed.
Found my answer here.
All the events are here but i prefer to add a global event:
addGlobalListener(listener) Add an event listener for all event types coming from the grid.)
Source: AgGrid javascript grid api
Let's imagine you have a fullscreen C++ desktop application that consists of several screens with each of them having a distinct function and a ViewController with appropriate models as well. For example a set of the following very simplified screens:
Quiz: The user is navigated through a set of multiple-choice questions.
Quiz Results with Statistics.
Information: The user is presented with information about a specific subject.
Menu (Quiz, Information, Exit)
Judging by the GRASP principle Information Expert, each ViewController will know best when it is finished and time to move to a new screen. Yet by the same principle, it is not the right place to decide what the next screen should actually be. In this rather simple example, one could argue it would be okay but in a more complex application, it will undoubtedly lead to duplicated code and logic as well as higher coupling and lower cohesion. There is also the problem that you would have to create the new widget and controller within the current screen's ViewController which brings all sorts of new problems and at least by the Creator principle, it is not the right choice. You would have to introduce a Factory to alleviate some of the problems, amongst other things.
So, the next logical step is to introduce an ApplicationController with the sole responsibility of managing Views and their controllers including the navigation flow from one view to the next.
This still leaves one problem wide open in my opinion: How to signal the ApplicationController that it is time to move to a different screen and hand over the control to that object properly?
One could use the Observer pattern, for example. Yet what if you have an expensive View active at the moment and want that one destroyed once the new screen is active? If the current ViewController signals the ApplicationController that the next screen should go up, it can manage everything up to the point where it would destroy the currently active screen which it cannot do because the current call comes from exactly that object. Apart from several other problems with that approach.
So my question is (and sorry for all the verbose introduction :P): How do you properly implement a navigation flow from one fullscreen widget to a different one with MVC which solves the above problems, splits the responsibility between the View- and ApplicationController and is nicely object oriented in terms of coupling and cohesion?
Sometimes you miss one detail in your thought process and you open up a whole can of problems without even realizing the mistake you made.
In this case the detail was that you can naturally post asynchronous as well as synchronous events. If you have to make sure that you are no longer in the context of the event posting method, post an asynchronous event. Once you receive that event in your handler, you can be sure that the context was left. And for example you can safely delete the object, if you so desire. Naturally the event handler should not be in the context of the same object that you are trying to delete.
For completeness: In Qt, you can specify for each signal/slot-connection you make with connect(), that it should be of type Qt::QueuedConnection. If you raise a signal, it won't be delivered until the control is back to the thread's event loop. Normally, Qt::AutoConnection is used which delivers a signal at the time it is raised (Qt::DirectConnection) if the receiver is in the same thread or falls back to queuing that signal (Qt::QueuedConnection) if the receiver is in a different thread.
In wxWidgets you can queue events with wxEvtHandler::QueueEvent(wxEvent* event) which is available through the Application singleton for example.
I'm making a game GUI and basically each Widget can have other widgets which listen to mouse or keyboard events. Anyone of these can consume the event too (and then any subsequent ones will not receive it.
The part I'm unsure for is if the order shoud be:
Send event to Target Widget
if(event is not consumed)
{
Send each listener the event
}
or
Send each listener the event
if(event is not consumed)
{
Send event to Target Widget
}
Which one makes most sense?
Thanks
The best event model I've every used is from the Tk toolkit (and I've used perhaps a dozen toolkits professionally during my career). The naive description is that the event starts from the most specific (the actual widget in which the widget occured) up a chain to the least specific (a global binding).
It's a little more complex than that, but that's the general idea, and it works extremely well. At each step in the process from most specific to most generic, each handler has the opportunity to say "I've handled this event" and to stop it from propagating. Or, it can handle or ignore the error while also letting it percolate up.
If you're rolling your own event mechanism you owe it to yourself to study Tk's "bindtag" mechanism. The default behavior is as I described, but the bindtag mechanism is much more powerful because it lets you alter the order for each widget. I've found this invaluable because, while the standard behavior works in 95% of the cases, you want to be able to support that other 5%.
I would probably use the first. It makes more logical sense to me (at least) to not send the event out unless it's not wanted.
I mean, you wouldn't send out invitations (event) to your friends (the listeners) if you cancelled the party (the original event has been consumed).