/* A stand-in for a library that hands out resources the way raylib does, for * programs/res-leaks.flan. Nothing here needs a window or a library * installed. Two names are raylib's own — GetClipboardImage and * LoadModelFromMesh — because the tracker knows those two by name: the first * is a Get that hands the caller a new resource, the second takes its * argument over. * * Thing has padding after `flag`, and its pointer is what identifies it. Tex * holds no pointer, so its `id` does, as a GPU handle would. */ #include #include typedef struct { int32_t id; uint8_t flag; float w; void *data; } Thing; Thing LoadThing(int32_t id) { Thing t = { id, 1, 0.5f, malloc(16) }; return t; } void UnloadThing(Thing t) { free(t.data); } /* Changes the Thing in place, as ImageFormat changes an Image. */ void ThingGrow(Thing *t) { void *d = realloc(t->data, 64); if (d != NULL) t->data = d; t->w *= 2.0f; } /* The library's own Thing, which a caller must not unload. */ Thing GetDefaultThing(void) { Thing t = { 0, 0, 0.0f, NULL }; return t; } /* A Get that hands over a new one. */ Thing GetClipboardImage(void) { return LoadThing(99); } typedef struct { uint32_t id; int32_t width; } Tex; static uint32_t next_tex = 1; Tex LoadTex(int32_t width) { Tex t = { next_tex++, width }; return t; } void UnloadTex(Tex t) { (void)t; } typedef struct { int32_t n; float *v; } Mesh; typedef struct { int32_t count; Mesh *meshes; } Model; Mesh GenMeshThing(void) { Mesh m = { 3, calloc(3, sizeof(float)) }; return m; } void UnloadMesh(Mesh m) { free(m.v); } Model LoadModelFromMesh(Mesh m) { Model o = { 1, malloc(sizeof(Mesh)) }; o.meshes[0] = m; return o; } void UnloadModel(Model o) { for (int32_t i = 0; i < o.count; i++) UnloadMesh(o.meshes[i]); free(o.meshes); } /* A bare buffer, freed by a call not named for it: not a resource. */ unsigned char *LoadBytes(int32_t n) { return (unsigned char *)malloc((size_t)n); } void UnloadBytes(unsigned char *p) { free(p); }