• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Michael Santer
      Hi!
      We're currently two programmers and a game designer working on a turn-based tactics fantasy board game. For reference you can search for images of "Tactics Arena Online", a fairly dated game that used to have a lot of depth and complexity.
      Our goal is to use the same combat concepts, but giving it a much needed modern touch as well as a whole new set of heroes to choose from with additional abilities. The game is a mix of isometric and 3D and we plan to release the game on Steam and hopefully Android & iOS as well.
      We are looking for someone to work with us pro-bono (just like we're doing) as a 3D character artist. The skills needed are creativity, a hard working attitude and an ability to make minor animations (things like idle, walk, block and very rudimentary attack animations). A perk to have would be the ability to make some VFX. If the game makes it on steam and money starts coming in, you'd obviously be compensated for your hard work, but as it stands this is a hobby project to garnish your portfolio.
      A bit more about the game:
      This game will be an online multiplayer game where each user gets to pick up to 10 characters to place on his half of the board (this would be done before even entering matchmaking. Think runes in League of Legends for example). The user can place his 10 units of choice anywhere he likes on his half board. Some units can be used more than once. So if you want 4 knights and 2 mages or even if you want 10 clerics, you can do as you please. You can then save your setups for future use. The goal of the game is to wipe out the enemy team.
      Each character or Hero (except premium and abyss characters) start with 1 ability and they can ascend (either by playing a certain amount of matches with the character or by forcing the ascension with real money) to gain a new ability or passive. Acquiring a new character can be done by using in-game currency that you earn from playing matches or using real money with the exception of Abyss characters which can only be acquired by winning certain rare matches. The goal is to offer a freemium game with lots of customizable elements while making sure that no user can "buy power" with real money. We want everything that a paying user can get to be available to non-paying users who play the game a lot.
      Ultimately we want this to become a competitive game that people can enjoy and really get invested in. Each character is designed with options for counterplay in mind and synergy with other heroes.
       
      We sincerely believe in what this game can become and we home to find someone just as passionate as we are to get involved in this project!
    • By CrazyApplesStudio
         Hello , i would like to showcase my first game project, a simple endless casual arcade game called Apples Mania : Apple Catcher. The game has simple goal , scoring as high as possible by collecting falling apples while the difficulty gradually increases. Different apples are worth different amount of points and there are also 2 power-ups to help you in your challenge.
        The game took me about 2 months to complete and polish and i made everything except for the music tracks and some of the sound files. Made in unity and blender3d.
        Would appreciate any kind of feedback.
      Google Play Link
       
        A trailer showing basic game-play:
       
    • By Paszq
      Troglodytes are a playable races in Arpago - they usually don't talk much and most of them lives near water sources.
    • By Paszq
      a Fox in a dungeon :)
    • By Paszq
      Fox Folk is one of 3 playable races in Arpago.
  • Advertisement
  • Advertisement
Sign in to follow this  

Unity C# Delegate in C++?

This topic is 3935 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm sure that this doesn't fully match the C# delegate spec as I did not look to closer at the spec. However, this method does allow for me to make an event handler interface that lets me connect event listeners and automatically disconnect them when they go out of scope in a thread safe manner. I was inspired to do this a GDNet thread, the realization that Boost signal is not thread safe, and the feeling that my previous solution could be improved upon. This is the prototype that I came up with. Do note that to ensure thread safety, the user must make all event listeners thread safe. Listeners can be called at any time.
template <typename ListenerT,typename TriggerFuncT>
class Delegate
{
public:
    typedef TriggerFuncT tiggerFunc_t; // trigger function type
    typedef boost::shared_ptr<ListenerT> listenerP_t; // function pointer type
    typedef boost::weak_ptr<ListenerT> listenerWkP_t; // weak function pointer type
    // connects a function pointer to the delegate
    inline void Connect(listenerP_t func) { boost::mutex::scoped_lock lock(mutex);functions.push_back(listenerWkP_t(func)); };

    // triggers all objects in functions vector
    void Trigger(TriggerFuncT &trigger)
    {
        boost::mutex::scoped_lock lock(mutex); // lock access mutex
        typedef typename std::vector<listenerWkP_t>::iterator it_t;
        listenerP_t p;
        for (it_t i=functions.begin();i!=functions.end();i++)
        {
            // copy to shared_ptr
            p=i->lock();
            // if not expired then trigger
            if (!i->expired())
                trigger(p);
            else // elsewise remove from functions list
                functions.erase(i);
        }
    }
private:
    boost::mutex mutex; // access mutex
    std::vector<listenerWkP_t> functions; // list of functions
};

// USAGE EXAMPLE

// EXAMPLE LISTENER BASE CLASS
class ResChangeListener
{
    public:
    virtual void operator()(const math::vector2i &resolution) = 0;
};

// EXAMPLE LISTENER TRIGGER
class ResChangeTrigger
{
public:
    // delegate type
    typedef Delegate<ResChangeListener,ResChangeTrigger> delegate_t;
    // function pointer type
    typedef delegate_t::listenerP_t listenerP_t;

    ResChangeTrigger(const math::vector2i &resolution_) : resolution(resolution_) {};
    void operator () (listenerP_t func)
    { func->operator()(resolution); };
private:
    math::vector2i resolution; // new resolution
};

// EXAMPLE USE OF A DELEGATE
class Window
{
public:
    // constructs window
    Window(const std::string &appTitle,math::vector2i &resolution,bool isFullscreen);
    // sets the window dimensions
    void SetResolution(const math::vector2i &resolution);
    // swaps the display buffers
    void SwapBuffers() const { glfwSwapBuffers(); };
    // issues request to close window
    void Quit() {};
    // set an on reschange listener
    void OnResChange(ResChangeTrigger::listenerP_t func) { resChangeEvent.Connect(func); };
private:
    ResChangeTrigger::delegate_t resChangeEvent;
    boost::mutex mutex; // thread mutex for window
    GLFWInstance glfwIns; // glfw Instance
};

// EXAMPLE RESCHANGE LISTENER OBJECT
class ResChanger : public renwin::ResChangeListener
{
    public:
    ResChanger(math::vector2i &resolution_) : resolution(resolution_),isChanged(false) {};
    void operator()(const math::vector2i &resolution_)
    {
        boost::mutex::scoped_lock lock(mutex);
        isChanged=true;
        resolution=resolution_;
    };
    bool IsChanged() { return isChanged; };
    math::vector2i Resolution() { boost::mutex::scoped_lock lock(mutex);return resolution; };
    private:
    volatile bool isChanged; // is changed flag
    math::vector2i resolution; // screen resolution
    boost::mutex mutex; // access mutex
};

// EXAMPLE IMPLEMENTATION CODE IN MAIN
math::vector2i screen(1024,768); // screen dimensions

renwin::ResChangeTrigger::listenerP_t func(new ResChanger(screen));
window.OnResChange(func);
window.SetResolution(math::vector2i(800,600));

log.Mode(lg::MESSAGE)<<screen; // logs the screen dimensions to file
if (((ResChanger*)func.get())->IsChanged())
    screen=((ResChanger*)func.get())->Resolution();
log.Mode(lg::MESSAGE)<<screen; // logs the screen dimensions to file

The log output shows success
Quote:
Log <Entry caller="main()" level="Message">[ 1024 768 ]</Entry> <Entry caller="main()" level="Message">[ 800 600 ]</Entry>
I am still experimenting with this code but I'm thinking I may use it in my GUI. I do plan on limiting my use of this method as I feel event driven design requires too much synchronization. All feedback is appreciated, thank you.

Share this post


Link to post
Share on other sites
Advertisement
If you're using this for GUI, then you won't benefit from multi-threading.

A lot of attempts have been made at thread-safe window managers, but ultimately, there's a "except..." case which breaks usefulness.

For this very reason, GUI frameworks use internal event pipeline that executes all events from a single thread. Even then, various problems arise. Or simply put: there are many hidden pitfalls when trying to do multi-threaded UIs.

When using implicit locking on every notification, the overhead is through the roof as soon as you have a moderate amount of resources.

But perhaps the greatest problem with this is that it's a dead-lock waiting to happen.

Button1--trigger-->B--trigger-->C // thread 1
Button2--trigger-->C--trigger-->B // thread 2



So you're left with two options: Using per object lock, resulting in above, or using global lock, which negates any benefit from multi-threading.

The only way to avoid this would be, well, what many window managers use - separate thread for event invocation.

And you're back to square one.

Long story short: Warning, there be dragons here. Boost folks aren't lazy. The reason it's not thread safe is due to design issues.

Share this post


Link to post
Share on other sites
Interesting, right now I am not sure if my GUI will need to be multi-threaded i just don't want to limit it unnecessarily. It seems that Qt has multi-threaded GUI handled well, although I don't want another library attached to my project, not for something with as limited use to my project as multi-threaded event handling.

My Window wrapper however, will need multi-threaded event handling.

If that is the only place that needs it then I should probably make a more closed system that only provides one "already defined for you" event listener type per event. That way I would limit the places where listener types could cause multi-threading issues.

Share this post


Link to post
Share on other sites
Your Delegate class depends on the listener class as a template parameter, which keeps it from being particularly useful. The ability to register a listener without inheriting from an explicit XyzListener class is the main advantage of delegates.

Share this post


Link to post
Share on other sites
^
Quote:
Original post by T1Oracle
I'm sure that this doesn't fully match the C# delegate spec...
However, this method does allow for me to make an event handler interface that lets me connect event listeners and automatically disconnect them when they go out of scope in a thread safe manner.

Regardless, I am about to restrict the "usefulness" even further in the name of thread safety by forcing users to use my XYZListener class instead being able to derive their own. For detecting things like changes in window dimensions, loss of window focus, and the closing of the application there isn't much need for offering that level of flexibility. Changes of window dimensions can be handled by doing an if (condition==true) and then explicitly copying the new dimensions by calling another class method if needed.

I see no such situation where more must be demanded of the event interface, to implement a useful functionality.

Share this post


Link to post
Share on other sites
Delegates area about organization, not functionality. If you don't want the convenience of a heterogeneous collection of listeners, why not just use a container of weak_ptrs to your listener interface?

Share this post


Link to post
Share on other sites
Quote:
Original post by T1OracleInteresting, right now I am not sure if my GUI will need to be multi-threaded i just don't want to limit it unnecessarily. It seems that Qt has multi-threaded GUI handled well, although I don't want another library attached to my project, not for something with as limited use to my project as multi-threaded event handling.


Qt performs all GUI work in a single thread. Threads may queue events through the main event loop but the events are dispatched on the main GUI thread. You can invoke Qt's signal/slot mechanism from multiple threads, but don't do any GUI work from those slots.

In short, Qt does not have a multi-threaded GUI.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement