Francisco Almeida - Developing for WinRT with C++

advertisement
Effective WinRT with C++
Tips and tricks for developing
WinRT applications in C++
Effective WinRT with C++
• How WinRT works with C++
• Thread safety
▫ Thread-safe singletons
▫ Using lambdas for callbacks
 Using the PPL
 Exception handling
• General hints with WinRT
▫ Error handling for permissions
▫ Using delegates for callbacks
How WinRT works with C++
• C++ implementation choices:
▫ XAML based.
▫ DirectX (Direct2D and/or Direct3D) based.
▫ A subset of win32 API is available.
• Windows Store apps are sandboxed, so there are
some limitations.
▫ Disk and hardware access is restricted.
▫ Fully multithreaded design.
Using C++ to implement WinRT classes
• public interface:
▫ WinRT types and conventions only.
• private (or internal) interface:
▫ Standard C++ containers, classes and conventions
can be used.
• Enumerated types:
▫ Strongly typed enums (enum
class)
are accepted.
Using new standard language features
• WinRT containers can be constructed from standard library
containers.
• Range-based for loops work with WinRT classes (include
collection.h).
• Move semantics is available.
• Lambdas are accepted as delegates/function pointers.
• Thread safety is very important.
Thread safety in modern C++
• Example of a thread-safe singleton
class Singleton
{
public:
virtual ~Singleton();
static Singleton& Get();
private:
static std::unique_ptr<Singleton> s_instance;
static std::once_flag s_creationFlag;
Singleton();
Singleton(const Singleton& other) /* = delete */;
Singleton& operator=(const Singleton& other) /* = delete */;
}
Thread safety in modern C++
• Example of a thread-safe singleton
std::unique_ptr<Singleton> Singletion::s_instance = nullptr;
std::once_flag Singleton::s_creationFlag;
Singleton& Singleton::Get()
{
std::call_once(s_creationFlag,
[]{
s_instance.reset(new Singleton);
});
return *s_instance.get();
}
Multithreading in WinRT
• Every command* runs in its own thread.
• Avoid the callback spaghetti:
▫ Parallel Patterns Library
▫ Use delegates for event handling
* That potentially lasts longer than 50 ms
Parallel Patterns Library
The Parallel Patterns Library (PPL) provides an imperative
programming model that promotes scalability and ease-of-use for
developing concurrent applications.
- MSDN (http://msdn.microsoft.com/en-us/library/dd492418.aspx)
Parallel Patterns Library
• Task objects, analogous to std::future objects.
using namespace concurrency;
task<void> myTask([]{ do_something(); });
auto myTask = concurrency::create_task([]{ do_something(); });
// Non-blocking or blocking call to retrieve the result
myTask.get();
// Blocking call, retrieves the status
myTask.wait();
• Allows an imperative style when launching nonblocking tasks
myTask.then([]{ do_what_comes_next(); });
Asynchronous calls made easy
concurrency::task<void> Singleton::ComplexTask()
{ /* ... */ }
// Define a sequence of tasks
Singleton::Get().ComplexTask()
.then([]
{
// ...
})
.then([]
{
// ...
});
WinRT CoreDispatcher class
• Every XAML page can access the CoreDispatcher
object through the Dispatcher member
• Issue tasks in the main thread, from any thread.
using namespace Windows::Core::UI;
using namespace Windows::System::Threading;
// Non-blocking call with normal priority.
Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
ref new DispatchedHandler([]{ /*...*/ }));
// Check whether the current thread can be accessed
Dispatcher->HasThreadAccess();
Capturing objects in task chains
concurrency::task<void> MyClass::ExecuteTask()
{
// ...
return concurrency::create_task(
[this, local_variable] // <-- avoid locals by reference!
{
m_cached_value = local_variable;
})
.then([this]
{
}); // and so on...
};
Exception handling
concurrency::create_task([]
{
})
// A few tasks “later”...
.then([this](concurrency::task<void> t)
{
try
{
t.get();
}
catch(Platform::Exception^ except)
{
// Handle except
}
});
Special cases in error handling
• Handle connection to devices
▫ Windows handles first access for you.
 Geolocation, camera, phone functionality, etc.
• When using webcam or microphone
▫ Permission errors are handled by checking:
 E_ACCESSDENIED
 HRESULT_FROM_WIN32(ERROR_FILE_HANDLE_REVOKED)
• When sending SMS (Windows Phone 8)
▫ Permission errors handled by checking:
 E_ACCESSDENIED
Special cases in error handling
• Examples of error handling for webcam capture
▫ Initialization error:
// (continued task chain including call to InitializeAsync)
.then([this](task<void> t) {
try { t.get(); }
catch(Exception^ e) {
if(e->HResult == E_ACCESSDENIED)
// Handle permissions error
else // Check if camera is not connected
}
}
▫ Spontaneous error:
void CameraCallback(MediaCapture^ currentCaptureObject,
MediaCaptureFailedEventArgs^ currentFailure)
{
if(currentFailure->Code == HRESULT_FROM_WIN32(ERROR_FILE_HANDLE_REVOKED))
// Handle revoked permissions
else // Check if camera was suddenly disconnected
}
Special cases in error handling
Short Demonstration
Granting permissions
• File system access may be needed for logging
▫ Add the targeted folder read/write access to
 ALL APPLICATION PACKAGES
Using delegates for callbacks
• In WinRT applications, callbacks can be
registered through a generic mechanism.
• Non-standard language extensions:
▫ delegate keyword.
▫ event keyword.
• WinRT EventRegistrationToken class:
▫ Used to register the delegates for corresponding
events.
Using delegates for callbacks
• A very simple class that reacts to events
public delegate void MyEventHandler();
public ref class MyEventsManager sealed
{
public:
static event MyEventHandler^ OnMyEvent;
static void FireMyEvent() { OnMyEvent(); }
};
Using delegates for callbacks
• Use EventRegistrationToken
// Class declaration
class MyClass
{
// ...
private:
Windows::Foundation::EventRegistrationToken token;
}
// Class implementation
token = MyEventsManager::OnMyEvent +=
ref new MyEventHandler([]{ /* ... */ });
• Finally, trigger the event when needed by calling
MyEventsManager::FireMyEvent();
Using delegates for callbacks
Short Demonstration
References and useful sources
• ISO Standard C++ official page
▫ http://www.isocpp.org/
• MSDN (Microsoft Developer Network)
▫ http://msdn.microsoft.com/library/windows/apps/
• CodeProject
▫ http://www.codeproject.com/Articles/472009/Creating-WindowsStore-app-Beginners-tutorial
• Marc Grégoire Blog
▫ http://www.nuonsoft.com/blog/
Thank you
Download