WRL implementations of IVector and IAsyncOperation
tl; dr
If you are developing your own Windows Runtime component using WRL, you might be interested in borrowing these implementations of standard interfaces:
- >https://github.com/Microsoft/Win2D/blob/master/winrt/inc/Vector.h
- >https://github.com/Microsoft/Win2D/blob/master/winrt/inc/AsyncOperation.h
More detail:
Windows Runtime components can be implemented using .NET, C++/CX, or standard C++ with WRL. We chose WRL for the Win2D projectbecause it’s the lowest level option and gives the most control over every detail of the implementation. Of course, this also means it is the hardest to work with and requires us to do the most work!
The Windows Runtime defines standard interfaces representing collections (IVector) and asynchronous computations (IAsyncOperation). Both .NET and C++/CX provide rich language projections on top of these interfacesmapping them to specialized APIs that make it easy to create and consume them. WRL, not so much src="https://blogs.msdn.microsoft.com/shawnhar/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" />
We looked around for existing WRL vector and async implementations that we could use in Win2D, but could not find anything that met all our requirements (complete, robust, well tested, under a suitable open source license, and not too badly tangled up with other code). So we rolled our own. Each interface is implemented in a single header with no dependencies on the rest of Win2D, so we hope these will prove suitable for anyone else who finds themselves needing the same thing in future.
Vector.h
This header provides the class Vector
Usage example (error handling skipped for brevity):
IFACEMETHODIMP CreateVectorOfInts(IVector<int>** returnValue) { ComPtr<Vector<int>> v = Make<Vector<int>>(initialSize, isFixedSize); // Access the vector using Windows Runtime interface methods. v->Append(42); v->InsertAt(0, 23); // Internally to your implementation module, it is also possible // to get direct access to the underlying STL collection. std::vector<int>& raw = v->InternalVector(); std::sort(raw.begin(), raw.end()); v.CopyTo(returnValue); return S_OK; }AsyncOperation.h
This header provides the classes AsyncOperation
Example (error handling skipped for brevity) which uses an asynchronous thread pool task to add two integers:
IFACEMETHODIMP AddAsync(int a, int b, IAsyncOperation<int>** returnValue) { auto asyncOperation = Make<AsyncOperation<int>>([=] { return a + b; }); asyncOperation.CopyTo(returnValue); return S_OK; }Even sillier example, which runs an asynchronous multiply task as the continuation of an asynchronous addition:
IFACEMETHODIMP AddAndThenMultiplyAsync(int a, int b, int c, IAsyncOperation<int>** returnValue) { // Start the first asynchronous computation. // This computes a + b. ComPtr<IAsyncOperation<int>> addOperation; AddAsync(a, b, &addOperation); // Register a second asynchronous computation to run as the continuation of the first. // This computes <previous async result> * c. auto multiplyOperation = Make<AsyncOperation<int>>(addOperation, [=] { int addResult; addOperation->GetResults(&addResult); return addResult * c; }); multiplyOperation.CopyTo(returnValue); return S_OK; }
Discussion