Adjust lovrRelease signature;

This commit is contained in:
bjorn 2021-02-08 17:52:26 -07:00
parent 3ded60948f
commit bc4cde1653
39 changed files with 171 additions and 148 deletions

View File

@ -21,7 +21,7 @@ static int luax_meta__gc(lua_State* L) {
lua_getfield(L, -1, "__destructor");
destructorFn* destructor = (destructorFn*) lua_tocfunction(L, -1);
if (destructor) {
_lovrRelease(p->object, destructor);
lovrRelease(p->object, destructor);
p->object = NULL;
}
}

View File

@ -122,7 +122,7 @@ static int l_lovrAudioNewSource(lua_State* L) {
if (!soundData) {
Blob* blob = luax_readblob(L, 1, "Source");
soundData = lovrSoundDataCreateFromFile(blob, false);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
} else {
lovrRetain(soundData);
}
@ -136,8 +136,8 @@ static int l_lovrAudioNewSource(lua_State* L) {
Source* source = lovrSourceCreate(soundData, spatial);
luax_pushtype(L, Source, source);
lovrRelease(SoundData, soundData);
lovrRelease(Source, source);
lovrRelease(soundData, lovrSoundDataDestroy);
lovrRelease(source, lovrSourceDestroy);
return 1;
}

View File

@ -33,7 +33,7 @@ static int l_lovrDataNewBlob(lua_State* L) {
const char* name = luaL_optstring(L, 2, "");
Blob* blob = lovrBlobCreate(data, size, name);
luax_pushtype(L, Blob, blob);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
return 1;
}
@ -41,8 +41,8 @@ static int l_lovrDataNewModelData(lua_State* L) {
Blob* blob = luax_readblob(L, 1, "Model");
ModelData* modelData = lovrModelDataCreate(blob, luax_readfile);
luax_pushtype(L, ModelData, modelData);
lovrRelease(Blob, blob);
lovrRelease(ModelData, modelData);
lovrRelease(blob, lovrBlobDestroy);
lovrRelease(modelData, lovrModelDataDestroy);
return 1;
}
@ -59,8 +59,8 @@ static int l_lovrDataNewRasterizer(lua_State* L) {
Rasterizer* rasterizer = lovrRasterizerCreate(blob, size);
luax_pushtype(L, Rasterizer, rasterizer);
lovrRelease(Blob, blob);
lovrRelease(Rasterizer, rasterizer);
lovrRelease(blob, lovrBlobDestroy);
lovrRelease(rasterizer, lovrRasterizerDestroy);
return 1;
}
@ -77,7 +77,7 @@ static int l_lovrDataNewSoundData(lua_State* L) {
lovrSoundDataCreateStream(frames, format, channels, sampleRate) :
lovrSoundDataCreateRaw(frames, format, channels, sampleRate, blob);
luax_pushtype(L, SoundData, soundData);
lovrRelease(SoundData, soundData);
lovrRelease(soundData, lovrSoundDataDestroy);
return 1;
}
@ -85,8 +85,8 @@ static int l_lovrDataNewSoundData(lua_State* L) {
bool decode = lua_toboolean(L, 2);
SoundData* soundData = lovrSoundDataCreateFromFile(blob, decode);
luax_pushtype(L, SoundData, soundData);
lovrRelease(Blob, blob);
lovrRelease(SoundData, soundData);
lovrRelease(blob, lovrBlobDestroy);
lovrRelease(soundData, lovrSoundDataDestroy);
return 1;
}
@ -106,12 +106,12 @@ static int l_lovrDataNewTextureData(lua_State* L) {
Blob* blob = luax_readblob(L, 1, "Texture");
bool flip = lua_isnoneornil(L, 2) ? true : lua_toboolean(L, 2);
textureData = lovrTextureDataCreateFromBlob(blob, flip);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
}
}
luax_pushtype(L, TextureData, textureData);
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
return 1;
}

View File

