locked
Events (in C++)

    Question

  • I'm still somewhat new to C++, coming from a C# background.  I'm in the midst of making a Windows 8 "metro" game.

    Now I'm in the need to use events in my game, and am at a loss as the proper way to implement them.  I've seen and heard many approaches:

    1. Using WinRT classes, I can actually have delegates and events.  Unfortunately, I decided early on that I didn't want to have to put "ref" on every single one of my classes, so I've more or less steered away from that.  Unless I'm wrong, please correct me.  But, that would mean that both the firing class and the subscriber would have to be "ref" classes, no?  Then, any classes the subscriber inherits from would also need to be "ref."

    2. I could use function pointers, sounded like a good choice.  Despite everyone saying that the syntax looks ugly, I thought it looked a little elegant.  But, then I learned that I can't simply use function pointers, but I need to use member function pointers (method pointers).  Couldn't find a whole lot of information when googling that.

    3. Use deprecated (or soon to be deprecated) "[event_source(native)]" and [event_reveiver(native)]" approach.  Which would also mean using __hook and other ugly syntax.  Not to mention this is mostly designed for COM.

    4. Use a library called Boost.  Despite the fact that I'm using a library for a problem that seems like it should be solved at the language level, I tried downloading it.  I don't know if it works on Windows 8, but I couldn't get it installed.  Also, I was told that it works with a lot of Win32, which is not good for a "metro" app.

    Any help/advice?  Thanks.

    Thursday, October 4, 2012 4:48 PM

Answers

  • Hi,

    I worked on a project called Marble Maze, which is a complete but basic Windows 8 game using C++ and DirectX. You can see from the code and guidance how we connect to Windows events. I highly recommend using C++/CX to implement your own events as well because C++/CX provides an easy syntax (plus remember that C++/CX is still pure native code!) The guidance describes when to use C++/CX and when to use pure C++ code. Take a look at what we've done and let us know what feedback or questions you have!

    Code:

    DirectX marble maze game sample

    Written guidance:

    Developing Marble Maze, a Windows Store game in C++ and DirectX

    Good luck! I hope you find this to be useful.

    • Marked as answer by DualOpAmp Tuesday, October 9, 2012 7:44 PM
    Friday, October 5, 2012 6:26 PM
  • So I believe that you will need to use a ref class if you're going to work with C++/CX events. I typically follow these guidelines:

    • Use ref classes when you need to interact with the Windows Runtime, need to create a reusable Windows Runtime component that can be accessed from JavaScript, C++, or .NET, or you simply want the benefits of automatic reference counting (of course, you can also use std::shared_ptr for this). In other words, use C++/CX along the boundary of your app.
    • Use pure C++ code to implement the business logic details of your app. This includes bringing forward code that you've already written and tested (remember, however, to use only those APIs allowed in Windows Store apps reference1 reference2). (Note, however, that you can always use C++/CX throughout your app -- it's your choice.)

    With that in mind, you might use C++/CX ref classes to work with Windows Runtime events, and Boost or some other library to work with internal events. Of course, you can use C++/CX ref classes to work with internal events as well.

    If you use ref classes to work with events, we recommend that you use a function handler instead of a lambda because a lambda can introduce a circular reference and prevent memory from being freed. This is from MSDN:

    http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh755799.aspx

    In general, it's better to use a named function, rather than a lambda, for an event handler unless you take great care to avoid circular references. A named function captures the "this" pointer by weak reference, whereas a lambda captures it by strong reference and creates a circular reference. For more information, see Weak references and breaking cycles (C++/CX).

    • Marked as answer by DualOpAmp Tuesday, October 9, 2012 9:20 PM
    Tuesday, October 9, 2012 9:03 PM

