Im using RobotLegs and Signals for my application. This is my first time using Robotlegs, and Im using Joel Hooks Signal Command Map example here
I've noticed that it seems quite verbose in contrast to events. For every Signal I have to create a new class, whereas with events I would group event types into one class.
I like how visually and instantly descriptive this is.. just browsing a signals package will reveal all app communications. Although it seems quite verbose to me.
Are other people using this, Is the way I'm using signals like this correct, or have people found a way around this verboseness?
Cheers
It's the correct way though. The major advantage of signals is you can include them in your interface definitions, but obviously you'll end up with a big pile of signals.
In general I use signals only for my view->mediator and service->command communication (1-to-1). For system wide notifications I use events (n-to-n). It makes the number of signals a bit more manageable.
But it's a matter of preference obviously.
Using a good IDE and/or a templating system alleviates a lot of the "pain" of having to create the various signals.
You do not have to make a new signal class for Command maps, its just good practice. You could just give the "dataType" class a type property - and do a switch on that. But that would be messy for commands. But note, Commands are basically for triggering application wide actions.
Not all signals trigger application wide actions.
For instance, if you are responding to a heap of events from a single View. I suggest making a Signal class for related "view events" (e.g. MyButtonSignal for MyButtonView) and give it a type property.
A typical signal of mine will look like:
package {
public class MyButtonSignal extends Signal {
public static const CLICK:String = 'myButtonClick';
public static const OVER:String = 'myButtonOver';
public function MyButtonSignal() {
super(String, Object);
}
}
}
Dispatch like so
myButtonSignal.dispatch(MyButtonSignal.CLICK, {name:'exit'});
Listen as normal:
myButtonSignal.add(doMyButtonSignal);
Handle signal like so:
protected function doMyButtonSignal(type:String, params:Object):void {
switch(type) {
case MyButtonSignal.CLICK: trace('click', params.name);
break;
case MyButtonSignal.OVER: trace('OVER', params.name);
break;
}
}
Occasionally its useful to give the data variable its own data class.
So everytime you realise "Aw shit, I need to react to another event", you simple go to the Signal and add a new static const to represent the event. Much like you (probably?) did when using Event objects.
For every Signal I have to create a new class, whereas with events I
would group event types into one class.
Instead of doing that you could just use the signal as a property… something like:
public var myCustomSignal:Signal = new Signal(String,String);
You can think of a signal as a property of your object/interface.
In Joel's example he's using signals to denote system level events and is mapping them with the robotlegs SignalMap which maps signals by type. Because they are mapped by type you need to create a unique type for each system level signal.
Related
I am trying to design a preferences panel for my multidocument app. When a given pref changes – font size, say – all of the document windows should immediately update to reflect the new pref value. I don't want to construct the preferences panel up front, for all the document windows to connect to, because it contains a QFontComboBox that takes more than a second to set itself up (ouch); that's not a price I want to pay at startup. So then, my question is: what is an elegant design for the prefs panel to let all the document windows know about the change? In Cocoa, which I'm more used to, I'd use NSNotification to broadcast a notification from the prefs panel that all the document windows could observe; that provides the loose coupling required (since objects can add themselves as observers before the broadcaster exists).
Two approaches occur to me so far:
Loop through topLevelWidgets, do a dynamic cast to my document window class, and for all the document windows I thereby find, just call a hard-coded method on them directly.
Make a second class, PreferencesNotifier, that is separate from the UI object that takes so long to load, and construct a singleton object of this class at startup that all of the document windows can connect themselves to. When the preferences panel eventually gets created, it can send signals to slots in PreferencesNotifier, which will then call its own signals to notify the connected document windows.
Neither seems quite as elegant as NSNotification, and I'm wondering if I'm missing something. Thanks for any tips.
First thing, do not try to copy patterns, like Cocoa's NSNotification/NotificationCenter, to other frameworks (or languages, or...). There are various ways to send messages and generally each framework has picked one. Trying to use the one method that was picked by the framework you are using will lead to the most elegant solutions.
If you really want to, you could implement your own set of classes that will do exactly what NSNotification does. It will feel more elegant to you, but only because you are used to using Cocoa. It will feel odd to every other Qt developer. Also, this solution will require you to write a lot of code as you will not be able to leverage all the features of Qt.
The first solution you are suggesting is a bit ugly and looks more like a hack than anything.
What I do, when I have to handle preferences in a program, is something similar to your solution 2. I create a class that is responsible for handling all settings: read/write setting file, change setting, set default values, etc. Generally this class is a singleton. This class has very limited access to other parts of the program, and generally no access at all to the UI. Each components that needs to access the preferences will use this class. If you do it properly (e.g. use Q_PROPERTY), this class can even be accessed by QML, if you ever need to use Qt Quick.
class Settings: public QObject {
Q_OBJECT
Q_PROERTY(bool showX READ showX WRITE setShowX NOTIFY showXChanged)
public:
bool showX() const { return m_showX; }
void setShowX(bool show) {
if (show == m_showX)
return;
m_showX = show;
emit showXChanged(m_showX);
}
signals:
void showXChanged(bool);
public slots:
void save() const; // Save to disk
void load(); // Load from disk
private:
QSettings m_settings; // Handle load/save from/to disk
bool m_showX;
};
class Window {
Window() {
...
m_widgetX->setVisible(settings->showX());
connect(settings, &Settings::showXChanged,
this, [this](bool show) { m_widgetX->setVisible(show); }
);
...
}
};
class PrefWindow {
PrefWindow () {
...
ui->checkBoxShowX->setChecked(settings->showX());
...
}
private slots:
void on_saveButton_clicked() {
settings->setShowX(ui->checkBoxShowX->checked()):
settings->save();
}
};
I am writing a program that needs to detect the difference between a long air-tap-and-hold vs. a quick air tap. Currently, I am using the following code to detect quick airtaps:
#region IInputClickHandler
public void OnInputClicked(InputClickedEventData eventData)
{
// stuff being done is coded here
}
#endregion IInputClickHandler
which works well, but is there a similar code to detect long taps? Thanks in advance.
There are a number of ways of detecting a hold. For just a generic hold gesture, you can inherit and use the IHoldHandle interface. If you want to get an updated state, you should either use the IManipulationHandler or the INavigationHandler interface.
If you are testing in the editor, use the manipulation handler instead as you can't test the navigation in the editor but it works on the HoloLens.
I have 2 classes: one maintains some loop (at leas for 2-3 minutes; and is inherited from QObject) and another shows up a progress dialog (inherited from QDialog).
I want to start the loop as soon as the dialog is shown. My first solution was:
int DialogClass::exec()
{
QTimer::singleShot(0, LoopClassPointer, SLOT(start()));
return __super::exec();
}
There is a problem with throwing exceptions from slots. so I considered a possibility to make public slot start() just a public function. But now I don't know how to make it works well. Things like this:
int DialogClass::exec()
{
LoopClassPointer->start();
QApplication::processEvents();
return __super::exec();
}
don't help. The dialog doesn't appears.
Is there a common approach to this kind of situations?
some details, according to questions:
I have to work with system with its own styles, so we have a common approach in creating any dialogs: to inherit them from stytle class, which is inherited from QDialog.
my 'LoopClassPointer' is an exported class from separate dll (there is no UI support in it).
I have a 'start' button in main app, which connected with a slot, which creates progress dialog and 'LoopClassPointer'. at the moment I send 'LoopClassPointer' instance in the dialog and don't whant to make significant changes in the architecture.
Take a look at QtDemo->Concurrent Programming->Run function
e.g. in Qt 4.8: http://qt-project.org/doc/qt-4.8/qtconcurrent-runfunction.html
In this situation, I recommend you separate the logic of the loop from the dialog. Gui elements should always be kept separate.
It's great that your worker class is derived from QObject because that means you can start it running on a separate thread: -
QThread* m_pWorkerThread = new QThread;
Worker* m_pWorkerObject = new Worker; // assuming this object runs the loop mentioned
// Qt 5 connect syntax
connect(m_pWorkerThread, &QThread::started, m_pWorkerObject, &WorkerObject::start);
connect(m_pWorkerThread, &QThread::finished, m_pWorkerThread, &QThread::deleteThis);
m_pWorkerObject->moveToThread(m_pWorkerThread);
m_pWorkerThread->start();
If you're not familiar with using QThread, then start by reading this.
The only other thing you require is to periodically send signals from your worker object with progress of its work and connect that to a slot in the dialog, which updates its display of the progress.
I am developing an application in GWT as my Bachelor's Thesis and I am fairly new to this. I have researched asynchronous callbacks on the internet. What I want to do is this: I want to handle the login of a user and display different data if they are an admin or a plain user.
My call looks like this:
serverCall.isAdmin(new AsyncCallback<Boolean>() {
public void onFailure(Throwable caught) {
//display error
}
public void onSuccess(Boolean admin) {
if (!admin){
//do something
}
else{
//do something else
}
}
});
Now, the code examples I have seen handle the data in the //do something// part directly. We discussed this with the person who is supervising me and I had the idea that I could fire an event upon success and when this event is fired load the page accordingly. Is this a good idea? Or should I stick with loading everything in the inner function? What confuses me about async callbacks is the fact that I can only use final variables inside the onSuccess function so I would rather not handle things in there - insight would be appreciated.
Thanks!
Since the inner-class/ anonymous function it is generated at runtime it needs a static memory reference to the variables it accesses. Putting final to a variable makes its memory address static, putting it to a safe memory region. The same happens if you reference a class field.
Its just standard java why you can only use Final variables inside an inner-class. Here is a great discussion discussing this topic.
When I use the AsyncCallback I do exactly what you suggested, I fire an event though GWT's EventBus. This allows several different parts of my application to respond when a user does log in.
Maybe I'm slow, but I just don't get why you would ever use an event that is not derived from an actual action (like clicking). Why go through the rigamarole of creating delegates and events when you can just call a method? It seems like when you create an event, all you're doing is creating a way for the caller to go through some complicated process to call a simple method. And the caller has to raise the event themselves! I don't get it.
Or maybe I'm just not grasping the concept. I get the need for events like OnClick and interactions with controls, but what about for classes? I tried to implement events for a class of mine, say, when the source of an item changed, but quickly realized that there was no point since I could just call a method whenever I wanted to perform a certain action instead of creating an event, raising an event, and writing an event handler. Plus, I can reuse my method, whereas I can't necessarily reuse my event handler.
Someone set me straight please. I feel like I'm just wrong here, and I want to be corrected. The last question I asked didn't really garner any sort of helpful answer.
Thanks.
I've always like the Radio Station metaphor.
When a radio station wants to broadcast something, it just sends it out. It doesn't need to know if there is actually anybody out there listening. Your radio is able to register itself with the radio station (by tuning in with the dial), and all radio station broadcasts (events in our little metaphor) are received by the radio who translates them into sound.
Without this registration (or event) mechanism. The radio station would have to contact each and every radio in turn and ask if it wanted the broadcast, if your radio said yes, then send the signal to it directly.
Your code may follow a very similar paradigm, where one class performs an action, but that class may not know, or may not want to know who will care about, or act on that action taking place. So it provides a way for any object to register or unregister itself for notification that the action has taken place.
Events in general can be a good way to decouple the listener/observer from the caller/raiser.
Consider the button. When someone clicks on the button, the click event fires. Does the listener of the button click care what the button looks like, does, or anything of that nature? Most likely not. It only cares that the click action has taken place, and it now goes and does something.
The same thing can be applied to anything that needs to same isolation/decoupling. It doesn't have to be UI driven, it can just be a logic separation that needs to take place.
Using events has the advantage of separating the class(es) which handle events from the classes which raise them (a la the Observer Pattern). While this is useful for Model View Controller (the button which raises click events is orthogonal to the class that handles them), it is also useful any time you want to make it easy to (whether at runtime or not) to keep the class which handles the events separated from the class which raises them (allowing you to change or replace them).
Basically, the whole point is to keep the classes which handle the events separated from the classes which raise them. Unnecessary coupling is bad, since it makes code maintainence much more difficult (since a change in one place in code will require changes in any pieces of code coupled to it).
Edit:
The majority of the event-handling you will do in Asp.Net will probably be to handle events from classes that are provided to you. Because such classes use event-handling, it makes it easy for you to interface with them. Often, the event will also serve to allow you to interact with the object that raised the event. For example, the databound controls usually raise an event right before they connect to the database, which you can handle in order to use runtime information to alter the arguments being passed to the stored procedure talking to your database, e.g. if the query string provides a page number parameter and the stored procedure has a page number argument.
Events can be used like messages to notify that something has happened, and an consumer can react to them in an appropriate way, so different components are loosely coupled. There's lots of things you can use events for, one example is auditing things that are happening in the system; the auditing component can consume various events and write out to a log when they are fired.
The things that you seem to be missing are two:
There are happenings in software that can take an arbitrary amount of time not only due to waiting for user input (async i/o, database queries and so on). If you launch an async i/o request you would want to subscribe to the event notifying you when the reading is done so you can do something with the data. This idea is generalized in .NET's BackgroundWorker class, which allows you to do heavy tasks in the background (another thread) and receive notifications in the calling thread when it's done.
There are happenings in software that are used by multiple clients not only a single one. For instance, if you have a plugin architecture where your main code offers hooks to plugin code, you could either do something like
foreach (Plugin p in getAvaliablePlugins()) { p.hook1(); }
in every hook all over your code which reduces flexibility (p cannot decide what to do, and has to provide the hook1 method publicly) or you can just
raiseEvent(hook1,this)
where all registered plugins can execute their code because they receive the event, letting them do their job as they see fit.
I think you're confusing ASP.NET's (mis)use of events, with plain ol' event handling.
We'll start with plain ol' event handling. Events is a (yet another) way of fulfilling the "Open [for extension]/Closed [for modification]" principle. When your class exposes an event, it allows external classes (perhaps classes that aren't even thought of, much less built, yet) to have code run by your class. That's a pretty powerful extension mechanism, and it doesn't require your class to be modified in any way.
As an example, consider a web server, that knows how to accept a request, but doesn't know how to process a file (I'll use bi-directional events here, where the handler can pass data back to the event source. Some would argue that's not kosher, but it's the first example that came to mind):
class WebServer {
public event EventHandler<RequestReceivedEventArgs> RequestReceived;
void ReceiveRequest() {
// lots of uninteresting network code here
var e = new RequestReceivedEventArgs();
e.Request = ReadRequest();
OnRequestReceived(e);
WriteResponse(e.Response);
}
void OnRequestReceived(RequestReceivedEventArgs e) {
var h = RequestReceived;
if (h != null) h(e);
}
}
Without changing the source code of that class - maybe it's in a 3rd party library - I can add a class that knows how to read a file from disk:
class FileRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
e.Response = File.ReadAllText(e.Request);
}
}
Or, maybe an ASP.NET compiler:
class AspNetRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
var p = Compile(e.Request);
e.Response = p.Render();
}
}
Or, maybe I'm just interested in knowing that an event happened, without affecting it at all. Say, for logging:
class LogRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
File.WriteAllText("log.txt", e.Request);
}
}
All of these classes are basically "injecting" code in the middle of WebServer.OnRequestReceived.
Now, for the ugly part. ASP.NET has this annoying little habit of having you write event handlers to handle your own events. So, the class that you're inheriting from (System.Web.UI.Page) has an event called Load:
abstract class Page {
public event EventHandler Load;
virtual void OnLoad(EventArgs e) {
var h = this.Load;
if (h != null) h(e);
}
}
and you want to run code when the page is loaded. Following the Open/Closed Principle, we can either inherit and override:
class MyPage : Page {
override void OnLoad(EventArgs e) {
base.OnLoad(e);
Response.Write("Hello World!");
}
}
or use eventing:
class MyPage : Page {
MyPage() {
this.Load += Page_Load;
}
void Page_Load(EventArgs e) {
Response.Write("Hello World!");
}
}
For some reason, Visual Studio and ASP.NET prefer the eventing approach. I suppose you can then have multiple handlers for the Load event, and they would all get run auto-magically - but I never see anyone doing that. Personally, I prefer the override approach - I think it's a bit clearer and you'll never have the question of "why am I subscribed to my own events?".