ChangeListener add failed

I was trying to call transportSource.addChangeListener(), but then i get assertion error:

Here’s how i called it:

And obviously, the changeListenerCallback() did not get called. Thanks for any help

Have you tried the MessageManagerLock like the comment above the assert so helpfully suggests?

1 Like

Not exactly related to the question, but shouldn’t you wait to call startThread() until the very end of the constructor, (or even later, via a call to the fully-constructed object), so that if the thread starts working, you know that everything has finished initializing?

1 Like

Yes, i called the constructor of MessageManagerLock but it get in a loop of assertion error somehow

It looks like you’re adding a change listener from inside the TimeSliceClient’s run function. Rather than messing around with MessageManager locks, it would be a much better idea to make sure that listeners are only added and removed from the message thread. You can safely call listeners from any thread after doing that.

Looking at the code you shared, I wonder whether the addChangeListener() call in question is actually coming from somewhere else (since this constructor will probably execute on the message thread). Take a look at your stack frame and see.

I also remove the TimeSliceThread as the base class, but the result is still the same

Can you show us your stack frame when the assertion happens?

I dont know how to debug it since it a cross-platform library, everything i’ve got is just this trace (TimeSliceThread removed and MessageManagerLock called):

That’s the error list window. There must be a stack frame window somewhere. When the program hits an assertion, it will tell you what function you’re currently in, and what function called that function, etc.

Trace it myself and this is the function trigger assertion error:
Still in the constructor of my MediaController

In what thread are you constructing the MediaController?

I just call it normally no new thread created

it could still be a different thread than what Juce expects (the main/message/GUI thread) even if you don’t explicitly create a new thread yourself. What’s the context you are trying to do this in?

I checked the thread that created the controller and it return null:

And seems like null means its the main thread

Have you actually initialized/started the Juce MessageManager in your code? That would typically happen automatically in GUI apps/plugins, but there are some other cases where it wouldn’t happen.

Oh i haven’t, i’m not using GUI components so guess that’s the problem, do i just call it like this to initialize? juce::MessageManager::getInstance()->setCurrentThreadAsMessageThread();

You’d need to use the initialiseJuce_GUI and shutdownJuce_GUI function calls or the ScopedJuceInitialiser_GUI class. Those are a bit confusing because they are required even in non-GUI contexts if you are going to use the MessageManager features.

I’ve put it in but still ended up with assertion error:

I am not sure what are you expecting to happen with that? You are just creating and immediately destroying the GUI initializer, before you even call your own code.

Oh sorry I thought it would initialize something :sob: