EventDescription and EventInstance caching in C++

Q1: Does FMOD Studio cache EventDescription objects internally or is it loading from disk every time I call System::getEvent()?

Q2: Does EventInstance support copy by value? For example, a sound plays with the following code:

FMOD::Studio::EventInstance eventInstance;
eventDescription.createInstance(&eventInstance);

FMOD::Studio::EventInstance copy = eventInstance;
copy.start();

However, when I used this trick, FMOD would crash when I called System::release(). Should I avoid copying and instead rely on allocating heap memory for long term EventInstance objects?

Currently it caches them internally when you load the bank, so getEvent() doesn’t read anything from disk.

You can copy EventInstance handles like that, but they will both refer to the same event instance internally. If you want more than one event instance, you need to call createInstance() multiple times.

This shouldn’t cause a crash - sorry about that! We’ll look into it.

I haven’t been able to reproduce this crash here. Could you email a code sample that causes the crash to support@fmod.org so we can look into it?

Thanks for the clarifications! The code I had that took advantage of copying EventInstances was mixed in with other game systems so it’s possible that it was something else. When I have time I’ll try to create a simplified version that reproduces the problem.

I discovered that the crash occurs when calling EventDescription::createInstance on an uninitialized block of memory. I am using Lua userdata to store my FMOD EventInstances, which doesn’t initialize the memory when it is allocated. I have to use placement new to explicitly construct the EventInstance, at which point I can use it safely.

Here is the relevant code, for anyone else who might run into this issue:

FmodEventInstanceUserData* udata = static_cast<FmodEventInstanceUserData*>(lua_newuserdata(L, sizeof(FmodEventInstanceUserData)));
new (&udata->instance) FMOD::Studio::EventInstance();
ERRCHECK( eventDescription.createInstance(&udata->instance) );

Good to hear you have solved your problem. Are you exposing the EventInstance API to lua script? If so, you should also try to ensure the script calls the release() function when finished with the sound.

Also, you will want to set up a finalizer in lua that explicitly calls the EventInstance destructor, as explained here:

http://www.lua.org/manual/5.1/manual.html#2.10.1

In fact it should call release() and then the destructor. That will catch cases where the script isn’t calling release() and just letting your userdata go free, although since it is tied to garbage collection it may not happen in a particularly timely fashion. That isn’t a big deal but it could mean a few extra memory allocations hang around for longer than they might otherwise.

Let us know if you have any further issues.

Hey geoff, thanks for the advice! I am calling release() in the __gc metamethod like you suggest.

However, unless I’m missing something, I don’t think I can call the EventInstance destructor myself. According to fmod_studio.hpp, the EventInstance inherits its destructor from Handle, which in turn has a protected destructor that I can’t access. I assume C++ generates a default destructor for EventInstance but I can’t seem to access that either.

You should be able to access the EventInstance destructor as in the following:

udata->instance.~EventInstance();

Ah, my problem was that I’m not using the FMOD namespace. Apparently it’s not possible to explicitly call destructors of objects unless you import the namespace.

This DOESNT work:

instance.~FMOD::Studio::EventInstance();

Here is what I needed to do to get it to work:

{
  using namespace FMOD::Studio;
  instance.~EventInstance();
}

Thanks for the help!