@ -229,7 +229,7 @@ static int nextEvent(lua_State* L) {
case EVENT_THREAD_ERROR:
luax_pushtype(L, Thread, event.data.thread.thread);
lua_pushstring(L, event.data.thread.error);
lovrRelease(Thread, event.data.thread.thread);
lovrRelease(event.data.thread.thread, lovrThreadDestroy);
return 3;
#endif

View File

@ -271,7 +271,7 @@ static int l_lovrFilesystemNewBlob(lua_State* L) {
lovrAssert(data, "Could not load file '%s'", path);
Blob* blob = lovrBlobCreate(data, size, path);
luax_pushtype(L, Blob, blob);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
return 1;
}

View File

@ -311,7 +311,7 @@ static TextureData* luax_checktexturedata(lua_State* L, int index, bool flip) {
} else {
Blob* blob = luax_readblob(L, index, "Texture");
textureData = lovrTextureDataCreateFromBlob(blob, flip);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
}
return textureData;
@ -374,7 +374,7 @@ static int l_lovrGraphicsCreateWindow(lua_State* L) {
lovrGraphicsCreateWindow(&flags);
luax_atexit(L, lovrGraphicsDestroy); // The lua_State that creates the window shall be the one to destroy it
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
return 0;
}
@ -1220,12 +1220,12 @@ static int l_lovrGraphicsNewCanvas(lua_State* L) {
if (attachmentCount > 0) {
lovrCanvasSetAttachments(canvas, attachments, attachmentCount);
if (anonymous) {
lovrRelease(Texture, attachments[0].texture);
lovrRelease(attachments[0].texture, lovrTextureDestroy);
}
}
luax_pushtype(L, Canvas, canvas);
lovrRelease(Canvas, canvas);
lovrRelease(canvas, lovrCanvasDestroy);
return 1;
}
@ -1244,13 +1244,13 @@ static int l_lovrGraphicsNewFont(lua_State* L) {
}
rasterizer = lovrRasterizerCreate(blob, size);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
}
Font* font = lovrFontCreate(rasterizer);
luax_pushtype(L, Font, font);
lovrRelease(Rasterizer, rasterizer);
lovrRelease(Font, font);
lovrRelease(rasterizer, lovrRasterizerDestroy);
lovrRelease(font, lovrFontDestroy);
return 1;
}
@ -1264,9 +1264,9 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
TextureData* textureData = lovrTextureDataCreateFromBlob(blob, true);
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, true, 0);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
lovrRelease(Blob, blob);
lovrRelease(TextureData, textureData);
lovrRelease(Texture, texture);
lovrRelease(blob, lovrBlobDestroy);
lovrRelease(textureData, lovrTextureDataDestroy);
lovrRelease(texture, lovrTextureDestroy);
} else if (lua_isuserdata(L, index)) {
Texture* texture = luax_checktype(L, index, Texture);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
@ -1280,7 +1280,7 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
}
luax_pushtype(L, Material, material);
lovrRelease(Material, material);
lovrRelease(material, lovrMaterialDestroy);
return 1;
}
@ -1419,10 +1419,10 @@ static int l_lovrGraphicsNewMesh(lua_State* L) {
lovrBufferFlush(vertexBuffer, 0, count * stride);
lovrBufferUnmap(vertexBuffer);
lovrRelease(Buffer, vertexBuffer);
lovrRelease(vertexBuffer, lovrBufferDestroy);
luax_pushtype(L, Mesh, mesh);
lovrRelease(Mesh, mesh);
lovrRelease(mesh, lovrMeshDestroy);
return 1;
}
@ -1432,15 +1432,15 @@ static int l_lovrGraphicsNewModel(lua_State* L) {
if (!modelData) {
Blob* blob = luax_readblob(L, 1, "Model");
modelData = lovrModelDataCreate(blob, luax_readfile);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
} else {
lovrRetain(modelData);
}
Model* model = lovrModelCreate(modelData);
luax_pushtype(L, Model, model);
lovrRelease(ModelData, modelData);
lovrRelease(Model, model);
lovrRelease(modelData, lovrModelDataDestroy);
lovrRelease(model, lovrModelDestroy);
return 1;
}
@ -1554,7 +1554,7 @@ static int l_lovrGraphicsNewShader(lua_State* L) {
}
luax_pushtype(L, Shader, shader);
lovrRelease(Shader, shader);
lovrRelease(shader, lovrShaderDestroy);
return 1;
}
@ -1573,7 +1573,7 @@ static int l_lovrGraphicsNewComputeShader(lua_State* L) {
Shader* shader = lovrShaderCreateCompute(source, sourceLength, flags, flagCount);
luax_pushtype(L, Shader, shader);
lovrRelease(Shader, shader);
lovrRelease(shader, lovrShaderDestroy);
return 1;
}
@ -1632,8 +1632,8 @@ static int l_lovrGraphicsNewShaderBlock(lua_State* L) {
ShaderBlock* block = lovrShaderBlockCreate(type, buffer, &uniforms);
luax_pushtype(L, ShaderBlock, block);
arr_free(&uniforms);
lovrRelease(Buffer, buffer);
lovrRelease(ShaderBlock, block);
lovrRelease(buffer, lovrBufferDestroy);
lovrRelease(block, lovrShaderBlockDestroy);
return 1;
}
@ -1714,13 +1714,13 @@ static int l_lovrGraphicsNewTexture(lua_State* L) {
lovrTextureAllocate(texture, textureData->width, textureData->height, depth, textureData->format);
}
lovrTextureReplacePixels(texture, textureData, 0, 0, i, 0);
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
lua_pop(L, 1);
}
}
luax_pushtype(L, Texture, texture);
lovrRelease(Texture, texture);
lovrRelease(texture, lovrTextureDestroy);
return 1;
}

View File

@ -57,7 +57,7 @@ static int l_lovrCanvasNewTextureData(lua_State* L) {
lovrAssert(index < count, "Can not create a TextureData from Texture #%d of Canvas (it only has %d textures)", index, count);
TextureData* textureData = lovrCanvasNewTextureData(canvas, index);
luax_pushtype(L, TextureData, textureData);
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
return 1;
}

View File

@ -620,8 +620,8 @@ static int l_lovrHeadsetNewModel(lua_State* L) {
if (modelData) {
Model* model = lovrModelCreate(modelData);
luax_pushtype(L, Model, model);
lovrRelease(ModelData, modelData);
lovrRelease(Model, model);
lovrRelease(modelData, lovrModelDataDestroy);
lovrRelease(model, lovrModelDestroy);
return 1;
}

View File

@ -44,7 +44,7 @@ static const char* lovrVectorTypeNames[] = {
};
static void luax_destroypool(void) {
lovrRelease(Pool, pool);
lovrRelease(pool, lovrPoolDestroy);
}
float* luax_tovector(lua_State* L, int index, VectorType* type) {
@ -126,7 +126,7 @@ static int l_lovrMathNewCurve(lua_State* L) {
}
luax_pushtype(L, Curve, curve);
lovrRelease(Curve, curve);
lovrRelease(curve, lovrCurveDestroy);
return 1;
}
@ -137,7 +137,7 @@ static int l_lovrMathNewRandomGenerator(lua_State* L) {
lovrRandomGeneratorSetSeed(generator, seed);
}
luax_pushtype(L, RandomGenerator, generator);
lovrRelease(RandomGenerator, generator);
lovrRelease(generator, lovrRandomGeneratorDestroy);
return 1;
}

View File

