Free thunk entry in the object destructor
[openal-soft.git] / OpenAL32 / alInstrument.c
blobdfcb93ba281b3a41d5da2bedca4db5b000bf45ba
2 #include "config.h"
4 #include <stdlib.h>
5 #include <string.h>
7 #include "alMain.h"
8 #include "alMidi.h"
9 #include "alError.h"
10 #include "alThunk.h"
12 #include "midi/base.h"
15 extern inline struct ALsfinstrument *LookupInstrument(ALCdevice *device, ALuint id);
16 extern inline struct ALsfinstrument *RemoveInstrument(ALCdevice *device, ALuint id);
19 AL_API void AL_APIENTRY alGenInstrumentsSOFT(ALsizei n, ALuint *ids)
21 ALCdevice *device;
22 ALCcontext *context;
23 ALsizei cur = 0;
24 ALenum err;
26 context = GetContextRef();
27 if(!context) return;
29 if(!(n >= 0))
30 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
32 device = context->Device;
33 for(cur = 0;cur < n;cur++)
35 ALsfinstrument *inst = calloc(1, sizeof(ALsfinstrument));
36 if(!inst)
38 alDeleteInstrumentsSOFT(cur, ids);
39 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
41 ALsfinstrument_Construct(inst);
43 err = NewThunkEntry(&inst->id);
44 if(err == AL_NO_ERROR)
45 err = InsertUIntMapEntry(&device->InstrumentMap, inst->id, inst);
46 if(err != AL_NO_ERROR)
48 ALsfinstrument_Destruct(inst);
49 memset(inst, 0, sizeof(*inst));
50 free(inst);
52 alDeleteInstrumentsSOFT(cur, ids);
53 SET_ERROR_AND_GOTO(context, err, done);
56 ids[cur] = inst->id;
59 done:
60 ALCcontext_DecRef(context);
63 AL_API ALvoid AL_APIENTRY alDeleteInstrumentsSOFT(ALsizei n, const ALuint *ids)
65 ALCdevice *device;
66 ALCcontext *context;
67 ALsfinstrument *inst;
68 ALsizei i;
70 context = GetContextRef();
71 if(!context) return;
73 if(!(n >= 0))
74 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
76 device = context->Device;
77 for(i = 0;i < n;i++)
79 if(!ids[i])
80 continue;
82 /* Check for valid ID */
83 if((inst=LookupInstrument(device, ids[i])) == NULL)
84 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
85 if(inst->ref != 0)
86 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
89 for(i = 0;i < n;i++)
91 if((inst=RemoveInstrument(device, ids[i])) == NULL)
92 continue;
94 ALsfinstrument_Destruct(inst);
96 memset(inst, 0, sizeof(*inst));
97 free(inst);
100 done:
101 ALCcontext_DecRef(context);
104 AL_API ALboolean AL_APIENTRY alIsInstrumentSOFT(ALuint id)
106 ALCcontext *context;
107 ALboolean ret;
109 context = GetContextRef();
110 if(!context) return AL_FALSE;
112 ret = ((!id || LookupInstrument(context->Device, id)) ?
113 AL_TRUE : AL_FALSE);
115 ALCcontext_DecRef(context);
117 return ret;
121 /* ReleaseALInstruments
123 * Called to destroy any instruments that still exist on the device
125 void ReleaseALInstruments(ALCdevice *device)
127 ALsizei i;
128 for(i = 0;i < device->InstrumentMap.size;i++)
130 ALsfinstrument *temp = device->InstrumentMap.array[i].value;
131 device->InstrumentMap.array[i].value = NULL;
133 ALsfinstrument_Destruct(temp);
135 memset(temp, 0, sizeof(*temp));
136 free(temp);