Thursday, October 4, 2012

Timers in windows8 using c++


Just getting a basic timer in c++ isn't as easy as in C#.
So I'm stepping myself through this and documenting my findings.
I just want to start a timer on a touch event to fade out a control when the finger leaves the screen.
So to do this I want that control to wait for a few seconds before going back to it's home position.
I could use wait, but then the rest of the screen locks up till after the wait.
Since I want to use multi touch features this is bad.
The best way to do this *I think* is concurrency and the call function, but finding a good example for this has been really hard.

http://msdn.microsoft.com/en-us/library/dd504870.aspx I started here to get a start on the concurrency run time.
Also writing a windows 8 metro app in WPF, so that's adding some little hitches here and there with various features that I can and can't use.
Also can't use 3rd party libs like boost.asio which is because the client doesn't like those things, doh.
Google for running multuple tasks and I get to
this link http://msdn.microsoft.com/en-us/library/dd728065.aspx.
In here was the following code snippet...

int wmain()
{
// Create a call object that prints a single character to the console.
call<wchar_t> report_progress([](wchar_t c) {
wcout << c;
});
// Create a timer object that sends the dot character to the  
// call object every 100 milliseconds.
timer<wchar_t> progress_timer(100, L'.', &report_progress, true);
wcout << L"Performing a lengthy operation";
// Start the timer on a separate context.
progress_timer.start();
// Perform a lengthy operation on the main context.
perform_lengthy_operation();
// Stop the timer and print a message.
progress_timer.stop();
wcout << L"done.";
}

This looked pretty helpful. There's the call and the timer functions that look pretty good.
Unfortunately in report_progress([] (wchar_t c) {...} there's a lambda and I get the following error

Error: a local lambda is not allowed in a member function of a WinRT class.

damn.

So now what? Dig around more for timer class in WinRT and I find
http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/fd9c3010-484b-4881-88c8-765473fd5b1e
What's going on here?

Instead of SetTimer(), you should use Windows::UI::Xaml::DispatcherTimer.
See the MSDN article here: http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.dispatchertimer.aspx.

Okay, so lets go there.
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.dispatchertimer.aspx.
and...

Server Error in '/' Application.
The resource cannot be found.Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. Requested URL: /en-us/library/windows/apps/windows.ui.xaml.dispatchertimer.aspx.

Crap, so look up xaml dispatch timer and get to  http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.dispatchertimer
I think im getting closer. This is looking a bit better, something that seems to be useful, finally.
I just used this in C# for the previous version of the interface I was building in C#, perfect!
I think I can use this. The example is in C# so i need to find a C++ example,
get to this http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/edff3bf2-4223-49fe-b66b-119702458700
The thread goes through a few iterations. I get to what I think is really close but get stuck at.

timer->Tick += ref new  Windows::Foundation::EventHandler<Object^>(this, &DispatcherTimer_Tick); 

I get an error:

object not needed for the specified function

So I delete "this" and the following "," and that seems to do the trick.
No more errors...
So I start my vars with...

Windows::UI::Xaml::DispatcherTimer ^SomeTimer;

and then add in a way to count ticks...

int Ticks;

and when the xaml page is initialized i add in

XAMLPage()
{
InitializeComponent();
//other init stuff...
SomeTimer = ref new DispatcherTimer;
SomeTimer->Tick += ref new  Windows::Foundation::EventHandler<Object^>( &Timer_Tick); 
TimeSpan t;
t.Duration=1;
SomeTimer->Interval = t;
}

Then I precede the page initialization with my Timer_Tick function that looks something like...

void Timer_Tick(Platform::Object^ sender, Platform::Object^ e)
{
OutputDebugString(L"TIMER!!!");
Ticks++;
if(Ticks>10)
SomeTimer->Stop();
}

so after 10 ticks the timer stops.

I'm far from a super c++ programmer, and mostly a C# or unrealscript game programmer guy.
I've been doing this stuff for a while and I learn fast, and that's pretty important.
I do these little process blog entries to help myself out.
It's like a breadcrumb trail I can follow to avoid backtracking.
Hope this helps someone.

No comments:

Post a Comment

rxokita's shared items