@ -42,7 +42,7 @@ static int l_lovrPhysicsNewWorld(lua_State* L) {
}
World* world = lovrWorldCreate(xg, yg, zg, allowSleep, tags, tagCount);
luax_pushtype(L, World, world);
lovrRelease(World, world);
lovrRelease(world, lovrWorldDestroy);
return 1;
}
@ -53,7 +53,7 @@ static int l_lovrPhysicsNewBallJoint(lua_State* L) {
luax_readvec3(L, 3, anchor, NULL);
BallJoint* joint = lovrBallJointCreate(a, b, anchor[0], anchor[1], anchor[2]);
luax_pushtype(L, BallJoint, joint);
lovrRelease(Joint, joint);
lovrRelease(joint, lovrJointDestroy);
return 1;
}
@ -62,7 +62,7 @@ static int l_lovrPhysicsNewBoxShape(lua_State* L) {
luax_readscale(L, 1, size, 1, NULL);
BoxShape* box = lovrBoxShapeCreate(size[0], size[1], size[2]);
luax_pushtype(L, BoxShape, box);
lovrRelease(Shape, box);
lovrRelease(box, lovrShapeDestroy);
return 1;
}
@ -71,7 +71,7 @@ static int l_lovrPhysicsNewCapsuleShape(lua_State* L) {
float length = luax_optfloat(L, 2, 1.f);
CapsuleShape* capsule = lovrCapsuleShapeCreate(radius, length);
luax_pushtype(L, CapsuleShape, capsule);
lovrRelease(Shape, capsule);
lovrRelease(capsule, lovrShapeDestroy);
return 1;
}
@ -80,7 +80,7 @@ static int l_lovrPhysicsNewCylinderShape(lua_State* L) {
float length = luax_optfloat(L, 2, 1.f);
CylinderShape* cylinder = lovrCylinderShapeCreate(radius, length);
luax_pushtype(L, CylinderShape, cylinder);
lovrRelease(Shape, cylinder);
lovrRelease(cylinder, lovrShapeDestroy);
return 1;
}
@ -93,7 +93,7 @@ static int l_lovrPhysicsNewDistanceJoint(lua_State* L) {
DistanceJoint* joint = lovrDistanceJointCreate(a, b, anchor1[0], anchor1[1], anchor1[2],
anchor2[0], anchor2[1], anchor2[2]);
luax_pushtype(L, DistanceJoint, joint);
lovrRelease(Joint, joint);
lovrRelease(joint, lovrJointDestroy);
return 1;
}
@ -105,7 +105,7 @@ static int l_lovrPhysicsNewHingeJoint(lua_State* L) {
luax_readvec3(L, index, axis, NULL);
HingeJoint* joint = lovrHingeJointCreate(a, b, anchor[0], anchor[1], anchor[2], axis[0], axis[1], axis[2]);
luax_pushtype(L, HingeJoint, joint);
lovrRelease(Joint, joint);
lovrRelease(joint, lovrJointDestroy);
return 1;
}
@ -116,7 +116,7 @@ static int l_lovrPhysicsNewSliderJoint(lua_State* L) {
luax_readvec3(L, 3, axis, NULL);
SliderJoint* joint = lovrSliderJointCreate(a, b, axis[0], axis[1], axis[2]);
luax_pushtype(L, SliderJoint, joint);
lovrRelease(Joint, joint);
lovrRelease(joint, lovrJointDestroy);
return 1;
}
@ -124,7 +124,7 @@ static int l_lovrPhysicsNewSphereShape(lua_State* L) {
float radius = luax_optfloat(L, 1, 1.f);
SphereShape* sphere = lovrSphereShapeCreate(radius);
luax_pushtype(L, SphereShape, sphere);
lovrRelease(Shape, sphere);
lovrRelease(sphere, lovrShapeDestroy);
return 1;
}

View File

@ -44,7 +44,7 @@ static int l_lovrWorldNewCollider(lua_State* L) {
luax_readvec3(L, 2, position, NULL);
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(collider, lovrColliderDestroy);
return 1;
}
@ -58,8 +58,8 @@ static int l_lovrWorldNewBoxCollider(lua_State* L) {
lovrColliderAddShape(collider, shape);
lovrColliderInitInertia(collider, shape);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(Shape, shape);
lovrRelease(collider, lovrColliderDestroy);
lovrRelease(shape, lovrShapeDestroy);
return 1;
}
@ -74,8 +74,8 @@ static int l_lovrWorldNewCapsuleCollider(lua_State* L) {
lovrColliderAddShape(collider, shape);
lovrColliderInitInertia(collider, shape);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(Shape, shape);
lovrRelease(collider, lovrColliderDestroy);
lovrRelease(shape, lovrShapeDestroy);
return 1;
}
@ -90,8 +90,8 @@ static int l_lovrWorldNewCylinderCollider(lua_State* L) {
lovrColliderAddShape(collider, shape);
lovrColliderInitInertia(collider, shape);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(Shape, shape);
lovrRelease(collider, lovrColliderDestroy);
lovrRelease(shape, lovrShapeDestroy);
return 1;
}
@ -105,8 +105,8 @@ static int l_lovrWorldNewSphereCollider(lua_State* L) {
lovrColliderAddShape(collider, shape);
lovrColliderInitInertia(collider, shape);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(Shape, shape);
lovrRelease(collider, lovrColliderDestroy);
lovrRelease(shape, lovrShapeDestroy);
return 1;
}
@ -143,8 +143,8 @@ static int l_lovrWorldNewMeshCollider(lua_State* L) {
lovrColliderAddShape(collider, shape);
lovrColliderInitInertia(collider, shape);
luax_pushtype(L, Collider, collider);
lovrRelease(Collider, collider);
lovrRelease(Shape, shape);
lovrRelease(collider, lovrColliderDestroy);
lovrRelease(shape, lovrShapeDestroy);
return 1;
}

View File

@ -36,7 +36,7 @@ static int threadRunner(void* data) {
mtx_lock(&thread->lock);
thread->running = false;
mtx_unlock(&thread->lock);
lovrRelease(Thread, thread);
lovrRelease(thread, lovrThreadDestroy);
lua_close(L);
return 0;
}
@ -56,7 +56,7 @@ static int threadRunner(void* data) {
}
thread->running = false;
mtx_unlock(&thread->lock);
lovrRelease(Thread, thread);
lovrRelease(thread, lovrThreadDestroy);
lua_close(L);
return 1;
}
@ -81,8 +81,8 @@ static int l_lovrThreadNewThread(lua_State* L) {
}
Thread* thread = lovrThreadCreate(threadRunner, blob);
luax_pushtype(L, Thread, thread);
lovrRelease(Thread, thread);
lovrRelease(Blob, blob);
lovrRelease(thread, lovrThreadDestroy);
lovrRelease(blob, lovrBlobDestroy);
return 1;
}

View File

