Signal Sending and Subscription System

This system can be seen as an addition to the already in place event system. This system treats events as signals instead. Sending them to objects called SignalReceiver. The developer can create his own custom signals too if he wants. The system is made up by three base classes: SignalSender, SignalReceiver and SignalObject.

It is possible for the developer to say how exact he wants the signals to be. He can subscribe to all types of signals or say he wants all mouse related signals or even be so precise to say that he only wants when a button is pressed on the mouse.

Keep also in mind that the system was developed to work without the SFML Window system. It works perfectly without it (Though you will need to link towards it unless you remove the base signal classes). This is because the purpose of the system is not to deliver events, but to allow objects to communicate with each others.

Simple Example

#include <SFML/Graphics.hpp>
 
#include "SignalSystem/SignalSender.hpp"
#include "SignalSystem/SignalReceiver.hpp"
 
#include "SignalSystem/QuitSignal.hpp"
 
class Application : public SignalReceiver {
    private:
        bool running;
        sf::RenderWindow theWindow;
 
    public:
        Application() : SignalReceiver() {
            this->RegisterNewSignalFunction(QuitSignal(), SIGNALRECEIVER_FUNCTION(&Application::OnQuit));
            // We can also write: this->RegisterNewSignalFunction("Signal.Window.Quit", SIGNALRECIVER_FUNCTION(&Application::OnQuit));
        }
 
        void OnQuit(const SignalBase& signal) {
            // This is an unnecessary check but it's to show an easy way to convert signals.
            const QuitSignal * quit = QUITSIGNAL_CONVERT(signal);
            if(&this->theWindow == quit->GetWindow())
                running = false;
        }
 
        bool IsRunning() {
            return this->running;
        }
 
        sf::RenderWindow * GetWindow() {
            return &this->theWindow;
        }
};
 
int main() {
    Application app;
    sf::RenderWindow * window = app.GetWindow();
    window->Create(sf::VideoMode(800, 600), "Signals Simple Demonstration");
 
    SignalSender sender;
    sender.SubscribeReceiver(&app, "Signal"); // We want the application to receive all signals
 
    while(app.IsRunning()) {
        sender.FetchEventsFromWindow(window); // The system is designed to work without a SFML Window
        sender.SendSignals();
 
        window->Clear();
        window->Display();
    }
}

Now we need to explain this. First we include the needed header files. After that we define the class Application and make it inherit from SignalReceiver. This gives it some handy functions needed to receive, process and handle the signals. In the constructor we register a new function to handle a QuitSignal. Each signal class implements a GetType function which will give you the string type of the signal. Which is what the RegisterNewSignalFunction is interested in. We also provide a handy macro to create a object member function pointer that the SignalReceiver object can work with. Next we define the OnQuit function. This function doesn't really need to do much, but just to explain how things work we add some extra code. In the function we convert the SignalBase variable into a pointer to the real QuitSignal object. If we want to we can check the type of the SignalBase by adding signal.GetType(), this will return „Signal.Window.Quit“ which is the type of the QuitSignal object. All base signal types (The signals which represents the SFML Events) implements a macro that will do this conversion for us. And all the base signal types keeps track of which window that created it. So we just compare and check if it's the main window that is being closed. This is unnecessary since we only have one window but this is for demonstration.

Next up is the main function. We create our application object and set up our window. Nothing weird. After that we create the sender object, and subscribe the application object to the signal type „Signal“. „Signal“ is the base string type of the signals and subscribing to this string type means we will receive all signals sent from this SignalSender. But only „Signal.Window.Quit“ will be handled because only that one has a function mapped for handling signals. The others will be discarded graciously.

Now we enter the main-loop and keep on running fetching events from the window with FetchEventsFromWindow and then we send them to their subscribers with SendSignals. We can also manually pump signals into the SignalSender's internal queue using AddSignal.

Feel free to download it, modify and use it. I encourage you to experiment with it but keep in mind that I have not made it thread-safe. signals.rar

 
en/sources/signal_system.txt · Last modified: 2009/04/08 20:44 by Groogy
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki