Sign in to follow this  
  • entries
    83
  • comments
    0
  • views
    65811

WRL implementations of IVector and IAsyncOperation

Sign in to follow this  

295 views

tl; dr

If you are developing your own Windows Runtime component using WRL, you might be interested in borrowing these implementations of standard interfaces:




More detail:


Windows Runtime components can be implemented using .NET, C++/CX, or standard C++ with WRL.  We chose WRL for the href="https://github.com/Microsoft/Win2D" target="_blank">Win2D project, because 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 (href="http://msdn.microsoft.com/en-us/library/windows/apps/br206598.aspx" target="_blank">IAsyncOperation).  Both .NET and C++/CX provide rich language projections on top of these interfaces, mapping 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<T>, which implements the Windows Runtime interfaces IVector<T>, href="http://msdn.microsoft.com/en-us/library/windows/apps/br226058.aspx" target="_blank">IVectorView<T>, href="http://msdn.microsoft.com/en-us/library/windows/apps/br226024.aspx" target="_blank">IIterable<T>, and href="http://msdn.microsoft.com/en-us/library/windows/apps/br226026.aspx" target="_blank">IIterator<T>.  The vector can be fixed size or dynamically resizable, and tracks a dirty flag so you can efficiently check if its contents have changed.  T may be any value type, interface, or runtime class, but strings are not currently supported.


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<T> and AsyncAction, which implement the Windows Runtime interfaces IAsyncOperation<T*> and href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.foundation.iasyncaction.aspx" target="_blank">IAsyncAction respectively.  It runs arbitrary code on the system threadpool, and reports the result or error status through standard async interfaces.  It is also possible to register one async operation to run as the continuation of another.


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;
}



Source

Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now