@ -61,5 +61,4 @@ static inline uint64_t hash64(const void* data, size_t length) {
// Refcounting
typedef atomic_uint ref_t;
#define lovrRetain(o) if (o) { atomic_fetch_add((ref_t*) (o), 1); }
#define lovrRelease(T, o) if (o && atomic_fetch_sub((ref_t*) (o), 1) == 1) lovr ## T ## Destroy(o), free(o);
#define _lovrRelease(o, f) if (o && atomic_fetch_sub((ref_t*) (o), 1) == 1) f(o), free(o);
#define lovrRelease(o, f) if (o && atomic_fetch_sub((ref_t*) (o), 1) == 1) f(o)

View File

@ -88,7 +88,7 @@ static void onPlayback(ma_device* device, void* out, const void* in, uint32_t co
if (!source->playing) {
*list = source->next;
source->tracked = false;
lovrRelease(Source, source);
lovrRelease(source, lovrSourceDestroy);
continue;
}
@ -215,7 +215,7 @@ void lovrAudioDestroy() {
}
ma_mutex_uninit(&state.lock);
ma_context_uninit(&state.context);
lovrRelease(SoundData, state.captureStream);
lovrRelease(state.captureStream, lovrSoundDataDestroy);
if (state.spatializer) state.spatializer->destroy();
for (size_t i = 0; i < state.converters.length; i++) {
ma_data_converter_uninit(state.converters.data[i]);
@ -270,7 +270,7 @@ bool lovrAudioSetDevice(AudioType type, void* id, size_t size, uint32_t sampleRa
config.capture.format = miniaudioFormats[format];
config.capture.channels = CAPTURE_CHANNELS;
config.capture.shareMode = exclusive ? ma_share_mode_exclusive : ma_share_mode_shared;
lovrRelease(SoundData, state.captureStream);
lovrRelease(state.captureStream, lovrSoundDataDestroy);
state.captureStream = lovrSoundDataCreateStream(sampleRate * 1., format, CAPTURE_CHANNELS, sampleRate);
}
@ -370,7 +370,8 @@ Source* lovrSourceCreate(SoundData* sound, bool spatial) {
void lovrSourceDestroy(void* ref) {
Source* source = ref;
state.spatializer->sourceDestroy(source);
lovrRelease(SoundData, source->sound);
lovrRelease(source->sound, lovrSoundDataDestroy);
free(source);
}
bool lovrSourcePlay(Source* source) {

View File

@ -14,4 +14,5 @@ Blob* lovrBlobCreate(void* data, size_t size, const char* name) {
void lovrBlobDestroy(void* ref) {
Blob* blob = ref;
free(blob->data);
free(blob);
}

View File

@ -21,15 +21,16 @@ ModelData* lovrModelDataCreate(Blob* source, ModelDataIO* io) {
void lovrModelDataDestroy(void* ref) {
ModelData* model = ref;
for (uint32_t i = 0; i < model->blobCount; i++) {
lovrRelease(Blob, model->blobs[i]);
lovrRelease(model->blobs[i], lovrBlobDestroy);
}
for (uint32_t i = 0; i < model->textureCount; i++) {
lovrRelease(TextureData, model->textures[i]);
lovrRelease(model->textures[i], lovrTextureDataDestroy);
}
map_free(&model->animationMap);
map_free(&model->materialMap);
map_free(&model->nodeMap);
free(model->data);
free(model);
}
// Note: this code is a scary optimization

View File

@ -661,7 +661,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
Blob* blob = lovrBlobCreate(buffer->data, buffer->size, NULL);
*texture = lovrTextureDataCreateFromBlob(blob, false);
blob->data = NULL; // XXX Blob data ownership
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
} else if (STR_EQ(key, "uri")) {
size_t size = 0;
gltfString uri = NOM_STR(json, token);
@ -672,7 +672,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
lovrAssert(data && size > 0, "Unable to read texture from '%s'", filename);
Blob* blob = lovrBlobCreate(data, size, NULL);
*texture = lovrTextureDataCreateFromBlob(blob, false);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
*root = '\0';
} else {
token += NOM_VALUE(json, token);

View File

@ -80,7 +80,7 @@ static void parseMtl(char* path, char* base, ModelDataIO* io, arr_texturedata_t*
material->filters[TEXTURE_DIFFUSE].mode = FILTER_TRILINEAR;
material->wraps[TEXTURE_DIFFUSE] = (TextureWrap) { .s = WRAP_REPEAT, .t = WRAP_REPEAT };
arr_push(textures, texture);
lovrRelease(Blob, blob);
lovrRelease(blob, lovrBlobDestroy);
}
next:

View File

@ -41,7 +41,8 @@ Rasterizer* lovrRasterizerCreate(Blob* blob, float size) {
void lovrRasterizerDestroy(void* ref) {
Rasterizer* rasterizer = ref;
lovrRelease(Blob, rasterizer->blob);
lovrRelease(rasterizer->blob, lovrBlobDestroy);
free(rasterizer);
}
bool lovrRasterizerHasGlyph(Rasterizer* rasterizer, uint32_t character) {

View File

@ -245,11 +245,12 @@ SoundData* lovrSoundDataCreateFromFile(struct Blob* blob, bool decode) {
void lovrSoundDataDestroy(void* ref) {
SoundData* soundData = (SoundData*) ref;
lovrRelease(Blob, soundData->blob);
lovrRelease(soundData->blob, lovrBlobDestroy);
if (soundData->read == lovrSoundDataReadOgg) stb_vorbis_close(soundData->decoder);
if (soundData->read == lovrSoundDataReadMp3) mp3dec_ex_close(soundData->decoder), free(soundData->decoder);
ma_pcm_rb_uninit(soundData->stream);
free(soundData->stream);
free(soundData);
}
Blob* lovrSoundDataGetBlob(SoundData* soundData) {

View File

@ -528,7 +528,7 @@ TextureData* lovrTextureDataCreateFromBlob(Blob* blob, bool flip) {
if (!textureData->blob->data) {
lovrThrow("Could not load texture data from '%s'", blob->name);
lovrRelease(Blob, textureData->blob);
lovrRelease(textureData->blob, lovrBlobDestroy);
free(textureData);
return NULL;
}
@ -751,7 +751,8 @@ void lovrTextureDataPaste(TextureData* textureData, TextureData* source, uint32_
void lovrTextureDataDestroy(void* ref) {
TextureData* textureData = ref;
lovrRelease(Blob, textureData->source);
lovrRelease(textureData->source, lovrBlobDestroy);
free(textureData->mipmaps);
lovrRelease(Blob, textureData->blob);
lovrRelease(textureData->blob, lovrBlobDestroy);
free(textureData);
}

View File

@ -42,7 +42,7 @@ static void onPermissionEvent(Permission permission, bool granted) {
void lovrVariantDestroy(Variant* variant) {
switch (variant->type) {
case TYPE_STRING: free(variant->value.string); return;
case TYPE_OBJECT: _lovrRelease(variant->value.object.pointer, variant->value.object.destructor); return;
case TYPE_OBJECT: lovrRelease(variant->value.object.pointer, variant->value.object.destructor); return;
default: return;
}
}
@ -62,7 +62,7 @@ void lovrEventDestroy() {
Event* event = &state.events.data[i];
switch (event->type) {
#ifndef LOVR_DISABLE_THREAD
case EVENT_THREAD_ERROR: lovrRelease(Thread, event->data.thread.thread); break;
case EVENT_THREAD_ERROR: lovrRelease(event->data.thread.thread, lovrThreadDestroy); break;
#endif
case EVENT_CUSTOM:
for (uint32_t j = 0; j < event->data.custom.count; j++) {

View File

@ -22,8 +22,9 @@ File* lovrFileInit(File* file ,const char* path) {
void lovrFileDestroy(void* ref) {
File* file = ref;
if (file->handle) {
lovrFileClose(ref);
lovrFileClose(file);
}
free(file);
}
bool lovrFileOpen(File* file, FileMode mode) {

View File

@ -83,14 +83,15 @@ Font* lovrFontCreate(Rasterizer* rasterizer) {
void lovrFontDestroy(void* ref) {
Font* font = ref;
lovrRelease(Rasterizer, font->rasterizer);
lovrRelease(Texture, font->texture);
lovrRelease(font->rasterizer, lovrRasterizerDestroy);
lovrRelease(font->texture, lovrTextureDestroy);
for (size_t i = 0; i < font->atlas.glyphs.length; i++) {
lovrRelease(TextureData, font->atlas.glyphs.data[i].data);
lovrRelease(font->atlas.glyphs.data[i].data, lovrTextureDataDestroy);
}
arr_free(&font->atlas.glyphs);
map_free(&font->atlas.glyphMap);
map_free(&font->kerning);
free(font);
}
Rasterizer* lovrFontGetRasterizer(Font* font) {
@ -370,10 +371,10 @@ static void lovrFontExpandTexture(Font* font) {
// TODO we only need the TextureData here to clear the texture, but it's a big waste of memory.
// Could look into using glClearTexImage when supported to make this more efficient.
static void lovrFontCreateTexture(Font* font) {
lovrRelease(Texture, font->texture);
lovrRelease(font->texture, lovrTextureDestroy);
TextureData* textureData = lovrTextureDataCreate(font->atlas.width, font->atlas.height, NULL, 0x0, FORMAT_RGB);
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, false, false, 0);
lovrTextureSetFilter(font->texture, (TextureFilter) { .mode = FILTER_BILINEAR });
lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP });
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
}

View File

@ -199,18 +199,18 @@ void lovrGraphicsDestroy() {
lovrGraphicsSetFont(NULL);
lovrGraphicsSetCanvas(NULL);
for (int i = 0; i < MAX_DEFAULT_SHADERS; i++) {
lovrRelease(Shader, state.defaultShaders[i][false]);
lovrRelease(Shader, state.defaultShaders[i][true]);
lovrRelease(state.defaultShaders[i][false], lovrShaderDestroy);
lovrRelease(state.defaultShaders[i][true], lovrShaderDestroy);
}
for (int i = 0; i < MAX_STREAMS; i++) {
lovrRelease(Buffer, state.buffers[i]);
lovrRelease(state.buffers[i], lovrBufferDestroy);
}
lovrRelease(Mesh, state.mesh);
lovrRelease(Mesh, state.instancedMesh);
lovrRelease(Buffer, state.identityBuffer);
lovrRelease(Material, state.defaultMaterial);
lovrRelease(Font, state.defaultFont);
lovrRelease(Canvas, state.defaultCanvas);
lovrRelease(state.mesh, lovrMeshDestroy);
lovrRelease(state.instancedMesh, lovrMeshDestroy);
lovrRelease(state.identityBuffer, lovrBufferDestroy);
lovrRelease(state.defaultMaterial, lovrMaterialDestroy);
lovrRelease(state.defaultFont, lovrFontDestroy);
lovrRelease(state.defaultCanvas, lovrCanvasDestroy);
lovrGpuDestroy();
memset(&state, 0, sizeof(state));
}
@ -412,7 +412,7 @@ void lovrGraphicsSetCanvas(Canvas* canvas) {
}
lovrRetain(canvas);
lovrRelease(Canvas, state.canvas);
lovrRelease(state.canvas, lovrCanvasDestroy);
state.canvas = canvas;
}
@ -467,7 +467,7 @@ Font* lovrGraphicsGetFont() {
if (!state.defaultFont) {
Rasterizer* rasterizer = lovrRasterizerCreate(NULL, 32);
state.defaultFont = lovrFontCreate(rasterizer);
lovrRelease(Rasterizer, rasterizer);
lovrRelease(rasterizer, lovrRasterizerDestroy);
}
lovrGraphicsSetFont(state.defaultFont);
@ -478,7 +478,7 @@ Font* lovrGraphicsGetFont() {
void lovrGraphicsSetFont(Font* font) {
lovrRetain(font);
lovrRelease(Font, state.font);
lovrRelease(state.font, lovrFontDestroy);
state.font = font;
}
@ -505,7 +505,7 @@ Shader* lovrGraphicsGetShader() {
void lovrGraphicsSetShader(Shader* shader) {
lovrAssert(!shader || lovrShaderGetType(shader) == SHADER_GRAPHICS, "Compute shaders can not be set as the active shader");
lovrRetain(shader);
lovrRelease(Shader, state.shader);
lovrRelease(state.shader, lovrShaderDestroy);
state.shader = shader;
}

View File

@ -31,8 +31,9 @@ void lovrMaterialDestroy(void* ref) {
Material* material = ref;
lovrGraphicsFlushMaterial(material);
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
lovrRelease(Texture, material->textures[i]);
lovrRelease(material->textures[i], lovrTextureDestroy);
}
free(material);
}
void lovrMaterialBind(Material* material, Shader* shader) {
@ -81,7 +82,7 @@ void lovrMaterialSetTexture(Material* material, MaterialTexture textureType, Tex
if (material->textures[textureType] != texture) {
lovrGraphicsFlushMaterial(material);
lovrRetain(texture);
lovrRelease(Texture, material->textures[textureType]);
lovrRelease(material->textures[textureType], lovrTextureDestroy);
material->textures[textureType] = texture;
}
}

View File

@ -201,35 +201,36 @@ void lovrModelDestroy(void* ref) {
if (model->buffers) {
for (uint32_t i = 0; i < model->data->bufferCount; i++) {
lovrRelease(Buffer, model->buffers[i]);
lovrRelease(model->buffers[i], lovrBufferDestroy);
}
free(model->buffers);
}
if (model->meshes) {
for (uint32_t i = 0; i < model->data->primitiveCount; i++) {
lovrRelease(Mesh, model->meshes[i]);
lovrRelease(model->meshes[i], lovrMeshDestroy);
}
free(model->meshes);
}
if (model->textures) {
for (uint32_t i = 0; i < model->data->textureCount; i++) {
lovrRelease(Texture, model->textures[i]);
lovrRelease(model->textures[i], lovrTextureDestroy);
}
free(model->textures);
}
if (model->materials) {
for (uint32_t i = 0; i < model->data->materialCount; i++) {
lovrRelease(Material, model->materials[i]);
lovrRelease(model->materials[i], lovrMaterialDestroy);
}
free(model->materials);
}
lovrRelease(ModelData, model->data);
lovrRelease(model->data, lovrModelDataDestroy);
free(model->globalTransforms);
free(model->localTransforms);
free(model);
}
ModelData* lovrModelGetModelData(Model* model) {

View File

@ -754,7 +754,7 @@ static void lovrGpuBindTexture(Texture* texture, int slot) {
if (texture != state.textures[slot]) {
lovrRetain(texture);
lovrRelease(Texture, state.textures[slot]);
lovrRelease(state.textures[slot], lovrTextureDestroy);
state.textures[slot] = texture;
if (state.activeTexture != slot) {
glActiveTexture(GL_TEXTURE0 + slot);
@ -783,7 +783,7 @@ static void lovrGpuBindImage(Image* image, int slot, const char* name) {
int slice = layered ? 0 : image->slice;
lovrRetain(texture);
lovrRelease(Texture, state.images[slot].texture);
lovrRelease(state.images[slot].texture, lovrTextureDestroy);
glBindImageTexture(slot, texture->id, image->mipmap, layered, slice, glAccess, glFormat);
memcpy(state.images + slot, image, sizeof(Image));
}
@ -1351,7 +1351,7 @@ void lovrGpuInit(void* (*getProcAddress)(const char*), bool debug) {
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false, 0);
lovrTextureSetFilter(state.defaultTexture, (TextureFilter) { .mode = FILTER_NEAREST });
lovrTextureSetWrap(state.defaultTexture, (TextureWrap) { WRAP_CLAMP, WRAP_CLAMP, WRAP_CLAMP });
lovrRelease(TextureData, textureData);
lovrRelease(textureData, lovrTextureDataDestroy);
map_init(&state.timerMap, 4);
state.queryPool.next = ~0u;
@ -1359,12 +1359,12 @@ void lovrGpuInit(void* (*getProcAddress)(const char*), bool debug) {
}
void lovrGpuDestroy() {
lovrRelease(Texture, state.defaultTexture);
lovrRelease(state.defaultTexture, lovrTextureDestroy);
for (int i = 0; i < MAX_TEXTURES; i++) {
lovrRelease(Texture, state.textures[i]);
lovrRelease(state.textures[i], lovrTextureDestroy);
}
for (int i = 0; i < MAX_IMAGES; i++) {
lovrRelease(Texture, state.images[i].texture);
lovrRelease(state.images[i].texture, lovrTextureDestroy);
}
for (int i = 0; i < MAX_BARRIERS; i++) {
arr_free(&state.incoherents[i]);
@ -1520,7 +1520,7 @@ void lovrGpuStencil(StencilAction action, int replaceValue, StencilCallback call
}
void lovrGpuDirtyTexture() {
lovrRelease(Texture, state.textures[state.activeTexture]);
lovrRelease(state.textures[state.activeTexture], lovrTextureDestroy);
state.textures[state.activeTexture] = NULL;
}
@ -1739,6 +1739,7 @@ void lovrTextureDestroy(void* ref) {
lovrGpuDestroySyncResource(texture, texture->incoherent);
state.stats.textureMemory -= getTextureMemorySize(texture);
state.stats.textureCount--;
free(texture);
}
void lovrTextureAllocate(Texture* texture, uint32_t width, uint32_t height, uint32_t depth, TextureFormat format) {
@ -2058,9 +2059,10 @@ void lovrCanvasDestroy(void* ref) {
glDeleteFramebuffers(1, &canvas->resolveBuffer);
}
for (uint32_t i = 0; i < canvas->attachmentCount; i++) {
lovrRelease(Texture, canvas->attachments[i].texture);
lovrRelease(canvas->attachments[i].texture, lovrTextureDestroy);
}
lovrRelease(Texture, canvas->depth.texture);
lovrRelease(canvas->depth.texture, lovrTextureDestroy);
free(canvas);
}
void lovrCanvasResolve(Canvas* canvas) {
@ -2171,7 +2173,7 @@ void lovrCanvasSetAttachments(Canvas* canvas, Attachment* attachments, uint32_t
}
for (uint32_t i = 0; i < canvas->attachmentCount; i++) {
lovrRelease(Texture, canvas->attachments[i].texture);
lovrRelease(canvas->attachments[i].texture, lovrTextureDestroy);
}
memcpy(canvas->attachments, attachments, count * sizeof(Attachment));
@ -2252,6 +2254,7 @@ void lovrBufferDestroy(void* ref) {
#endif
state.stats.bufferMemory -= buffer->size;
state.stats.bufferCount--;
free(buffer);
}
size_t lovrBufferGetSize(Buffer* buffer) {
@ -2741,7 +2744,7 @@ void lovrShaderDestroy(void* ref) {
}
for (BlockType type = BLOCK_UNIFORM; type <= BLOCK_COMPUTE; type++) {
for (size_t i = 0; i < shader->blocks[type].length; i++) {
lovrRelease(Buffer, shader->blocks[type].data[i].source);
lovrRelease(shader->blocks[type].data[i].source, lovrBufferDestroy);
arr_free(&shader->blocks[type].data[i].uniforms);
}
}
@ -2751,6 +2754,7 @@ void lovrShaderDestroy(void* ref) {
map_free(&shader->attributes);
map_free(&shader->uniformMap);
map_free(&shader->blockMap);
free(shader);
}
ShaderType lovrShaderGetType(Shader* shader) {
@ -2832,7 +2836,7 @@ void lovrShaderSetBlock(Shader* shader, const char* name, Buffer* buffer, size_t
if (block->source != buffer || block->offset != offset || block->size != size) {
lovrGraphicsFlushShader(shader);
lovrRetain(buffer);
lovrRelease(Buffer, block->source);
lovrRelease(block->source, lovrBufferDestroy);
block->access = access;
block->source = buffer;
block->offset = offset;
@ -2884,9 +2888,10 @@ ShaderBlock* lovrShaderBlockCreate(BlockType type, Buffer* buffer, arr_uniform_t
void lovrShaderBlockDestroy(void* ref) {
ShaderBlock* block = ref;
lovrRelease(Buffer, block->buffer);
lovrRelease(block->buffer, lovrBufferDestroy);
arr_free(&block->uniforms);
map_free(&block->uniformMap);
free(block);
}
BlockType lovrShaderBlockGetType(ShaderBlock* block) {
@ -2974,19 +2979,20 @@ void lovrMeshDestroy(void* ref) {
lovrGraphicsFlushMesh(mesh);
glDeleteVertexArrays(1, &mesh->vao);
for (uint32_t i = 0; i < mesh->attributeCount; i++) {
lovrRelease(Buffer, mesh->attributes[i].buffer);
lovrRelease(mesh->attributes[i].buffer, lovrBufferDestroy);
}
map_free(&mesh->attributeMap);
lovrRelease(Buffer, mesh->vertexBuffer);
lovrRelease(Buffer, mesh->indexBuffer);
lovrRelease(Material, mesh->material);
lovrRelease(mesh->vertexBuffer, lovrBufferDestroy);
lovrRelease(mesh->indexBuffer, lovrBufferDestroy);
lovrRelease(mesh->material, lovrMaterialDestroy);
free(mesh);
}
void lovrMeshSetIndexBuffer(Mesh* mesh, Buffer* buffer, uint32_t indexCount, size_t indexSize, size_t offset) {
if (mesh->indexBuffer != buffer || mesh->indexCount != indexCount || mesh->indexSize != indexSize) {
lovrGraphicsFlushMesh(mesh);
lovrRetain(buffer);
lovrRelease(Buffer, mesh->indexBuffer);
lovrRelease(mesh->indexBuffer, lovrBufferDestroy);
mesh->indexBuffer = buffer;
mesh->indexCount = indexCount;
mesh->indexSize = indexSize;
@ -3037,7 +3043,7 @@ void lovrMeshDetachAttribute(Mesh* mesh, const char* name) {
lovrAssert(index != MAP_NIL, "No attached attribute named '%s' was found", name);
MeshAttribute* attribute = &mesh->attributes[index];
lovrGraphicsFlushMesh(mesh);
lovrRelease(Buffer, attribute->buffer);
lovrRelease(attribute->buffer, lovrBufferDestroy);
map_remove(&mesh->attributeMap, hash);
mesh->attributeNames[index][0] = '\0';
memmove(mesh->attributeNames + index, mesh->attributeNames + index + 1, (mesh->attributeCount - index - 1) * MAX_ATTRIBUTE_NAME_LENGTH * sizeof(char));
@ -3110,6 +3116,6 @@ Material* lovrMeshGetMaterial(Mesh* mesh) {
void lovrMeshSetMaterial(Mesh* mesh, Material* material) {
lovrRetain(material);
lovrRelease(Material, mesh->material);
lovrRelease(mesh->material, lovrMaterialDestroy);
mesh->material = material;
}

View File

@ -111,7 +111,7 @@ static bool oculus_init(float supersample, float offset, uint32_t msaa) {
static void oculus_destroy(void) {
for (size_t i = 0; i < state.textures.length; i++) {
lovrRelease(Texture, state.textures.data[i]);
lovrRelease(state.textures.data[i], lovrTextureDestroy);
}
map_free(&state.textureLookup);
@ -125,7 +125,7 @@ static void oculus_destroy(void) {
state.chain = NULL;
}
lovrRelease(Canvas, state.canvas);
lovrRelease(state.canvas, lovrCanvasDestroy);
ovr_Destroy(state.session);
ovr_Shutdown();
memset(&state, 0, sizeof(state));

View File

@ -256,7 +256,7 @@ static bool openvr_init(float supersample, float offset, uint32_t msaa) {
}
static void openvr_destroy(void) {
lovrRelease(Canvas, state.canvas);
lovrRelease(state.canvas, lovrCanvasDestroy);
VR_ShutdownInternal();
free(state.mask);
memset(&state, 0, sizeof(state));
@ -816,7 +816,7 @@ static void openvr_renderTo(void (*callback)(void*), void* userdata) {
lovrTextureAllocate(texture, width * 2, height, 1, FORMAT_RGBA);
lovrTextureSetFilter(texture, lovrGraphicsGetDefaultFilter());
lovrCanvasSetAttachments(state.canvas, &(Attachment) { texture, 0, 0 }, 1);
lovrRelease(Texture, texture);
lovrRelease(texture, lovrTextureDestroy);
lovrPlatformSetSwapInterval(0);
}

View File

@ -479,7 +479,7 @@ static bool openxr_init(float supersample, float offset, uint32_t msaa) {
Texture* texture = lovrTextureCreateFromHandle(images[i].image, textureType, arraySize, state.msaa);
state.canvases[i] = lovrCanvasCreate(state.width, state.height, flags);
lovrCanvasSetAttachments(state.canvases[i], &(Attachment) { texture, 0, 0 }, 1);
lovrRelease(Texture, texture);
lovrRelease(texture, lovrTextureDestroy);
}
// Pre-init composition layer
@ -516,7 +516,7 @@ static bool openxr_init(float supersample, float offset, uint32_t msaa) {
static void openxr_destroy(void) {
for (uint32_t i = 0; i < state.imageCount; i++) {
lovrRelease(Canvas, state.canvases[i]);
lovrRelease(state.canvases[i], lovrCanvasDestroy);
}
for (size_t i = 0; i < MAX_ACTIONS; i++) {

View File

@ -80,7 +80,7 @@ static void vrapi_destroy() {
vrapi_DestroyTextureSwapChain(state.swapchain);
vrapi_Shutdown();
for (uint32_t i = 0; i < 3; i++) {
lovrRelease(Canvas, state.canvases[i]);
lovrRelease(state.canvases[i], lovrCanvasDestroy);
}
free(state.rawBoundaryPoints);
free(state.boundaryPoints);
@ -686,7 +686,7 @@ static void vrapi_renderTo(void (*callback)(void*), void* userdata) {
uint32_t handle = vrapi_GetTextureSwapChainHandle(state.swapchain, i);
Texture* texture = lovrTextureCreateFromHandle(handle, TEXTURE_ARRAY, 2, 1);
lovrCanvasSetAttachments(state.canvases[i], &(Attachment) { .texture = texture }, 1);
lovrRelease(Texture, texture);
lovrRelease(texture, lovrTextureDestroy);
}
}

View File

@ -62,6 +62,7 @@ Curve* lovrCurveCreate(void) {
void lovrCurveDestroy(void* ref) {
Curve* curve = ref;
arr_free(&curve->points);
free(curve);
}
void lovrCurveEvaluate(Curve* curve, float t, vec3 p) {

View File

@ -23,7 +23,7 @@ bool lovrMathInit() {
void lovrMathDestroy() {
if (!state.initialized) return;
lovrRelease(RandomGenerator, state.generator);
lovrRelease(state.generator, lovrRandomGeneratorDestroy);
memset(&state, 0, sizeof(state));
}

View File

@ -21,6 +21,7 @@ Pool* lovrPoolCreate() {
void lovrPoolDestroy(void* ref) {
Pool* pool = ref;
free(pool->data);
free(pool);
}
void lovrPoolGrow(Pool* pool, size_t count) {

View File

@ -40,7 +40,7 @@ RandomGenerator* lovrRandomGeneratorCreate(void) {
}
void lovrRandomGeneratorDestroy(void* ref) {
//
free(ref);
}
Seed lovrRandomGeneratorGetSeed(RandomGenerator* generator) {

View File

@ -80,6 +80,7 @@ void lovrWorldDestroy(void* ref) {
for (uint32_t i = 0; i < MAX_TAGS && world->tags[i]; i++) {
free(world->tags[i]);
}
free(world);
}
void lovrWorldDestroyData(World* world) {
@ -325,6 +326,7 @@ void lovrColliderDestroy(void* ref) {
lovrColliderDestroyData(collider);
arr_free(&collider->shapes);
arr_free(&collider->joints);
free(collider);
}
void lovrColliderDestroyData(Collider* collider) {
@ -341,7 +343,7 @@ void lovrColliderDestroyData(Collider* collider) {
Joint** joints = lovrColliderGetJoints(collider, &count);
for (size_t i = 0; i < count; i++) {
lovrRelease(Joint, joints[i]);
lovrRelease(joints[i], lovrJointDestroy);
}
dBodyDestroy(collider->body);
@ -353,7 +355,7 @@ void lovrColliderDestroyData(Collider* collider) {
collider->next = collider->prev = NULL;
// If the Collider is destroyed, the world lets go of its reference to this Collider
lovrRelease(Collider, collider);
lovrRelease(collider, lovrColliderDestroy);
}
void lovrColliderInitInertia(Collider* collider, Shape* shape) {
@ -386,7 +388,7 @@ void lovrColliderRemoveShape(Collider* collider, Shape* shape) {
dSpaceRemove(collider->world->space, shape->id);
dGeomSetBody(shape->id, 0);
shape->collider = NULL;
lovrRelease(Shape, shape);
lovrRelease(shape, lovrShapeDestroy);
}
}
@ -688,6 +690,7 @@ void lovrColliderGetAABB(Collider* collider, float aabb[6]) {
void lovrShapeDestroy(void* ref) {
Shape* shape = ref;
lovrShapeDestroyData(shape);
free(shape);
}
void lovrShapeDestroyData(Shape* shape) {
@ -938,6 +941,7 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount
void lovrJointDestroy(void* ref) {
Joint* joint = ref;
lovrJointDestroyData(joint);
free(joint);
}
void lovrJointDestroyData(Joint* joint) {

View File

@ -35,6 +35,7 @@ void lovrChannelDestroy(void* ref) {
arr_free(&channel->messages);
mtx_destroy(&channel->lock);
cnd_destroy(&channel->cond);
free(channel);
}
bool lovrChannelPush(Channel* channel, Variant* variant, double timeout, uint64_t* id) {
@ -82,7 +83,7 @@ bool lovrChannelPop(Channel* channel, Variant* variant, double timeout) {
*variant = channel->messages.data[channel->head++];
if (channel->head == channel->messages.length) {
channel->head = channel->messages.length = 0;
lovrRelease(Channel, channel);
lovrRelease(channel, lovrChannelDestroy);
}
channel->received++;
cnd_broadcast(&channel->cond);

View File

@ -29,7 +29,7 @@ void lovrThreadModuleDestroy() {
for (size_t i = 0; i < state.channels.size; i++) {
if (state.channels.values[i] != MAP_NIL) {
ChannelEntry entry = { state.channels.values[i] };
lovrRelease(Channel, entry.channel);
lovrRelease(entry.channel, lovrChannelDestroy);
}
}
mtx_destroy(&state.channelLock);
@ -67,8 +67,9 @@ void lovrThreadDestroy(void* ref) {
Thread* thread = ref;
mtx_destroy(&thread->lock);
thrd_detach(thread->handle);
lovrRelease(Blob, thread->body);
lovrRelease(thread->body, lovrBlobDestroy);
free(thread->error);
free(thread);
}
void lovrThreadStart(Thread* thread, Variant* arguments, uint32_t argumentCount) {