2

I'm trying to create a simple gesture recognizer for a D3D application. The gesture recognizer works by storing each point received into a boost::circular_buffer of capacity 3 and then counting the number of similar FrameID's in the buffer, like so:

UINT Trackball::CalculateGestureSize(Windows::UI::Input::PointerPoint ^ pPoint)
{
    // shift the circular buffer queue one if it's full (common case)
    if (m_pointQueue.full())
    {
        m_pointQueue.pop_back();
    }

    // then store our point
    m_pointQueue.push_front(*pPoint);

    // now we need to see how many of the points in the
    // circular buffer match the frame Id
    UINT gestureLength = 0;
    for (UINT i = 0; i < MAX_GESTURE_SIZE; i += 1)
    {
        if (m_pointQueue[i].FrameId == pPoint->FrameId)
        {
            gestureLength += 1;
        }
    }

    assert(gestureLength != 0);

    return gestureLength;
}

However, the compiler is unable to figure out how to instantiate this type:

// a queue of size 3 that helps determine what kind of gesture we're working with
boost::circular_buffer<Windows::UI::Input::PointerPoint> m_pointQueue;

because & and * cannot be used on WinRT objects:

boost/concept_check.hpp(195): error C3699: '&' : cannot use this indirection on type 'const Windows::UI::Input::PointerPoint' compiler replacing '&' with '^' to continue parsing

The compiler's error list then grows long very quickly due to the cascading effects of that error.

Right now, my solution is copy the necessary information for a PointerPoint into a struct and use that as the boost::circular_buffer's typename, like so:

// So WinRT objects (like Windows::UI::Input::PointerPoint) can't
// be used in STL-like containers (like boost::circular_buffer)
// because * and & operators cannot be used on them, so I'm copying 
// the necessary info into this struct and using that instead
typedef struct 
{
    UINT FrameId;
    Windows::Foundation::Point Position;
} LocalPoint;

// a queue of size 3 that helps determine what kind of gesture we're working with
boost::circular_buffer<LocalPoint> m_pointQueue;

This definitely works, but I was wondering if there's a better solution out there.

Thanks for reading and for trying to help.

Nico
  • 1,181
  • 2
  • 17
  • 35
  • 1
    Is there a reason why you're trying to store a `PointerPoint` instead of a `PointerPoint^` ? – MSalters Jul 01 '13 at 07:52
  • Eh, well my intuition was that I would rather copy the memory over rather than keep a reference to it for lifetime issues but I suppose that since ^ is a ref counted smart pointer, the PointerPoint being stored should not go out of scope if I keep a handle on it with a ^ pointer. Right? – Nico Jul 01 '13 at 15:09
  • The reaon I ask is that PointerPoint apparently is a managed object, i.e. its storage is managed by the CLR. Trying to _also_ manage it via Boost is the underlying cause. – MSalters Jul 01 '13 at 15:10
  • Ah, I was editing my comment while you posted but that turned out to be irrelevant. So okay, in that case, since I do not control the lifetime of a PointerPoint, copying the memory into my own local buffer is the correct solution. Right? – Nico Jul 01 '13 at 15:11
  • If you keep a `PointerPoint^`, you DO control the lifetime of the object. So I´m not sure about your conclusion. – MSalters Jul 01 '13 at 15:18
  • Right, that was my original understanding too. I look at WinRT object lifetime sort of like how I look at COM object lifetime, if I pass in a ComPtr, then I increment it's refcount and I've guaranteed got it until I release it. Okay, I'll try to use the pointer type as the typename instead and ill report back. Thanks for the help. – Nico Jul 01 '13 at 15:29
  • Yup, using the pointer type instead of the contents of it worked like a charm. If you want to write that up as an answer, I'll mark it as the correct answer. – Nico Jul 01 '13 at 16:45

2 Answers2

2

If you want to put a reference type in an STL collection, you need to use the ^ form. So you'd use: boost::circular_buffer<PointerPoint^> instead of boost::circular_buffer<PointerPoint>. A Windows::Foundation::Point is a value type so it can be used in a collection directly.

Larry Osterman
  • 16,086
  • 32
  • 60
0

I think I accidentally found a working solution by using that Windows::Foundation::Point object in my LocalPoint struct. Just wrap the WinRT object with a struct and then the operators will work just fine, but it'll add a bit of syntactic noise.

However I'm still listening for a better solution, but I'll leave this here till then.

Nico
  • 1,181
  • 2
  • 17
  • 35