Using Unity functions inside VLC events
Summary
Unity's a single-threaded application and fussy about it. Most Unity functions (things ranging from GameObject.transform to Texture.width) can only run on the main thread. VLC events run on a different thread, so you can't use most Unity functions inside a VLC event. If you try, they throw an exception (which you have to catch to avoid a potential freeze or crash, so potentially this could do some damage.)
I don't think this is a bug at all. But it's a pain and it comes up frequently and I think it is worth discussing how we want people to handle it.
Possible solutions:
Obviously ideally this would just work. But we can't fix Unity's stupid architecture, and I doubt we can make VLC events run on the main thread, so I'm pretty sure we just have write our Unity-side code to handle this.
Currently in the new demo, we do this by setting a boolean flag, and then handling that flag in the next Update:
vlcPlayer.mediaPlayer.Stopped += (object sender, EventArgs e) => {
//Always use Try/Catch for VLC Events
try
{
_shouldClearTracks = true;//Clear tracks next update
}
catch (Exception ex)
{
Debug.LogError("Exception caught in mediaPlayer.Stopped: \n" + ex.ToString());
}
};
void Update()
{
if (_shouldClearTracks)
{
ClearTrackButtons();
_shouldClearTracks = false;
}
}
This works, at least so far, but it's not very elegant especially if you have more than one or two of these in your script.
A more reusable solution might be a queue of actions -- every time an event fires we add any actions that need to be performed in Unity to the queue, and and every Unity update we pop whatever is in the queue and run it. That doesn't sound so bad, but I don't know much about working with multiple threads, and I know communicating between them can get quite complicated, so I am not sure if this is safe, and even if it is, there might be a better way.
What do you think?