All replies

  • If you want to stay in C++ (Not C++/CX) you can use the Windows Runtime C++ Template Library (WRL).

    References & useful pages:

      * http://msdn.microsoft.com/en-us/library/jj155852.aspx

    [Research details: http://bit.ly/VBzbQD]



    Visual C++ MVP

    Thursday, October 4, 2012 10:27 PM
  • Hi,

    I worked on a project called Marble Maze, which is a complete but basic Windows 8 game using C++ and DirectX. You can see from the code and guidance how we connect to Windows events. I highly recommend using C++/CX to implement your own events as well because C++/CX provides an easy syntax (plus remember that C++/CX is still pure native code!) The guidance describes when to use C++/CX and when to use pure C++ code. Take a look at what we've done and let us know what feedback or questions you have!

    Code:

    DirectX marble maze game sample

    Written guidance:

    Developing Marble Maze, a Windows Store game in C++ and DirectX

    Good luck! I hope you find this to be useful.

    • Marked as answer by DualOpAmp Tuesday, October 9, 2012 7:44 PM
    Friday, October 5, 2012 6:26 PM
  • Also, consider using the task pattern from the Parallel Patterns Library (#include <ppltasks.h>, use the concurrency namespace) with lambda syntax. It's good to invest in understanding the PPL and lambda syntax, as it is incorporated as a best practice in many of the Windows Store app C++ samples.

    There's a great example in the BasicReaderWriter.h and .cpp files in the Direct3D resource loading sample.

    Take a look over the hyperlinked docs, walk a few samples, and give it a try!

    Doug





    Friday, October 5, 2012 6:46 PM
  • Hi,

    I worked on a project called Marble Maze, which is a complete but basic Windows 8 game using C++ and DirectX. You can see from the code and guidance how we connect to Windows events. I highly recommend using C++/CX to implement your own events as well because C++/CX provides an easy syntax (plus remember that C++/CX is still pure native code!) The guidance describes when to use C++/CX and when to use pure C++ code. Take a look at what we've done and let us know what feedback or questions you have!

    Code:

    DirectX marble maze game sample

    Written guidance:

    Developing Marble Maze, a Windows Store game in C++ and DirectX

    Good luck! I hope you find this to be useful.

    Well, here's my question: As a general design guide, should I use C++/CX "ref" classes any time that class is going to need an event?

    Sunday, October 7, 2012 4:48 AM
  • So I believe that you will need to use a ref class if you're going to work with C++/CX events. I typically follow these guidelines:

    • Use ref classes when you need to interact with the Windows Runtime, need to create a reusable Windows Runtime component that can be accessed from JavaScript, C++, or .NET, or you simply want the benefits of automatic reference counting (of course, you can also use std::shared_ptr for this). In other words, use C++/CX along the boundary of your app.
    • Use pure C++ code to implement the business logic details of your app. This includes bringing forward code that you've already written and tested (remember, however, to use only those APIs allowed in Windows Store apps reference1 reference2). (Note, however, that you can always use C++/CX throughout your app -- it's your choice.)

    With that in mind, you might use C++/CX ref classes to work with Windows Runtime events, and Boost or some other library to work with internal events. Of course, you can use C++/CX ref classes to work with internal events as well.

    If you use ref classes to work with events, we recommend that you use a function handler instead of a lambda because a lambda can introduce a circular reference and prevent memory from being freed. This is from MSDN:

    http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh755799.aspx

    In general, it's better to use a named function, rather than a lambda, for an event handler unless you take great care to avoid circular references. A named function captures the "this" pointer by weak reference, whereas a lambda captures it by strong reference and creates a circular reference. For more information, see Weak references and breaking cycles (C++/CX).

    • Marked as answer by DualOpAmp Tuesday, October 9, 2012 9:20 PM
    Tuesday, October 9, 2012 9:03 PM
  • I've heard that before in a BUILD video use C++/CX "along the boundary" of your app.  But, my confusion came from the fact that I needed to use events inside my app, for situations in the game, such as spawning an object, etc.

    Anyway, I have started to use ref classes where I need events.  Problem solved, thanks.

    Tuesday, October 9, 2012 9:25 PM