Top Banner
Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++
24

Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Dec 27, 2015

Download

Documents

Spencer Walton
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Effective WinRT with C++Tips and tricks for developing WinRT applications in C++

Page 2: 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

Page 3: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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.

Page 4: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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.

Page 5: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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.

Page 6: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 7: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 8: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 9: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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)

Page 10: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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 resultmyTask.get();

// Blocking call, retrieves the statusmyTask.wait();

• Allows an imperative style when launching non-blocking tasks

myTask.then([]{ do_what_comes_next(); });

Page 11: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Asynchronous calls made easy

concurrency::task<void> Singleton::ComplexTask(){ /* ... */ }

// Define a sequence of tasksSingleton::Get().ComplexTask() .then([] { // ... }) .then([] { // ... });

Page 12: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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();

Page 13: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 14: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Exception handling

concurrency::create_task([] { }) // A few tasks “later”... .then([this](concurrency::task<void> t) { try { t.get(); } catch(Platform::Exception^ except) { // Handle except } });

Page 15: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 16: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

}

Page 17: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Special cases in error handling

Short Demonstration

Page 18: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Granting permissions

•File system access may be needed for logging

▫Add the targeted folder read/write access to ALL APPLICATION PACKAGES

Page 19: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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.

Page 20: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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

Page 21: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Using delegates for callbacks

• Use EventRegistrationToken

// Class declarationclass MyClass{// ...private: Windows::Foundation::EventRegistrationToken token;}

// Class implementation

token = MyEventsManager::OnMyEvent += ref new MyEventHandler([]{ /* ... */ });

• Finally, trigger the event when needed by calling

MyEventsManager::FireMyEvent();

Page 22: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Using delegates for callbacks

Short Demonstration

Page 23: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

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-Windows-

Store-app-Beginners-tutorial

• Marc Grégoire Blog▫ http://www.nuonsoft.com/blog/

Page 24: Effective WinRT with C++ Tips and tricks for developing WinRT applications in C++

Thank you