Pass 'this' pointer from parent to child object: scheduler/ofTimer system

First of all, I’d like to say thank you to this forum. There is a wealth of great information here …
It’s taken me a while to run into a question that I couldn’t inevitably resolve given all of the documentation and all of your help here on the forum. I could probably eventually solve this one too, but I just really wanna talk to you guys! And I bet that you’ll reward my pestering with some good advice! PEACE
~

I’m writing a drum machine application.
Currently, I’m trying to smooth out my scheduler/timer system that is responsible for
adjusting the tempo, given a BPM parameter … and scheduling microsecond-precision timers (ofTimer) that reflect the last updated schedule and trigger the next Beat! at the scheduled time.

I’ve just picked up a book on C++ at my local, beloved bookshop, and I’ve been learning a lot about the core functionality of the language… initializing objects in Free Store, using references and pointers, etc.

I have a class ‘Scheduler’ inheriting from ofThread. I have included a ‘timer.h’ file that defines a class ‘Timer’ also inheriting from ofThread and initializing an ofTimer. When the Scheduler creates the Timer object, like this:

Timer* timer;
. . .
timer = new Timer ( . . .

. . . it also pass a this pointer to the constructor of the Timer object, like this:

Scheduler* schedPtr = this;
. . .
timer = new Timer ( Scheduler* schedPtr, . . .

The scheduler object is initialized in main and is responsible for creating and managing Timer objects and communicating with main application and with the GUI. Timer objects are initialized in the free store and only interact with the Scheduler object. I have no problem including the Timer class header file in the Scheduler header, creating Timer pointers and initializing them. But the reverse doesn’t work! (’!’ added for cheesy inflection).

this is the point:
I need to store a pointer referring to the parent object (scheduler) and pass from parent to the child object (timer), so that the timer’s threaded function can call startThread on the scheduler object after updating the beat register. Like this,

schedPtr->startThread();

I am receiving the error: “Scheduler does not name a type.” @ line: Scheduler scheduler;*


Thank you everyone! I would be happy to provide more information as needed, but I thought that this was enough to get the issue across to anyone with plenty of experience. I appreciate you dudes. OF ROCKS

I should clarify that the error occurs twice in the Timer class, first when creating the Scheduler* ‘schedPtr’, and again in the Timer constructor, where I would like it to receive a Scheduler* from the parent object, scheduler.

TY

Should I declare a static member function in Scheduler that triggers the private threaded function?

Aha! I was required to use a forward declaration of Scheduler class in Timer header. See, just a basic thang. Thanks anyways, peeps.

The forward declaration didn’t do the trick I had hoped it would! I was running into cyclic dependency issues; the header files from Scheduler and Timer needed to refer to one another. I’ve ended up nesting the Timer class inside the Schedule class declaration.

This isn’t the solution I was hoping for, but it works --I can pass a pointer referring to the scheduler object into timer objects, so the timer thread can trigger the scheduler thread.

If anyone has any further advice, please share.

this really sounds like a recursive inclusion issue and the solution is using forward declaration. you might be doing it incorrectly but pretty sure that’s the solution.

also your design seems pretty convoluted, you shouldn’t need as many threads just to create timers and in general when working with sound you shouldn’t even use system timers like ofTimer. just count the number of sound buffers and that will give you the exact time according to the sound card’s clock which is what you want to use:

numbuffers * buffersize / samplerate = seconds

ofSoundBuffer when sent from a soundstream has a getTickCount method that will tell you which buffer number it belongs to and from that you can calculate the time.

Right on. I’ll keep trying.

I haven’t gotten around to working with audio in OF, yet. I’ve been designing a graphical user interface: It’s a polar grid of buttons that keeps up with which beats the user chooses and does flashy effects. Each ring of buttons will correspond to a specific drum sample. There’s a kind of radar that spins around in time with the beats, and it’s looking really nice. I need some kind of a scheduler/timer register as a back-end that will coordinate the audio triggers and the graphical interface. I’m excited to learn more about audio in OF, but I’ve been working on the timer system for a while! I had a setup that used a single ofTimer and would re-call setPeriodicEvent() on that object to reset the timer, but I was unsure of the limitations and implementation of ofTimer.

How often can one call setPeriodicEvent on an ofTimer? I need to be able to update the tempo on-the-fly whenever the user chooses within reasonable constraints with respect to the limitations of the timer system.

Thanks for all your help around the forum, Arturo. All your comments have been a great help, and I appreciate you taking the time.

By the way, my failed attempt at forward declaration was giving me an “Incomplete Type” that the Timer class could not initialize a pointer to … I’ll figure it out. I’ll continue studying Threads for now.

After re-reading your ofThread chapter in the ofBook, it dawned on me that we have 16000 microseconds to play with in-between frames. That is plenty of time to execute a full timer update, even as often as once per draw cycle, if it were really needed … My Scheduler class does not need its own thread. I’m retaining the dual Timer objects for now, so that the temporary update timer can trigger the normalized periodic timer before being stopped and deleted. The threaded Timer function must also call Scheduler function, so that the scheduler in turn can communicate with the main program and take care of clean-up . . on a side note, it seems to require 30 - 100 microseconds to start a thread, and I do not understand why, because I have not done enough research into the ways of threads. I am concerned about the effect this has on the precision of my timer system … perhaps these fraction-of-a-millis differences are somewhat arbitrary for now …

Regardless, the Scheduler passes a this pointer to its child timer objects at their initialization, and so both classes require a forward declaration to one another, because each class declaration depends on the other. My improper use of forward declaration in this case is giving me an error.

For reference, this is the essence of & solution to my “Incomplete Type” error:

It makes perfect sense. I’m just learning about using Templates and the ways of inter-relating classes through Hierarchies and Friendship and Pointers and whatnot … This is a great and puzzling adventure! C++ is an infinite puzzle! So fun!

~Peace

I spent some time studying templates in C++, and this does solve my issue. I’ll spell it out here simply and explicitly, for reference.

The objects of the dependent class ‘Timer’ are created by the “parent” class ‘Scheduler’. Timers created by the scheduler trigger a threaded function at the completion of each period, and I wanted that thread to call a main function in the Scheduler class, so that it could take care of some house work. So I needed to store a pointer to the “parent” scheduler object within the Timer class that could point the timers to a ‘scheduler->update()’ function. In order to send a parent pointer to the Timer constructor, I had to create a template. The Timer class was parameterized, like this:

template< typename Parent >

class Timer: public ofThread {

public:
ofTimer thread;

Timer (Parent * parent) :
scheduler { parent },
newTimer { 0 }
{}
. . .

I also had to include ‘timer.h’ and forward declare the class, by repeating the template notation, like this:

template< typename Parent >
class Timer;
//--------

class Scheduler: public ofBaseApp {
. . .

Then when initializing timer objects and pointers to timer objects in the Scheduler class, I did it like this:

Timer< Scheduler > * timer;
. . .
timer = new Timer< Scheduler >(this);