base: merge gc remove
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marc Kirchner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
https://github.com/mkirchner/gc
|
||||
@@ -116,7 +116,6 @@ else if (platform == "wasm") {
|
||||
project.add_cfiles("sources/backends/webgpu_gpu.*");
|
||||
project.add_define("IRON_WASM");
|
||||
project.add_define("IRON_WEBGPU");
|
||||
project.add_define("NO_GC");
|
||||
project.add_cfiles("sources/miniclib/**");
|
||||
project.add_include_dir("sources/miniclib");
|
||||
project.add_assets("sources/backends/data/wasm/*");
|
||||
|
||||
@@ -749,10 +749,9 @@ static int xk_to_iron(KeySym symbol) {
|
||||
return KEY_CODE_UNKNOWN;
|
||||
}
|
||||
|
||||
void *gc_alloc(size_t size);
|
||||
|
||||
static char *uri_decode(const char *src) {
|
||||
char *res = gc_alloc(1024);
|
||||
char *res = calloc(1, 1024);
|
||||
char *dst = res;
|
||||
char a, b;
|
||||
while (*src) {
|
||||
|
||||
@@ -513,6 +513,8 @@ void gpu_shader_destroy(gpu_shader_t *shader) {
|
||||
id<MTLFunction> function = (__bridge_transfer id<MTLFunction>)shader->impl.mtl_function;
|
||||
function = nil;
|
||||
shader->impl.mtl_function = NULL;
|
||||
free(shader->impl.source);
|
||||
shader->impl.source = NULL;
|
||||
}
|
||||
|
||||
void gpu_shader_init(gpu_shader_t *shader, const void *data, size_t length, gpu_shader_type_t type) {
|
||||
@@ -527,7 +529,8 @@ void gpu_shader_init(gpu_shader_t *shader, const void *data, size_t length, gpu_
|
||||
shader->impl.name[i - 3] = source[i];
|
||||
}
|
||||
|
||||
shader->impl.source = data;
|
||||
shader->impl.source = malloc(length);
|
||||
memcpy(shader->impl.source, data, length);
|
||||
shader->impl.length = length;
|
||||
}
|
||||
|
||||
|
||||
+109
-94
@@ -46,7 +46,7 @@ gpu_shader_t *sys_get_shader(char *name);
|
||||
// ╚═════╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝
|
||||
|
||||
object_t *object_create(bool is_empty) {
|
||||
object_t *raw = gc_alloc(sizeof(object_t));
|
||||
object_t *raw = calloc(1, sizeof(object_t));
|
||||
raw->name = "";
|
||||
raw->children = any_array_create(0);
|
||||
raw->visible = true;
|
||||
@@ -54,7 +54,7 @@ object_t *object_create(bool is_empty) {
|
||||
raw->uid = _object_uid_counter++;
|
||||
raw->transform = transform_create(raw);
|
||||
raw->is_empty = is_empty;
|
||||
raw->_ = gc_alloc(sizeof(object_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(object_runtime_t));
|
||||
if (raw->is_empty) {
|
||||
any_array_push(scene_empties, raw);
|
||||
}
|
||||
@@ -97,6 +97,17 @@ void object_remove_super(object_t *raw) {
|
||||
}
|
||||
}
|
||||
|
||||
void object_free(object_t *raw) {
|
||||
if (raw->owns_raw && raw->raw != NULL) {
|
||||
array_delete(raw->raw->dimensions);
|
||||
free(raw->raw);
|
||||
}
|
||||
free(raw->transform);
|
||||
array_delete(raw->children);
|
||||
free(raw->_);
|
||||
free(raw);
|
||||
}
|
||||
|
||||
void object_remove(object_t *raw) {
|
||||
if (string_equals(raw->ext_type, "mesh_object_t")) {
|
||||
mesh_object_remove(raw->ext);
|
||||
@@ -106,6 +117,7 @@ void object_remove(object_t *raw) {
|
||||
}
|
||||
else {
|
||||
object_remove_super(raw);
|
||||
object_free(raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +143,7 @@ object_t *object_get_child(object_t *raw, char *name) {
|
||||
// ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
||||
|
||||
transform_t *transform_create(object_t *object) {
|
||||
transform_t *raw = gc_alloc(sizeof(transform_t));
|
||||
transform_t *raw = calloc(1, sizeof(transform_t));
|
||||
raw->scale_world = 1.0;
|
||||
raw->object = object;
|
||||
transform_reset(raw);
|
||||
@@ -225,9 +237,10 @@ void transform_compute_dim(transform_t *raw) {
|
||||
if (raw->object->raw == NULL && string_equals(raw->object->ext_type, "mesh_object_t")) {
|
||||
mesh_object_t *mo = (mesh_object_t *)raw->object->ext;
|
||||
vec4_t aabb = mesh_data_calculate_aabb(mo->data);
|
||||
obj_t *o_raw = gc_alloc(sizeof(obj_t));
|
||||
obj_t *o_raw = calloc(1, sizeof(obj_t));
|
||||
o_raw->dimensions = f32_array_create_xyz(aabb.x, aabb.y, aabb.z);
|
||||
raw->object->raw = o_raw;
|
||||
raw->object->owns_raw = true;
|
||||
}
|
||||
|
||||
if (raw->object->raw == NULL || raw->object->raw->dimensions == NULL) {
|
||||
@@ -310,7 +323,7 @@ world_data_t *world_data_parse(char *name, char *id) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raw->_ = gc_alloc(sizeof(world_data_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(world_data_runtime_t));
|
||||
raw->_->radiance_mipmaps = any_array_create(0);
|
||||
|
||||
raw->_->irradiance = world_data_set_irradiance(raw);
|
||||
@@ -349,7 +362,6 @@ world_data_t *world_data_get_raw_by_name(any_array_t *datas, char *name) {
|
||||
f32_array_t *world_data_get_empty_irradiance() {
|
||||
if (_world_data_empty_irr == NULL) {
|
||||
_world_data_empty_irr = f32_array_create(28);
|
||||
gc_root(_world_data_empty_irr);
|
||||
for (i32 i = 0; i < _world_data_empty_irr->length; ++i) {
|
||||
_world_data_empty_irr->buffer[i] = 0.0;
|
||||
}
|
||||
@@ -386,7 +398,7 @@ void world_data_load_envmap(world_data_t *raw) {
|
||||
i32 _material_data_uid_counter = 0;
|
||||
|
||||
material_data_t *material_data_create(material_data_t *raw, char *file) {
|
||||
raw->_ = gc_alloc(sizeof(material_data_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(material_data_runtime_t));
|
||||
raw->_->uid = (float)(++_material_data_uid_counter); // Start from 1
|
||||
|
||||
any_array_t *ref = string_split(raw->shader, "/");
|
||||
@@ -443,7 +455,7 @@ material_context_t *material_data_get_context(material_data_t *raw, char *name)
|
||||
}
|
||||
|
||||
void material_context_load(material_context_t *raw) {
|
||||
raw->_ = gc_alloc(sizeof(material_context_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(material_context_runtime_t));
|
||||
if (raw->bind_textures != NULL && raw->bind_textures->length > 0) {
|
||||
raw->_->textures = any_array_create(0);
|
||||
for (i32 i = 0; i < (i32)raw->bind_textures->length; ++i) {
|
||||
@@ -526,7 +538,7 @@ shader_context_t *shader_data_get_context(shader_data_t *raw, char *name) {
|
||||
|
||||
void shader_context_load(shader_context_t *raw) {
|
||||
if (raw->_ == NULL) {
|
||||
raw->_ = gc_alloc(sizeof(shader_context_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(shader_context_runtime_t));
|
||||
}
|
||||
shader_context_parse_vertex_struct(raw);
|
||||
shader_context_compile(raw);
|
||||
@@ -630,9 +642,9 @@ void shader_context_compile(shader_context_t *raw) {
|
||||
raw->_->pipe->fragment_shader = sys_get_shader(raw->fragment_shader);
|
||||
raw->_->pipe->vertex_shader = sys_get_shader(raw->vertex_shader);
|
||||
#else
|
||||
buffer_t *vs_buffer = data_get_blob(string("%s%s", raw->vertex_shader, shader_data_ext()));
|
||||
buffer_t *vs_buffer = data_get_blob(string_tmp("%s%s", raw->vertex_shader, shader_data_ext()));
|
||||
raw->_->pipe->vertex_shader = gpu_create_shader(vs_buffer, GPU_SHADER_TYPE_VERTEX);
|
||||
buffer_t *fs_buffer = data_get_blob(string("%s%s", raw->fragment_shader, shader_data_ext()));
|
||||
buffer_t *fs_buffer = data_get_blob(string_tmp("%s%s", raw->fragment_shader, shader_data_ext()));
|
||||
raw->_->pipe->fragment_shader = gpu_create_shader(fs_buffer, GPU_SHADER_TYPE_FRAGMENT);
|
||||
#endif
|
||||
}
|
||||
@@ -820,7 +832,7 @@ mesh_data_t *mesh_data_get_raw_by_name(any_array_t *datas, char *name) {
|
||||
}
|
||||
|
||||
mesh_data_t *mesh_data_create(mesh_data_t *raw) {
|
||||
raw->_ = gc_alloc(sizeof(mesh_data_runtime_t));
|
||||
raw->_ = calloc(1, sizeof(mesh_data_runtime_t));
|
||||
if (raw->scale_pos == 0.0) {
|
||||
raw->scale_pos = 1.0;
|
||||
}
|
||||
@@ -940,6 +952,25 @@ vec4_t mesh_data_calculate_aabb(mesh_data_t *raw) {
|
||||
void mesh_data_delete(mesh_data_t *raw) {
|
||||
gpu_delete_buffer(raw->_->vertex_buffer);
|
||||
gpu_delete_buffer(raw->_->index_buffer);
|
||||
if (raw->_->owns_arrays) {
|
||||
// Skip armpack meshes pointing to a decoded blob
|
||||
for (i32 i = 0; i < raw->vertex_arrays->length; ++i) {
|
||||
vertex_array_t *va = raw->vertex_arrays->buffer[i];
|
||||
if (va->values != NULL) {
|
||||
array_free(va->values);
|
||||
free(va->values);
|
||||
}
|
||||
free(va);
|
||||
}
|
||||
array_free(raw->vertex_arrays);
|
||||
free(raw->vertex_arrays);
|
||||
if (raw->index_array != NULL) {
|
||||
array_free(raw->index_array);
|
||||
free(raw->index_array);
|
||||
}
|
||||
free(raw->_);
|
||||
free(raw);
|
||||
}
|
||||
}
|
||||
|
||||
// ███╗ ███╗███████╗███████╗██╗ ██╗ ██████╗ ██████╗ ██╗███████╗ ██████╗████████╗
|
||||
@@ -950,7 +981,7 @@ void mesh_data_delete(mesh_data_t *raw) {
|
||||
// ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝
|
||||
|
||||
mesh_object_t *mesh_object_create(mesh_data_t *data, material_data_t *material) {
|
||||
mesh_object_t *raw = gc_alloc(sizeof(mesh_object_t));
|
||||
mesh_object_t *raw = calloc(1, sizeof(mesh_object_t));
|
||||
raw->frustum_culling = true;
|
||||
raw->base = object_create(false);
|
||||
raw->base->ext = raw;
|
||||
@@ -970,6 +1001,8 @@ void mesh_object_set_data(mesh_object_t *raw, mesh_data_t *data) {
|
||||
void mesh_object_remove(mesh_object_t *raw) {
|
||||
array_remove(scene_meshes, raw);
|
||||
object_remove_super(raw->base);
|
||||
object_free(raw->base);
|
||||
free(raw);
|
||||
}
|
||||
|
||||
bool mesh_object_cull_material(mesh_object_t *raw, char *context) {
|
||||
@@ -1031,9 +1064,7 @@ void mesh_object_render(mesh_object_t *raw, char *context, string_array_t *bind_
|
||||
|
||||
if (scontext->_->pipe != _mesh_object_last_pipeline) {
|
||||
gpu_set_pipeline(scontext->_->pipe);
|
||||
gc_unroot(_mesh_object_last_pipeline);
|
||||
_mesh_object_last_pipeline = scontext->_->pipe;
|
||||
gc_root(_mesh_object_last_pipeline);
|
||||
}
|
||||
uniforms_set_context_consts(scontext, bind_params);
|
||||
uniforms_set_obj_consts(scontext, raw->base);
|
||||
@@ -1055,7 +1086,7 @@ bool mesh_object_valid_context(mesh_object_t *raw, material_data_t *mat, char *c
|
||||
// ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝
|
||||
|
||||
camera_object_t *camera_object_create(camera_data_t *data) {
|
||||
camera_object_t *raw = gc_alloc(sizeof(camera_object_t));
|
||||
camera_object_t *raw = calloc(1, sizeof(camera_object_t));
|
||||
raw->no_jitter_p = mat4_identity();
|
||||
raw->frame = 0;
|
||||
raw->base = object_create(false);
|
||||
@@ -1097,6 +1128,14 @@ void camera_object_build_proj(camera_object_t *raw, f32 screen_aspect) {
|
||||
void camera_object_remove(camera_object_t *raw) {
|
||||
array_remove(scene_cameras, raw);
|
||||
object_remove_super(raw->base);
|
||||
object_free(raw->base);
|
||||
if (raw->frustum_planes != NULL) {
|
||||
for (i32 i = 0; i < raw->frustum_planes->length; ++i) {
|
||||
free(raw->frustum_planes->buffer[i]);
|
||||
}
|
||||
array_delete(raw->frustum_planes);
|
||||
}
|
||||
free(raw);
|
||||
}
|
||||
|
||||
void camera_object_proj_jitter(camera_object_t *raw) {
|
||||
@@ -1186,7 +1225,7 @@ bool camera_object_sphere_in_frustum(frustum_plane_array_t *frustum_planes, tran
|
||||
// ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝
|
||||
|
||||
frustum_plane_t *frustum_plane_create() {
|
||||
frustum_plane_t *raw = gc_alloc(sizeof(frustum_plane_t));
|
||||
frustum_plane_t *raw = calloc(1, sizeof(frustum_plane_t));
|
||||
raw->normal = (vec4_t){1.0, 0.0, 0.0, 0.0};
|
||||
raw->constant = 0.0;
|
||||
return raw;
|
||||
@@ -1526,7 +1565,7 @@ bool uniforms_set_context_const(i32 location, shader_const_t *c) {
|
||||
v.y = (-zfar * znear) / (zfar - znear);
|
||||
}
|
||||
else if (starts_with(c->link, "_size(")) {
|
||||
char *tex = substring(c->link, 6, string_length(c->link) - 1);
|
||||
char *tex = string_tmp("%.*s", string_length(c->link) - 7, c->link + 6);
|
||||
gpu_texture_t *image = uniforms_tex_links != NULL ? uniforms_tex_links(NULL, NULL, tex) : NULL;
|
||||
if (image != NULL) {
|
||||
v.x = (f32)image->width;
|
||||
@@ -1854,6 +1893,9 @@ buffer_t *iron_load_blob(char *file);
|
||||
gpu_texture_t *iron_load_texture(char *file);
|
||||
void gpu_delete_texture(gpu_texture_t *texture);
|
||||
void *iron_load_sound(char *file);
|
||||
#ifdef WITH_EMBED
|
||||
bool embed_owns(uint8_t *buffer);
|
||||
#endif
|
||||
|
||||
char *data_path(void) {
|
||||
#ifdef IRON_ANDROID
|
||||
@@ -1864,11 +1906,11 @@ char *data_path(void) {
|
||||
}
|
||||
|
||||
bool data_is_abs(char *file) {
|
||||
return char_at(file, 0)[0] == '/' || char_at(file, 1)[0] == ':' || (char_at(file, 0)[0] == '\\' && char_at(file, 1)[0] == '\\');
|
||||
return file[0] == '/' || (file[0] != '\0' && file[1] == ':') || (file[0] == '\\' && file[1] == '\\');
|
||||
}
|
||||
|
||||
bool data_is_up(char *file) {
|
||||
return char_at(file, 0)[0] == '.' && char_at(file, 1)[0] == '.';
|
||||
return file[0] == '.' && file[1] == '.';
|
||||
}
|
||||
|
||||
char *data_resolve_path(char *file) {
|
||||
@@ -1886,7 +1928,6 @@ char *data_resolve_path(char *file) {
|
||||
mesh_data_t *data_get_mesh(char *file, char *name) {
|
||||
if (data_cached_meshes == NULL) {
|
||||
data_cached_meshes = any_map_create();
|
||||
gc_root(data_cached_meshes);
|
||||
}
|
||||
char *handle = string("%s%s", file, name);
|
||||
mesh_data_t *cached = (mesh_data_t *)any_map_get(data_cached_meshes, handle);
|
||||
@@ -1894,7 +1935,7 @@ mesh_data_t *data_get_mesh(char *file, char *name) {
|
||||
return cached;
|
||||
}
|
||||
mesh_data_t *b = mesh_data_parse(file, name);
|
||||
any_map_set(data_cached_meshes, handle, b);
|
||||
any_map_set(data_cached_meshes, string_copy(handle), b);
|
||||
b->_->handle = handle;
|
||||
return b;
|
||||
}
|
||||
@@ -1902,7 +1943,6 @@ mesh_data_t *data_get_mesh(char *file, char *name) {
|
||||
camera_data_t *data_get_camera(char *file, char *name) {
|
||||
if (data_cached_cameras == NULL) {
|
||||
data_cached_cameras = any_map_create();
|
||||
gc_root(data_cached_cameras);
|
||||
}
|
||||
char *handle = string("%s%s", file, name);
|
||||
camera_data_t *cached = (camera_data_t *)any_map_get(data_cached_cameras, handle);
|
||||
@@ -1910,14 +1950,13 @@ camera_data_t *data_get_camera(char *file, char *name) {
|
||||
return cached;
|
||||
}
|
||||
camera_data_t *b = camera_data_parse(file, name);
|
||||
any_map_set(data_cached_cameras, handle, b);
|
||||
any_map_set(data_cached_cameras, string_copy(handle), b);
|
||||
return b;
|
||||
}
|
||||
|
||||
material_data_t *data_get_material(char *file, char *name) {
|
||||
if (data_cached_materials == NULL) {
|
||||
data_cached_materials = any_map_create();
|
||||
gc_root(data_cached_materials);
|
||||
}
|
||||
char *handle = string("%s%s", file, name);
|
||||
material_data_t *cached = (material_data_t *)any_map_get(data_cached_materials, handle);
|
||||
@@ -1925,14 +1964,13 @@ material_data_t *data_get_material(char *file, char *name) {
|
||||
return cached;
|
||||
}
|
||||
material_data_t *b = material_data_parse(file, name);
|
||||
any_map_set(data_cached_materials, handle, b);
|
||||
any_map_set(data_cached_materials, string_copy(handle), b);
|
||||
return b;
|
||||
}
|
||||
|
||||
world_data_t *data_get_world(char *file, char *name) {
|
||||
if (data_cached_worlds == NULL) {
|
||||
data_cached_worlds = any_map_create();
|
||||
gc_root(data_cached_worlds);
|
||||
}
|
||||
char *handle = string("%s%s", file, name);
|
||||
world_data_t *cached = (world_data_t *)any_map_get(data_cached_worlds, handle);
|
||||
@@ -1940,14 +1978,13 @@ world_data_t *data_get_world(char *file, char *name) {
|
||||
return cached;
|
||||
}
|
||||
world_data_t *b = world_data_parse(file, name);
|
||||
any_map_set(data_cached_worlds, handle, b);
|
||||
any_map_set(data_cached_worlds, string_copy(handle), b);
|
||||
return b;
|
||||
}
|
||||
|
||||
shader_data_t *data_get_shader(char *file, char *name) {
|
||||
if (data_cached_shaders == NULL) {
|
||||
data_cached_shaders = any_map_create();
|
||||
gc_root(data_cached_shaders);
|
||||
}
|
||||
// Only one context override per shader data for now
|
||||
char *handle = name; // Shader must have unique name
|
||||
@@ -1956,14 +1993,13 @@ shader_data_t *data_get_shader(char *file, char *name) {
|
||||
return cached;
|
||||
}
|
||||
shader_data_t *b = shader_data_parse(file, name);
|
||||
any_map_set(data_cached_shaders, handle, b);
|
||||
any_map_set(data_cached_shaders, string_copy(handle), b);
|
||||
return b;
|
||||
}
|
||||
|
||||
scene_t *data_get_scene_raw(char *file) {
|
||||
if (data_cached_scene_raws == NULL) {
|
||||
data_cached_scene_raws = any_map_create();
|
||||
gc_root(data_cached_scene_raws);
|
||||
}
|
||||
scene_t *cached = (scene_t *)any_map_get(data_cached_scene_raws, file);
|
||||
if (cached != NULL) {
|
||||
@@ -1973,21 +2009,20 @@ scene_t *data_get_scene_raw(char *file) {
|
||||
char *ext = ends_with(file, ".arm") ? "" : ".arm";
|
||||
buffer_t *b = data_get_blob(string("%s%s", file, ext));
|
||||
scene_t *parsed = (scene_t *)armpack_decode(b);
|
||||
any_map_set(data_cached_scene_raws, file, parsed);
|
||||
any_map_set(data_cached_scene_raws, string_copy(file), parsed);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
buffer_t *data_get_blob(char *file) {
|
||||
if (data_cached_blobs == NULL) {
|
||||
data_cached_blobs = any_map_create();
|
||||
gc_root(data_cached_blobs);
|
||||
}
|
||||
buffer_t *cached = (buffer_t *)any_map_get(data_cached_blobs, file);
|
||||
if (cached != NULL) {
|
||||
return cached;
|
||||
}
|
||||
buffer_t *b = iron_load_blob(data_resolve_path(file));
|
||||
any_map_set(data_cached_blobs, file, b);
|
||||
any_map_set(data_cached_blobs, string_copy(file), b);
|
||||
data_assets_loaded++;
|
||||
return b;
|
||||
}
|
||||
@@ -1995,7 +2030,6 @@ buffer_t *data_get_blob(char *file) {
|
||||
gpu_texture_t *data_get_texture(char *file) {
|
||||
if (data_cached_textures == NULL) {
|
||||
data_cached_textures = any_map_create();
|
||||
gc_root(data_cached_textures);
|
||||
}
|
||||
gpu_texture_t *cached = (gpu_texture_t *)any_map_get(data_cached_textures, file);
|
||||
if (cached != NULL) {
|
||||
@@ -2005,7 +2039,7 @@ gpu_texture_t *data_get_texture(char *file) {
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
any_map_set(data_cached_textures, file, b);
|
||||
any_map_set(data_cached_textures, string_copy(file), b);
|
||||
data_assets_loaded++;
|
||||
return b;
|
||||
}
|
||||
@@ -2013,7 +2047,6 @@ gpu_texture_t *data_get_texture(char *file) {
|
||||
video_t *data_get_video(char *file) {
|
||||
if (data_cached_videos == NULL) {
|
||||
data_cached_videos = any_map_create();
|
||||
gc_root(data_cached_videos);
|
||||
}
|
||||
// Strip extension and use .webm
|
||||
char *base = substring(file, 0, string_length(file) - 4);
|
||||
@@ -2032,17 +2065,16 @@ video_t *data_get_video(char *file) {
|
||||
draw_font_t *data_get_font(char *file) {
|
||||
if (data_cached_fonts == NULL) {
|
||||
data_cached_fonts = any_map_create();
|
||||
gc_root(data_cached_fonts);
|
||||
}
|
||||
draw_font_t *cached = (draw_font_t *)any_map_get(data_cached_fonts, file);
|
||||
if (cached != NULL) {
|
||||
return cached;
|
||||
}
|
||||
buffer_t *blob = iron_load_blob(data_resolve_path(file));
|
||||
draw_font_t *b = gc_alloc(sizeof(draw_font_t));
|
||||
draw_font_t *b = calloc(1, sizeof(draw_font_t));
|
||||
b->buf = blob;
|
||||
b->index = 0;
|
||||
any_map_set(data_cached_fonts, file, b);
|
||||
any_map_set(data_cached_fonts, string_copy(file), b);
|
||||
data_assets_loaded++;
|
||||
return b;
|
||||
}
|
||||
@@ -2050,14 +2082,13 @@ draw_font_t *data_get_font(char *file) {
|
||||
sound_t *data_get_sound(char *file) {
|
||||
if (data_cached_sounds == NULL) {
|
||||
data_cached_sounds = any_map_create();
|
||||
gc_root(data_cached_sounds);
|
||||
}
|
||||
sound_t *cached = (sound_t *)any_map_get(data_cached_sounds, file);
|
||||
if (cached != NULL) {
|
||||
return cached;
|
||||
}
|
||||
sound_t *b = iron_load_sound(data_resolve_path(file));
|
||||
any_map_set(data_cached_sounds, file, b);
|
||||
any_map_set(data_cached_sounds, string_copy(file), b);
|
||||
data_assets_loaded++;
|
||||
return b;
|
||||
}
|
||||
@@ -2097,6 +2128,14 @@ void data_delete_blob(char *handle) {
|
||||
return;
|
||||
}
|
||||
map_delete(data_cached_blobs, handle);
|
||||
#ifdef WITH_EMBED
|
||||
if (embed_owns(blob->buffer)) {
|
||||
free(blob);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
free(blob->buffer);
|
||||
free(blob);
|
||||
}
|
||||
|
||||
void data_delete_texture(char *handle) {
|
||||
@@ -2158,59 +2197,41 @@ i32 _scene_objects_count = 0;
|
||||
object_t *scene_create(scene_t *format) {
|
||||
_scene_uid = _scene_uid_counter++;
|
||||
|
||||
gc_unroot(scene_meshes);
|
||||
scene_meshes = any_array_create(0);
|
||||
gc_root(scene_meshes);
|
||||
|
||||
gc_unroot(scene_cameras);
|
||||
scene_cameras = any_array_create(0);
|
||||
gc_root(scene_cameras);
|
||||
|
||||
gc_unroot(scene_empties);
|
||||
scene_empties = any_array_create(0);
|
||||
gc_root(scene_empties);
|
||||
|
||||
gc_unroot(scene_embedded);
|
||||
scene_embedded = any_map_create();
|
||||
gc_root(scene_embedded);
|
||||
|
||||
gc_unroot(_scene_root);
|
||||
_scene_root = object_create(true);
|
||||
gc_root(_scene_root);
|
||||
_scene_root->name = format->name;
|
||||
|
||||
gc_unroot(_scene_raw);
|
||||
_scene_raw = format;
|
||||
gc_root(_scene_raw);
|
||||
|
||||
gc_unroot(scene_world);
|
||||
scene_world = data_get_world(format->name, format->world_ref);
|
||||
gc_root(scene_world);
|
||||
|
||||
// Startup scene
|
||||
scene_add_scene(format->name);
|
||||
|
||||
gc_unroot(scene_camera);
|
||||
scene_camera = (camera_object_t *)scene_cameras->buffer[0]; // format->camera_ref
|
||||
gc_root(scene_camera);
|
||||
|
||||
return _scene_root;
|
||||
}
|
||||
|
||||
void scene_remove(void) {
|
||||
for (i32 i = 0; i < scene_meshes->length; ++i) {
|
||||
mesh_object_t *o = (mesh_object_t *)scene_meshes->buffer[i];
|
||||
mesh_object_remove(o);
|
||||
while (scene_meshes->length > 0) {
|
||||
mesh_object_remove((mesh_object_t *)scene_meshes->buffer[0]);
|
||||
}
|
||||
for (i32 i = 0; i < scene_cameras->length; ++i) {
|
||||
camera_object_t *o = (camera_object_t *)scene_cameras->buffer[i];
|
||||
camera_object_remove(o);
|
||||
while (scene_cameras->length > 0) {
|
||||
camera_object_remove((camera_object_t *)scene_cameras->buffer[0]);
|
||||
}
|
||||
for (i32 i = 0; i < scene_empties->length; ++i) {
|
||||
object_t *o = (object_t *)scene_empties->buffer[i];
|
||||
object_remove(o);
|
||||
while (scene_empties->length > 0) {
|
||||
object_remove((object_t *)scene_empties->buffer[0]);
|
||||
}
|
||||
object_remove(_scene_root);
|
||||
_scene_root = NULL;
|
||||
scene_camera = NULL;
|
||||
}
|
||||
|
||||
object_t *scene_set_active(char *scene_name) {
|
||||
@@ -2405,6 +2426,11 @@ object_t *scene_return_mesh_object(char *object_file, char *data_ref, material_d
|
||||
|
||||
object_t *scene_return_object(object_t *object, obj_t *o) {
|
||||
if (object != NULL) {
|
||||
if (object->owns_raw && object->raw != NULL) {
|
||||
array_delete(object->raw->dimensions);
|
||||
free(object->raw);
|
||||
object->owns_raw = false;
|
||||
}
|
||||
object->raw = o;
|
||||
object->name = o->name;
|
||||
object->visible = o->visible;
|
||||
@@ -2495,11 +2521,9 @@ void render_path_set_target(char *target, string_array_t *additional, char *dept
|
||||
render_path_end();
|
||||
}
|
||||
|
||||
gc_unroot(_mesh_object_last_pipeline);
|
||||
_mesh_object_last_pipeline = NULL;
|
||||
|
||||
if (string_equals(target, "")) { // Framebuffer
|
||||
gc_unroot(_render_path_current_target);
|
||||
_render_path_current_target = NULL;
|
||||
render_path_current_w = sys_w();
|
||||
render_path_current_h = sys_h();
|
||||
@@ -2508,40 +2532,34 @@ void render_path_set_target(char *target, string_array_t *additional, char *dept
|
||||
}
|
||||
else { // Render target
|
||||
render_target_t *rt = (render_target_t *)any_map_get(render_path_render_targets, target);
|
||||
gc_unroot(_render_path_current_target);
|
||||
_render_path_current_target = rt;
|
||||
gc_root(_render_path_current_target);
|
||||
static any_array_t additional_images_scratch = {0};
|
||||
any_array_t *additional_images = NULL;
|
||||
if (additional != NULL) {
|
||||
additional_images = any_array_create(0);
|
||||
additional_images_scratch.length = 0;
|
||||
for (i32 i = 0; i < additional->length; ++i) {
|
||||
char *s = (char *)additional->buffer[i];
|
||||
render_target_t *t = (render_target_t *)any_map_get(render_path_render_targets, s);
|
||||
any_array_push(additional_images, t->_image);
|
||||
any_array_push(&additional_images_scratch, t->_image);
|
||||
}
|
||||
additional_images = &additional_images_scratch;
|
||||
}
|
||||
render_path_current_w = rt->_image->width;
|
||||
render_path_current_h = rt->_image->height;
|
||||
render_target_t *db = depth_buffer != NULL ? (render_target_t *)any_map_get(render_path_render_targets, depth_buffer) : NULL;
|
||||
gc_unroot(_render_path_current_image);
|
||||
_render_path_current_image = rt->_image;
|
||||
gc_root(_render_path_current_image);
|
||||
_gpu_begin(rt->_image, additional_images, db != NULL ? db->_image : NULL, flags, color, depth);
|
||||
}
|
||||
gc_unroot(_render_path_bind_params);
|
||||
_render_path_bind_params = NULL;
|
||||
}
|
||||
|
||||
void render_path_end(void) {
|
||||
gpu_end();
|
||||
gc_unroot(_render_path_current_image);
|
||||
_render_path_current_image = NULL;
|
||||
gc_unroot(_render_path_bind_params);
|
||||
_render_path_bind_params = NULL;
|
||||
}
|
||||
|
||||
void render_path_draw_meshes(char *context) {
|
||||
gc_unroot(_mesh_object_last_pipeline);
|
||||
_mesh_object_last_pipeline = NULL;
|
||||
any_array_t *meshes = scene_meshes;
|
||||
for (i32 i = 0; i < meshes->length; ++i) {
|
||||
@@ -2566,17 +2584,13 @@ void render_path_draw_skydome(char *handle) {
|
||||
}
|
||||
|
||||
void render_path_bind_target(char *target, char *uniform) {
|
||||
if (_render_path_bind_params != NULL) {
|
||||
static string_array_t bind_params = {0};
|
||||
if (_render_path_bind_params == NULL) {
|
||||
bind_params.length = 0;
|
||||
_render_path_bind_params = &bind_params;
|
||||
}
|
||||
string_array_push(_render_path_bind_params, target);
|
||||
string_array_push(_render_path_bind_params, uniform);
|
||||
}
|
||||
else {
|
||||
_render_path_bind_params = string_array_create(2);
|
||||
gc_root(_render_path_bind_params);
|
||||
_render_path_bind_params->buffer[0] = target;
|
||||
_render_path_bind_params->buffer[1] = uniform;
|
||||
_render_path_bind_params->length = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void render_path_draw_shader(char *handle) {
|
||||
@@ -2599,7 +2613,6 @@ void render_path_load_shader(char *handle) {
|
||||
_render_path_loading++;
|
||||
if (_render_path_cached_shader_contexts == NULL) {
|
||||
_render_path_cached_shader_contexts = any_map_create();
|
||||
gc_root(_render_path_cached_shader_contexts);
|
||||
}
|
||||
cached_shader_context_t *cc = (cached_shader_context_t *)any_map_get(_render_path_cached_shader_contexts, handle);
|
||||
if (cc != NULL) {
|
||||
@@ -2607,14 +2620,15 @@ void render_path_load_shader(char *handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
cc = gc_alloc(sizeof(cached_shader_context_t));
|
||||
any_map_set(_render_path_cached_shader_contexts, handle, cc);
|
||||
cc = calloc(1, sizeof(cached_shader_context_t));
|
||||
any_map_set(_render_path_cached_shader_contexts, string_copy(handle), cc); // Callers may pass frame-temporary handles
|
||||
|
||||
// file/data_name/context
|
||||
any_array_t *shader_path = string_split(handle, "/");
|
||||
|
||||
shader_data_t *res = data_get_shader((char *)shader_path->buffer[0], (char *)shader_path->buffer[1]);
|
||||
cc->context = shader_data_get_context(res, (char *)shader_path->buffer[2]);
|
||||
string_split_free(shader_path);
|
||||
_render_path_loading--;
|
||||
}
|
||||
|
||||
@@ -2631,12 +2645,13 @@ void render_path_resize(void) {
|
||||
rt->_image = render_path_create_image(rt);
|
||||
}
|
||||
}
|
||||
array_free(render_targets_keys);
|
||||
free(render_targets_keys);
|
||||
}
|
||||
|
||||
render_target_t *render_path_create_render_target(render_target_t *t) {
|
||||
if (render_path_render_targets == NULL) {
|
||||
render_path_render_targets = any_map_create();
|
||||
gc_root(render_path_render_targets);
|
||||
}
|
||||
t->_image = render_path_create_image(t);
|
||||
any_map_set(render_path_render_targets, t->name, t);
|
||||
@@ -2683,7 +2698,7 @@ gpu_texture_format_t render_path_get_tex_format(char *s) {
|
||||
}
|
||||
|
||||
render_target_t *render_target_create(void) {
|
||||
render_target_t *raw = gc_alloc(sizeof(render_target_t));
|
||||
render_target_t *raw = calloc(1, sizeof(render_target_t));
|
||||
raw->scale = 1.0;
|
||||
return raw;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "iron_array.h"
|
||||
#include "iron_audio.h"
|
||||
#include "iron_draw.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_gpu.h"
|
||||
#include "iron_map.h"
|
||||
#include "iron_math.h"
|
||||
@@ -106,6 +106,7 @@ typedef struct mesh_data_runtime {
|
||||
gpu_vertex_structure_t structure;
|
||||
buffer_t *skin_blob; // Source file bytes
|
||||
i32 skin_frames;
|
||||
bool owns_arrays;
|
||||
} mesh_data_runtime_t;
|
||||
|
||||
typedef struct mesh_data {
|
||||
@@ -329,6 +330,7 @@ typedef struct object {
|
||||
bool visible;
|
||||
bool culled;
|
||||
bool is_empty;
|
||||
bool owns_raw;
|
||||
void *ext;
|
||||
char *ext_type;
|
||||
object_runtime_t *_;
|
||||
@@ -346,6 +348,7 @@ extern i32 _object_uid_counter;
|
||||
object_t *object_create(bool is_empty);
|
||||
void object_set_parent(object_t *raw, object_t *parent_object);
|
||||
void object_remove_super(object_t *raw);
|
||||
void object_free(object_t *raw);
|
||||
void object_remove(object_t *raw);
|
||||
object_t *object_get_child(object_t *raw, char *name);
|
||||
|
||||
|
||||
+32
-7
@@ -7,7 +7,7 @@
|
||||
#include "iron_array.h"
|
||||
#include "iron_draw.h"
|
||||
#include "iron_file.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_gpu.h"
|
||||
#include "iron_json.h"
|
||||
#include "iron_lz4.h"
|
||||
@@ -62,6 +62,15 @@ buffer_t *embed_get(char *key) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool embed_owns(uint8_t *buffer) {
|
||||
for (int i = 0; i < embed_count; ++i) {
|
||||
if (embed_values[i] == buffer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void _kickstart();
|
||||
@@ -147,13 +156,11 @@ int kickstart(int argc, char **argv) {
|
||||
|
||||
iron_threads_init();
|
||||
iron_display_init();
|
||||
gc_start(&argc);
|
||||
_kickstart();
|
||||
|
||||
#ifdef IRON_AUDIO
|
||||
iron_a2_shutdown();
|
||||
#endif
|
||||
gc_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -236,11 +243,9 @@ void _update() {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (paused_frames == 30) {
|
||||
gc_run();
|
||||
}
|
||||
#endif
|
||||
|
||||
string_tmp_reset();
|
||||
iron_net_update();
|
||||
iron_update();
|
||||
if (ui_get_current())
|
||||
@@ -842,6 +847,10 @@ gpu_texture_t *gpu_create_texture_from_encoded_bytes(buffer_t *data, char *forma
|
||||
|
||||
void gpu_delete_texture(gpu_texture_t *texture) {
|
||||
gpu_texture_destroy(texture);
|
||||
if (texture->buffer != NULL) { // Cached by gpu_get_texture_pixels
|
||||
free(texture->buffer->buffer);
|
||||
free(texture->buffer);
|
||||
}
|
||||
free(texture);
|
||||
}
|
||||
|
||||
@@ -864,7 +873,9 @@ gpu_texture_t *iron_load_texture(char *file) {
|
||||
buffer_t buf;
|
||||
buf.buffer = data;
|
||||
buf.length = size;
|
||||
return gpu_create_texture_from_encoded_bytes(&buf, file);
|
||||
gpu_texture_t *texture = gpu_create_texture_from_encoded_bytes(&buf, file);
|
||||
free(data); // Encoded bytes are decoded into a separate buffer
|
||||
return texture;
|
||||
}
|
||||
|
||||
void *iron_load_sound(char *file) {
|
||||
@@ -895,6 +906,20 @@ buffer_t *iron_load_blob(char *file) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void iron_delete_blob(buffer_t *buffer) {
|
||||
if (buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
#ifdef WITH_EMBED
|
||||
if (embed_owns(buffer->buffer)) {
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
array_free(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
i32 iron_display_ppi(i32 index) {
|
||||
return iron_display_current_mode(index).pixels_per_inch;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "iron_string.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// point_t *p = ALLOC_INIT(point_t, {x: 1.5, y: 3.5});
|
||||
#define ALLOC_INIT(type, ...) (type *)memcpy(malloc(sizeof(type)), (type[]){__VA_ARGS__}, sizeof(type))
|
||||
|
||||
#define TMP_ALLOC_INIT(type, ...) (type *)memcpy(string_tmp_alloc(sizeof(type)), (type[]){__VA_ARGS__}, sizeof(type))
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "iron_armpack.h"
|
||||
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_json.h"
|
||||
#include "iron_string.h"
|
||||
#include <stdbool.h>
|
||||
@@ -251,9 +251,8 @@ static uint8_t flag_to_byte_size(uint8_t flag) {
|
||||
static void store_typed_array(uint8_t flag, uint32_t count) {
|
||||
uint32_t size = flag_to_byte_size(flag) * count;
|
||||
if (size > 4096) {
|
||||
void *data = gc_alloc(size);
|
||||
void *data = calloc(1, size);
|
||||
memcpy(data, encoded + ei, size);
|
||||
gc_leaf(data);
|
||||
*(uintptr_t *)(decoded + di - 4 - 4 - PTR_SIZE) = (uintptr_t)data; // Set buffer ptr
|
||||
*(uint32_t *)(decoded + di - 4) = count; // Set capacity
|
||||
}
|
||||
@@ -406,7 +405,7 @@ void *armpack_decode(buffer_t *b) {
|
||||
encoded = b->buffer;
|
||||
capacity = traverse(0, true);
|
||||
reset();
|
||||
decoded = gc_alloc(capacity);
|
||||
decoded = calloc(1, capacity);
|
||||
read_store();
|
||||
return decoded;
|
||||
}
|
||||
@@ -592,7 +591,7 @@ uint32_t armpack_size_bool() {
|
||||
|
||||
static char *read_string_alloc() {
|
||||
char *s = read_string();
|
||||
char *allocated = gc_alloc(str_len + 1);
|
||||
char *allocated = calloc(1, str_len + 1);
|
||||
memcpy(allocated, s, str_len);
|
||||
allocated[str_len] = '\0';
|
||||
return allocated;
|
||||
|
||||
+67
-43
@@ -1,6 +1,6 @@
|
||||
#include "iron_array.h"
|
||||
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_string.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@@ -8,13 +8,22 @@
|
||||
|
||||
void array_free(void *a) {
|
||||
u8_array_t *tmp = (u8_array_t *)a;
|
||||
gc_free(tmp->buffer);
|
||||
free(tmp->buffer);
|
||||
tmp->buffer = NULL;
|
||||
tmp->length = tmp->capacity = 0;
|
||||
}
|
||||
|
||||
static void *gc_realloc_no_free(void *ptr, size_t old_size, size_t new_size) {
|
||||
void *buffer = gc_alloc(new_size);
|
||||
void array_delete(void *a) {
|
||||
if (a == NULL) {
|
||||
return;
|
||||
}
|
||||
array_free(a);
|
||||
free(a);
|
||||
}
|
||||
|
||||
// Old buffer may point into an armpack blob
|
||||
static void *alloc_no_free(void *ptr, size_t old_size, size_t new_size) {
|
||||
void *buffer = calloc(1, new_size);
|
||||
memcpy(buffer, ptr, old_size);
|
||||
return buffer;
|
||||
}
|
||||
@@ -27,14 +36,11 @@ static void array_alloc(void *a, uint8_t element_size) {
|
||||
tmp->capacity = tmp->length + 1;
|
||||
size_t old_size = tmp->length * element_size;
|
||||
size_t new_size = tmp->capacity * element_size;
|
||||
tmp->buffer = gc_realloc_no_free(tmp->buffer, old_size, new_size);
|
||||
tmp->buffer = alloc_no_free(tmp->buffer, old_size, new_size);
|
||||
}
|
||||
else {
|
||||
tmp->capacity *= 2;
|
||||
tmp->buffer = gc_realloc(tmp->buffer, tmp->capacity * element_size);
|
||||
}
|
||||
if (element_size < 8) {
|
||||
gc_leaf(tmp->buffer);
|
||||
tmp->buffer = realloc(tmp->buffer, tmp->capacity * element_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,60 +92,52 @@ void string_array_push(string_array_t *a, void *e) {
|
||||
|
||||
void i8_array_resize(i8_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(int8_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(int8_t));
|
||||
}
|
||||
|
||||
void u8_array_resize(u8_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(uint8_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void i16_array_resize(i16_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(int16_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(int16_t));
|
||||
}
|
||||
|
||||
void u16_array_resize(u16_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(uint16_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void i32_array_resize(i32_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(int32_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(int32_t));
|
||||
}
|
||||
|
||||
void u32_array_resize(u32_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(uint32_t));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void f32_array_resize(f32_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(float));
|
||||
gc_leaf(a->buffer);
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(float));
|
||||
}
|
||||
|
||||
void any_array_resize(any_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(void *));
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(void *));
|
||||
}
|
||||
|
||||
void string_array_resize(string_array_t *a, uint32_t size) {
|
||||
a->capacity = size;
|
||||
a->buffer = gc_realloc(a->buffer, a->capacity * sizeof(void *));
|
||||
a->buffer = realloc(a->buffer, a->capacity * sizeof(void *));
|
||||
}
|
||||
|
||||
void buffer_resize(buffer_t *b, uint32_t size) {
|
||||
b->length = size;
|
||||
b->buffer = gc_realloc(b->buffer, b->length * sizeof(uint8_t));
|
||||
gc_leaf(b->buffer);
|
||||
b->buffer = realloc(b->buffer, b->length * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
static int _array_sort_alpha(const void *a, const void *b) {
|
||||
@@ -208,7 +206,7 @@ void i32_array_splice(i32_array_t *ar, uint32_t start, uint32_t delete_count) {
|
||||
}
|
||||
|
||||
any_array_t *array_concat(any_array_t *a, any_array_t *b) {
|
||||
any_array_t *ar = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *ar = calloc(1, sizeof(any_array_t));
|
||||
ar->length = a->length + b->length;
|
||||
any_array_resize(ar, ar->length);
|
||||
for (uint32_t i = 0; i < a->length; ++i) {
|
||||
@@ -221,7 +219,7 @@ any_array_t *array_concat(any_array_t *a, any_array_t *b) {
|
||||
}
|
||||
|
||||
any_array_t *array_slice(any_array_t *a, uint32_t begin, uint32_t end) {
|
||||
any_array_t *ar = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *ar = calloc(1, sizeof(any_array_t));
|
||||
ar->length = end - begin;
|
||||
any_array_resize(ar, ar->length);
|
||||
for (uint32_t i = 0; i < ar->length; ++i) {
|
||||
@@ -296,7 +294,7 @@ void array_reverse(any_array_t *ar) {
|
||||
}
|
||||
|
||||
buffer_t *buffer_slice(buffer_t *a, uint32_t begin, uint32_t end) {
|
||||
buffer_t *b = gc_alloc(sizeof(buffer_t));
|
||||
buffer_t *b = calloc(1, sizeof(buffer_t));
|
||||
buffer_resize(b, end - begin);
|
||||
for (uint32_t i = 0; i < b->length; ++i) {
|
||||
b->buffer[i] = a->buffer[begin + i];
|
||||
@@ -385,13 +383,13 @@ void buffer_set_f32(buffer_t *b, uint32_t p, float n) {
|
||||
}
|
||||
|
||||
buffer_t *buffer_create(uint32_t length) {
|
||||
buffer_t *b = gc_alloc(sizeof(buffer_t));
|
||||
buffer_t *b = calloc(1, sizeof(buffer_t));
|
||||
buffer_resize(b, length);
|
||||
return b;
|
||||
}
|
||||
|
||||
buffer_t *buffer_create_from_raw(uint8_t *raw, uint32_t length) {
|
||||
buffer_t *b = gc_alloc(sizeof(buffer_t));
|
||||
buffer_t *b = calloc(1, sizeof(buffer_t));
|
||||
b->buffer = raw;
|
||||
b->length = length;
|
||||
b->capacity = length;
|
||||
@@ -399,7 +397,7 @@ buffer_t *buffer_create_from_raw(uint8_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
f32_array_t *f32_array_create(uint32_t length) {
|
||||
f32_array_t *a = gc_alloc(sizeof(f32_array_t));
|
||||
f32_array_t *a = calloc(1, sizeof(f32_array_t));
|
||||
if (length > 0) {
|
||||
f32_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -408,7 +406,7 @@ f32_array_t *f32_array_create(uint32_t length) {
|
||||
}
|
||||
|
||||
f32_array_t *f32_array_create_from_buffer(buffer_t *b) {
|
||||
f32_array_t *a = gc_alloc(sizeof(f32_array_t));
|
||||
f32_array_t *a = calloc(1, sizeof(f32_array_t));
|
||||
a->buffer = b->buffer;
|
||||
a->length = b->length / 4;
|
||||
a->capacity = b->length / 4;
|
||||
@@ -431,6 +429,19 @@ f32_array_t *f32_array_create_from_raw(float *raw, uint32_t length) {
|
||||
return a;
|
||||
}
|
||||
|
||||
f32_array_t *f32_array_create_from_raw_tmp(float *raw, uint32_t length) {
|
||||
f32_array_t *a = (f32_array_t *)string_tmp_alloc(sizeof(f32_array_t));
|
||||
a->buffer = (float *)string_tmp_alloc(length * sizeof(float));
|
||||
a->length = length;
|
||||
a->capacity = length;
|
||||
if (raw != NULL) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
a->buffer[i] = raw[i];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
f32_array_t *f32_array_create_x(float x) {
|
||||
f32_array_t *a = f32_array_create(1);
|
||||
a->buffer[0] = x;
|
||||
@@ -472,7 +483,7 @@ f32_array_t *f32_array_create_xyzwv(float x, float y, float z, float w, float v)
|
||||
}
|
||||
|
||||
u32_array_t *u32_array_create(uint32_t length) {
|
||||
u32_array_t *a = gc_alloc(sizeof(u32_array_t));
|
||||
u32_array_t *a = calloc(1, sizeof(u32_array_t));
|
||||
if (length > 0) {
|
||||
u32_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -497,7 +508,7 @@ u32_array_t *u32_array_create_from_raw(uint32_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
i32_array_t *i32_array_create(uint32_t length) {
|
||||
i32_array_t *a = gc_alloc(sizeof(i32_array_t));
|
||||
i32_array_t *a = calloc(1, sizeof(i32_array_t));
|
||||
if (length > 0) {
|
||||
i32_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -522,7 +533,7 @@ i32_array_t *i32_array_create_from_raw(int32_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
u16_array_t *u16_array_create(uint32_t length) {
|
||||
u16_array_t *a = gc_alloc(sizeof(u16_array_t));
|
||||
u16_array_t *a = calloc(1, sizeof(u16_array_t));
|
||||
if (length > 0) {
|
||||
u16_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -539,7 +550,7 @@ u16_array_t *u16_array_create_from_raw(uint16_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
i16_array_t *i16_array_create(uint32_t length) {
|
||||
i16_array_t *a = gc_alloc(sizeof(i16_array_t));
|
||||
i16_array_t *a = calloc(1, sizeof(i16_array_t));
|
||||
if (length > 0) {
|
||||
i16_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -564,7 +575,7 @@ i16_array_t *i16_array_create_from_raw(int16_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
u8_array_t *u8_array_create(uint32_t length) {
|
||||
u8_array_t *a = gc_alloc(sizeof(u8_array_t));
|
||||
u8_array_t *a = calloc(1, sizeof(u8_array_t));
|
||||
if (length > 0) {
|
||||
u8_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -597,13 +608,13 @@ u8_array_t *u8_array_create_from_string(char *s) {
|
||||
}
|
||||
|
||||
char *u8_array_to_string(u8_array_t *a) {
|
||||
char *r = gc_alloc(a->length + 1);
|
||||
char *r = calloc(1, a->length + 1);
|
||||
memcpy(r, a->buffer, a->length);
|
||||
return r;
|
||||
}
|
||||
|
||||
i8_array_t *i8_array_create(uint32_t length) {
|
||||
i8_array_t *a = gc_alloc(sizeof(i8_array_t));
|
||||
i8_array_t *a = calloc(1, sizeof(i8_array_t));
|
||||
if (length > 0) {
|
||||
i8_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -620,7 +631,7 @@ i8_array_t *i8_array_create_from_raw(int8_t *raw, uint32_t length) {
|
||||
}
|
||||
|
||||
any_array_t *any_array_create(uint32_t length) {
|
||||
any_array_t *a = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *a = calloc(1, sizeof(any_array_t));
|
||||
if (length > 0) {
|
||||
any_array_resize(a, length);
|
||||
a->length = length;
|
||||
@@ -636,8 +647,21 @@ any_array_t *any_array_create_from_raw(void **raw, uint32_t length) {
|
||||
return a;
|
||||
}
|
||||
|
||||
any_array_t *any_array_create_from_raw_tmp(void **raw, uint32_t length) {
|
||||
any_array_t *a = (any_array_t *)string_tmp_alloc(sizeof(any_array_t));
|
||||
a->buffer = (void **)string_tmp_alloc(length * sizeof(void *));
|
||||
a->length = length;
|
||||
a->capacity = length;
|
||||
if (raw != NULL) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
a->buffer[i] = raw[i];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
string_array_t *string_array_create(uint32_t length) {
|
||||
string_array_t *a = gc_alloc(sizeof(string_array_t));
|
||||
string_array_t *a = calloc(1, sizeof(string_array_t));
|
||||
if (length > 0) {
|
||||
string_array_resize(a, length);
|
||||
a->length = length;
|
||||
|
||||
@@ -58,7 +58,8 @@ typedef struct string_array {
|
||||
|
||||
typedef u8_array_t buffer_t;
|
||||
|
||||
void array_free(void *a);
|
||||
void array_free(void *a); // Releases the buffer, keeps the struct
|
||||
void array_delete(void *a); // Releases the buffer and the struct, not the elements
|
||||
void i8_array_push(i8_array_t *a, int8_t e);
|
||||
void u8_array_push(u8_array_t *a, uint8_t e);
|
||||
void i16_array_push(i16_array_t *a, int16_t e);
|
||||
@@ -123,6 +124,7 @@ f32_array_t *f32_array_create(uint32_t length);
|
||||
f32_array_t *f32_array_create_from_buffer(buffer_t *b);
|
||||
f32_array_t *f32_array_create_from_array(f32_array_t *from);
|
||||
f32_array_t *f32_array_create_from_raw(float *raw, uint32_t length);
|
||||
f32_array_t *f32_array_create_from_raw_tmp(float *raw, uint32_t length);
|
||||
f32_array_t *f32_array_create_x(float x);
|
||||
f32_array_t *f32_array_create_xy(float x, float y);
|
||||
f32_array_t *f32_array_create_xyz(float x, float y, float z);
|
||||
@@ -148,6 +150,7 @@ i8_array_t *i8_array_create(uint32_t length);
|
||||
i8_array_t *i8_array_create_from_raw(int8_t *raw, uint32_t length);
|
||||
any_array_t *any_array_create(uint32_t length);
|
||||
any_array_t *any_array_create_from_raw(void **raw, uint32_t length);
|
||||
any_array_t *any_array_create_from_raw_tmp(void **raw, uint32_t length);
|
||||
string_array_t *string_array_create(uint32_t length);
|
||||
uint16_t float_to_half_fast(float value);
|
||||
uint8_t half_to_u8_fast(uint16_t h);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "iron_draw.h"
|
||||
#include "const_data.h"
|
||||
#include "iron_file.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_gpu.h"
|
||||
#include "iron_math.h"
|
||||
#include "iron_simd.h"
|
||||
@@ -124,6 +124,9 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *rect_vert,
|
||||
draw_pipeline_init(&image_r8_pipeline, &vert_shader, &frag_shader);
|
||||
image_r8_pipeline.color_attachment[0] = GPU_TEXTURE_FORMAT_R8;
|
||||
gpu_pipeline_compile(&image_r8_pipeline);
|
||||
|
||||
gpu_shader_destroy(&vert_shader);
|
||||
gpu_shader_destroy(&frag_shader);
|
||||
}
|
||||
|
||||
// Rect painter
|
||||
@@ -133,6 +136,9 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *rect_vert,
|
||||
draw_pipeline_init(&rect_pipeline, &vert_shader, &frag_shader);
|
||||
rect_pipeline.blend_source = GPU_BLEND_SOURCE_ALPHA;
|
||||
gpu_pipeline_compile(&rect_pipeline);
|
||||
|
||||
gpu_shader_destroy(&vert_shader);
|
||||
gpu_shader_destroy(&frag_shader);
|
||||
}
|
||||
|
||||
// Tris painter
|
||||
@@ -142,6 +148,9 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *rect_vert,
|
||||
draw_pipeline_init(&tris_pipeline, &vert_shader, &frag_shader);
|
||||
tris_pipeline.blend_source = GPU_BLEND_SOURCE_ALPHA;
|
||||
gpu_pipeline_compile(&tris_pipeline);
|
||||
|
||||
gpu_shader_destroy(&vert_shader);
|
||||
gpu_shader_destroy(&frag_shader);
|
||||
}
|
||||
|
||||
// Text painter
|
||||
@@ -156,6 +165,9 @@ void draw_init(buffer_t *image_vert, buffer_t *image_frag, buffer_t *rect_vert,
|
||||
draw_pipeline_init(&text_rt_pipeline, &vert_shader, &frag_shader);
|
||||
text_rt_pipeline.blend_source = GPU_BLEND_SOURCE_ALPHA;
|
||||
gpu_pipeline_compile(&text_rt_pipeline);
|
||||
|
||||
gpu_shader_destroy(&vert_shader);
|
||||
gpu_shader_destroy(&frag_shader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,8 +684,6 @@ void draw_font_13(draw_font_t *font) {
|
||||
}
|
||||
|
||||
void draw_font_init_glyphs(int from, int to) {
|
||||
gc_unroot(draw_font_glyphs);
|
||||
gc_unroot(draw_font_glyph_blocks);
|
||||
|
||||
draw_font_glyphs = i32_array_create(to - from);
|
||||
for (int i = from; i < to; ++i) {
|
||||
@@ -684,8 +694,6 @@ void draw_font_init_glyphs(int from, int to) {
|
||||
draw_font_glyph_blocks->buffer[1] = to - 1;
|
||||
draw_glyphs_version++;
|
||||
|
||||
gc_root(draw_font_glyphs);
|
||||
gc_root(draw_font_glyph_blocks);
|
||||
}
|
||||
|
||||
bool draw_font_has_glyph(int glyph) {
|
||||
@@ -709,9 +717,7 @@ void draw_font_build_glyphs() {
|
||||
++pos;
|
||||
}
|
||||
|
||||
gc_unroot(draw_font_glyph_blocks);
|
||||
draw_font_glyph_blocks = i32_array_create(2 * blocks);
|
||||
gc_root(draw_font_glyph_blocks);
|
||||
|
||||
draw_font_glyph_blocks->buffer[0] = draw_font_glyphs->buffer[0];
|
||||
next_char = draw_font_glyphs->buffer[0] + 1;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "iron_file.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_json.h"
|
||||
#include "iron_map.h"
|
||||
#include "iron_net.h"
|
||||
@@ -509,7 +509,7 @@ any_array_t *file_read_directory(char *path) {
|
||||
return files;
|
||||
}
|
||||
else {
|
||||
return gc_alloc(sizeof(any_array_t));
|
||||
return calloc(1, sizeof(any_array_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,7 +525,6 @@ any_array_t *file_read_directory(char *path) {
|
||||
buffer_t *blob = data_get_blob("data_list.json");
|
||||
char *s = sys_buffer_to_string(blob);
|
||||
file_internal = json_parse_to_map(s);
|
||||
gc_root(file_internal);
|
||||
}
|
||||
if (any_map_get(file_internal, path) != NULL) {
|
||||
return string_split(any_map_get(file_internal, path), ",");
|
||||
@@ -595,7 +594,6 @@ static void _file_download_to_callback(char *url, buffer_t *ab) {
|
||||
void file_download_to(char *url, char *dst_path, void (*done)(char *url), i32 size) {
|
||||
if (_file_download_map == NULL) {
|
||||
_file_download_map = any_map_create();
|
||||
gc_root(_file_download_map);
|
||||
}
|
||||
file_download_data_t *fdd = malloc(sizeof(file_download_data_t));
|
||||
fdd->done = done;
|
||||
@@ -618,7 +616,6 @@ static void _file_cache_cloud_callback(char *url) {
|
||||
void file_cache_cloud(char *path, void (*done)(char *dest), char *server) {
|
||||
if (_file_cache_cloud_map == NULL) {
|
||||
_file_cache_cloud_map = any_map_create();
|
||||
gc_root(_file_cache_cloud_map);
|
||||
}
|
||||
|
||||
char dest[512];
|
||||
@@ -658,14 +655,14 @@ void file_cache_cloud(char *path, void (*done)(char *dest), char *server) {
|
||||
|
||||
static void _file_init_cloud_bytes_callback(char *url, buffer_t *buffer) {
|
||||
if (buffer == NULL) {
|
||||
any_array_t *empty = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *empty = calloc(1, sizeof(any_array_t));
|
||||
any_map_set(file_cloud, "cloud", empty);
|
||||
console_error(strings_check_internet_connection());
|
||||
return;
|
||||
}
|
||||
|
||||
any_array_t *files = gc_alloc(sizeof(any_array_t));
|
||||
i32_array_t *sizes = gc_alloc(sizeof(i32_array_t));
|
||||
any_array_t *files = calloc(1, sizeof(any_array_t));
|
||||
i32_array_t *sizes = calloc(1, sizeof(i32_array_t));
|
||||
char *str = sys_buffer_to_string(buffer);
|
||||
i32 str_len = string_length(str);
|
||||
i32 pos_start = 0;
|
||||
@@ -689,7 +686,7 @@ static void _file_init_cloud_bytes_callback(char *url, buffer_t *buffer) {
|
||||
for (i32 i = 0; i < (i32)files->length; ++i) {
|
||||
char *file = files->buffer[i];
|
||||
if (path_is_folder(file)) {
|
||||
any_array_t *empty = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *empty = calloc(1, sizeof(any_array_t));
|
||||
any_map_set(file_cloud, substring(file, 0, string_length(file) - 1), empty);
|
||||
}
|
||||
}
|
||||
@@ -721,8 +718,6 @@ void file_init_cloud_bytes(void (*done)(void), char *append, char *server) {
|
||||
|
||||
void file_init_cloud(void (*done)(void), char *server) {
|
||||
file_cloud = any_map_create();
|
||||
gc_root(file_cloud);
|
||||
file_cloud_sizes = i32_map_create();
|
||||
gc_root(file_cloud_sizes);
|
||||
file_init_cloud_bytes(done, NULL, server);
|
||||
}
|
||||
|
||||
@@ -1,448 +0,0 @@
|
||||
|
||||
#include "iron_gc.h"
|
||||
|
||||
// A simple mark and sweep garbage collector for C.
|
||||
|
||||
#ifdef NO_GC
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *gc_alloc(size_t size) {
|
||||
return calloc(size, 1);
|
||||
}
|
||||
|
||||
void gc_leaf(void *ptr) {}
|
||||
void gc_root(void *ptr) {}
|
||||
void gc_unroot(void *ptr) {}
|
||||
void gc_resize(void *ptr, size_t size) {}
|
||||
|
||||
void *gc_realloc(void *ptr, size_t size) {
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void gc_free(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void gc_pause() {}
|
||||
void gc_resume() {}
|
||||
void gc_run() {}
|
||||
void gc_start(void *bos) {}
|
||||
void gc_stop() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PTRSIZE sizeof(char *)
|
||||
|
||||
#define GC_TAG_NONE 0x0
|
||||
#define GC_TAG_LEAF 0x1
|
||||
#define GC_TAG_MARK 0x2
|
||||
#define GC_TAG_ROOT 0x4
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define __builtin_frame_address(x) ((void)(x), _AddressOfReturnAddress())
|
||||
#endif
|
||||
|
||||
typedef struct gc_allocation {
|
||||
void *ptr; // mem pointer
|
||||
size_t size; // allocated size in bytes
|
||||
char tag; // the tag for mark-and-sweep
|
||||
char roots; // number of root users
|
||||
struct gc_allocation *next; // separate chaining
|
||||
} gc_allocation_t;
|
||||
|
||||
typedef struct gc_allocation_map {
|
||||
size_t capacity;
|
||||
size_t min_capacity;
|
||||
double downsize_factor;
|
||||
double upsize_factor;
|
||||
double sweep_factor;
|
||||
size_t sweep_limit;
|
||||
size_t size;
|
||||
gc_allocation_t **allocs;
|
||||
} gc_allocation_map_t;
|
||||
|
||||
typedef struct garbage_collector {
|
||||
struct gc_allocation_map *allocs; // allocation map
|
||||
bool paused; // (temporarily) switch gc on/off
|
||||
void *bos; // bottom of stack
|
||||
} garbage_collector_t;
|
||||
|
||||
static garbage_collector_t _gc;
|
||||
static garbage_collector_t *gc = &_gc;
|
||||
|
||||
static gc_allocation_t *gc_allocation_new(void *ptr, size_t size) {
|
||||
gc_allocation_t *a = (gc_allocation_t *)malloc(sizeof(gc_allocation_t));
|
||||
a->ptr = ptr;
|
||||
a->size = size;
|
||||
a->tag = GC_TAG_NONE;
|
||||
a->roots = 0;
|
||||
a->next = NULL;
|
||||
return a;
|
||||
}
|
||||
|
||||
static void gc_allocation_delete(gc_allocation_t *a) {
|
||||
free(a);
|
||||
}
|
||||
|
||||
static gc_allocation_map_t *gc_allocation_map_new(size_t min_capacity, size_t capacity, double sweep_factor, double downsize_factor, double upsize_factor) {
|
||||
gc_allocation_map_t *am = (gc_allocation_map_t *)malloc(sizeof(gc_allocation_map_t));
|
||||
am->min_capacity = min_capacity;
|
||||
am->capacity = capacity;
|
||||
am->sweep_factor = sweep_factor;
|
||||
am->sweep_limit = (int)(sweep_factor * am->capacity);
|
||||
am->downsize_factor = downsize_factor;
|
||||
am->upsize_factor = upsize_factor;
|
||||
am->allocs = (gc_allocation_t **)calloc(am->capacity, sizeof(gc_allocation_t *));
|
||||
am->size = 0;
|
||||
return am;
|
||||
}
|
||||
|
||||
static void gc_allocation_map_delete(gc_allocation_map_t *am) {
|
||||
// Iterate over the map
|
||||
gc_allocation_t *alloc;
|
||||
gc_allocation_t *tmp;
|
||||
for (size_t i = 0; i < am->capacity; ++i) {
|
||||
if ((alloc = am->allocs[i])) {
|
||||
// Make sure to follow the chain inside a bucket
|
||||
while (alloc) {
|
||||
tmp = alloc;
|
||||
alloc = alloc->next;
|
||||
// free the management structure
|
||||
gc_allocation_delete(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(am->allocs);
|
||||
free(am);
|
||||
}
|
||||
|
||||
static size_t gc_hash(void *ptr) {
|
||||
return ((uintptr_t)ptr) >> 3;
|
||||
}
|
||||
|
||||
static void gc_allocation_map_resize(gc_allocation_map_t *am, size_t new_capacity) {
|
||||
if (new_capacity <= am->min_capacity) {
|
||||
return;
|
||||
}
|
||||
// Replaces the existing items array in the hash table
|
||||
// with a resized one and pushes items into the new, correct buckets
|
||||
gc_allocation_t **resized_allocs = calloc(new_capacity, sizeof(gc_allocation_t *));
|
||||
|
||||
for (size_t i = 0; i < am->capacity; ++i) {
|
||||
gc_allocation_t *alloc = am->allocs[i];
|
||||
while (alloc) {
|
||||
gc_allocation_t *next_alloc = alloc->next;
|
||||
size_t new_index = gc_hash(alloc->ptr) & (new_capacity - 1);
|
||||
alloc->next = resized_allocs[new_index];
|
||||
resized_allocs[new_index] = alloc;
|
||||
alloc = next_alloc;
|
||||
}
|
||||
}
|
||||
free(am->allocs);
|
||||
am->capacity = new_capacity;
|
||||
am->allocs = resized_allocs;
|
||||
am->sweep_limit = am->size + am->sweep_factor * (am->capacity - am->size);
|
||||
}
|
||||
|
||||
static bool gc_allocation_map_resize_to_fit(gc_allocation_map_t *am) {
|
||||
double load_factor = (double)am->size / (double)am->capacity;
|
||||
if (load_factor > am->upsize_factor) {
|
||||
gc_allocation_map_resize(am, am->capacity * 2);
|
||||
return true;
|
||||
}
|
||||
if (load_factor < am->downsize_factor) {
|
||||
gc_allocation_map_resize(am, am->capacity / 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static gc_allocation_t *gc_allocation_map_get(gc_allocation_map_t *am, void *ptr) {
|
||||
size_t index = gc_hash(ptr) & (am->capacity - 1); // % am->capacity
|
||||
gc_allocation_t *cur = am->allocs[index];
|
||||
while (cur) {
|
||||
if (cur->ptr == ptr) {
|
||||
return cur;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gc_allocation_t *gc_allocation_map_put(gc_allocation_map_t *am, gc_allocation_t *alloc) {
|
||||
size_t index = gc_hash(alloc->ptr) & (am->capacity - 1);
|
||||
gc_allocation_t *cur = am->allocs[index];
|
||||
gc_allocation_t *prev = NULL;
|
||||
/* Upsert if ptr is already known */
|
||||
while (cur != NULL) {
|
||||
if (cur->ptr == alloc->ptr) {
|
||||
// found it
|
||||
alloc->next = cur->next;
|
||||
if (!prev) {
|
||||
// position 0
|
||||
am->allocs[index] = alloc;
|
||||
}
|
||||
else {
|
||||
// in the list
|
||||
prev->next = alloc;
|
||||
}
|
||||
gc_allocation_delete(cur);
|
||||
return alloc;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
/* Insert at the front of the separate chaining list */
|
||||
cur = am->allocs[index];
|
||||
alloc->next = cur;
|
||||
am->allocs[index] = alloc;
|
||||
am->size++;
|
||||
void *p = alloc->ptr;
|
||||
if (gc_allocation_map_resize_to_fit(am)) {
|
||||
alloc = gc_allocation_map_get(am, p);
|
||||
}
|
||||
return alloc;
|
||||
}
|
||||
|
||||
static void gc_allocation_map_remove(gc_allocation_map_t *am, void *ptr, bool allow_resize) {
|
||||
// ignores unknown keys
|
||||
size_t index = gc_hash(ptr) & (am->capacity - 1);
|
||||
gc_allocation_t *cur = am->allocs[index];
|
||||
gc_allocation_t *prev = NULL;
|
||||
gc_allocation_t *next;
|
||||
while (cur != NULL) {
|
||||
next = cur->next;
|
||||
if (cur->ptr == ptr) {
|
||||
// found it
|
||||
if (!prev) {
|
||||
// first item in list
|
||||
am->allocs[index] = cur->next;
|
||||
}
|
||||
else {
|
||||
// not the first item in the list
|
||||
prev->next = cur->next;
|
||||
}
|
||||
gc_allocation_delete(cur);
|
||||
am->size--;
|
||||
}
|
||||
else {
|
||||
// move on
|
||||
prev = cur;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
if (allow_resize) {
|
||||
gc_allocation_map_resize_to_fit(am);
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_alloc(void *ptr) {
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
/* Mark if alloc exists and is not tagged already, otherwise skip */
|
||||
if (alloc && !(alloc->tag & GC_TAG_MARK)) {
|
||||
alloc->tag |= GC_TAG_MARK;
|
||||
if (!(alloc->tag & GC_TAG_LEAF)) { // Skip contents
|
||||
/* Iterate over allocation contents and mark them as well */
|
||||
for (void **p = (void **)alloc->ptr; (char *)p <= (char *)alloc->ptr + alloc->size - PTRSIZE; ++p) {
|
||||
gc_mark_alloc(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_stack() {
|
||||
void *tos = __builtin_frame_address(0);
|
||||
void *bos = gc->bos;
|
||||
/* The stack grows towards smaller memory addresses, hence we scan tos->bos.
|
||||
* Stop scanning once the distance between tos & bos is too small to hold a valid pointer */
|
||||
for (void **p = (void **)tos; (char *)p <= (char *)bos - PTRSIZE; ++p) {
|
||||
gc_mark_alloc(*p);
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_roots() {
|
||||
for (size_t i = 0; i < gc->allocs->capacity; ++i) {
|
||||
gc_allocation_t *chunk = gc->allocs->allocs[i];
|
||||
while (chunk) {
|
||||
if (chunk->tag & GC_TAG_ROOT) {
|
||||
gc_mark_alloc(chunk->ptr);
|
||||
}
|
||||
chunk = chunk->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark() {
|
||||
/* Note: We only look at the stack and the heap, and ignore BSS. */
|
||||
/* Scan the heap for roots */
|
||||
gc_mark_roots();
|
||||
/* Dump registers onto stack and scan the stack */
|
||||
void (*volatile _mark_stack)(void) = gc_mark_stack;
|
||||
jmp_buf ctx;
|
||||
memset(&ctx, 0, sizeof(jmp_buf));
|
||||
setjmp(ctx);
|
||||
_mark_stack();
|
||||
}
|
||||
|
||||
static size_t gc_sweep() {
|
||||
size_t total = 0;
|
||||
for (size_t i = 0; i < gc->allocs->capacity; ++i) {
|
||||
gc_allocation_t *chunk = gc->allocs->allocs[i];
|
||||
gc_allocation_t *next = NULL;
|
||||
/* Iterate over separate chaining */
|
||||
while (chunk) {
|
||||
if (chunk->tag & GC_TAG_MARK) {
|
||||
/* unmark */
|
||||
chunk->tag &= ~GC_TAG_MARK;
|
||||
chunk = chunk->next;
|
||||
}
|
||||
else {
|
||||
/* no reference to this chunk, hence delete it */
|
||||
total += chunk->size;
|
||||
free(chunk->ptr);
|
||||
/* and remove it from the bookkeeping */
|
||||
next = chunk->next;
|
||||
gc_allocation_map_remove(gc->allocs, chunk->ptr, false);
|
||||
chunk = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
gc_allocation_map_resize_to_fit(gc->allocs);
|
||||
return total;
|
||||
}
|
||||
|
||||
void *gc_alloc(size_t size) {
|
||||
if (size == 0) {
|
||||
size = 1;
|
||||
}
|
||||
/* Check if we reached the high-water mark and need to clean up */
|
||||
if (gc->allocs->size > gc->allocs->sweep_limit && !gc->paused) {
|
||||
gc_run();
|
||||
}
|
||||
/* With cleanup out of the way, attempt to allocate memory */
|
||||
void *ptr = calloc(size, sizeof(uint8_t));
|
||||
/* If allocation fails, force an out-of-policy run to free some memory and try again. */
|
||||
if (!ptr && !gc->paused) {
|
||||
gc_run();
|
||||
ptr = calloc(size, sizeof(uint8_t));
|
||||
}
|
||||
/* Start managing the memory we received from the system */
|
||||
if (ptr) {
|
||||
gc_allocation_t *alloc = gc_allocation_map_put(gc->allocs, gc_allocation_new(ptr, size));
|
||||
/* Deal with metadata allocation failure */
|
||||
if (alloc) {
|
||||
ptr = alloc->ptr;
|
||||
}
|
||||
else {
|
||||
/* We failed to allocate the metadata, fail cleanly. */
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void gc_leaf(void *ptr) {
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (alloc) {
|
||||
alloc->tag |= GC_TAG_LEAF;
|
||||
}
|
||||
}
|
||||
|
||||
void gc_root(void *ptr) {
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (alloc) {
|
||||
alloc->roots++;
|
||||
alloc->tag |= GC_TAG_ROOT;
|
||||
}
|
||||
}
|
||||
|
||||
void gc_unroot(void *ptr) {
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (alloc) {
|
||||
alloc->roots--;
|
||||
if (alloc->roots == 0) {
|
||||
alloc->tag &= ~GC_TAG_ROOT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gc_resize(void *ptr, size_t size) {
|
||||
// Narrows the range gc_mark_alloc walks
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (alloc) {
|
||||
alloc->size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void *gc_realloc(void *ptr, size_t size) {
|
||||
if (ptr == NULL) {
|
||||
return gc_alloc(size);
|
||||
}
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (!alloc) {
|
||||
// the user passed an unknown pointer
|
||||
return NULL;
|
||||
}
|
||||
void *q = realloc(ptr, size);
|
||||
if (!q) {
|
||||
// realloc failed but ptr is still valid
|
||||
return NULL;
|
||||
}
|
||||
if (ptr == q) {
|
||||
// successful reallocation w/o copy
|
||||
alloc->size = size;
|
||||
}
|
||||
else {
|
||||
// successful reallocation w/ copy
|
||||
gc_allocation_map_remove(gc->allocs, ptr, true);
|
||||
gc_allocation_map_put(gc->allocs, gc_allocation_new(q, size));
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
void gc_free(void *ptr) {
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
gc_allocation_t *alloc = gc_allocation_map_get(gc->allocs, ptr);
|
||||
if (alloc) {
|
||||
free(ptr);
|
||||
gc_allocation_map_remove(gc->allocs, ptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void gc_pause() {
|
||||
gc->paused = true;
|
||||
}
|
||||
|
||||
void gc_resume() {
|
||||
gc->paused = false;
|
||||
}
|
||||
|
||||
void gc_run() {
|
||||
// double t = iron_time();
|
||||
gc_mark();
|
||||
gc_sweep();
|
||||
// iron_log("gc took %fms, freed %db.\n", (iron_time() - t) * 1000, collected);
|
||||
}
|
||||
|
||||
void gc_start(void *bos) {
|
||||
gc->paused = false;
|
||||
gc->bos = bos;
|
||||
// Create allocation map with no downsizing
|
||||
// Capacity must be a power of two
|
||||
gc->allocs = gc_allocation_map_new(1024 * 1024, 1024 * 1024, 0.5, 0.0, 0.8);
|
||||
}
|
||||
|
||||
void gc_stop() {
|
||||
gc_sweep();
|
||||
gc_allocation_map_delete(gc->allocs);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// point_t *p = GC_ALLOC_INIT(point_t, {x: 1.5, y: 3.5});
|
||||
#define GC_ALLOC_INIT(type, ...) (type *)memcpy(gc_alloc(sizeof(type)), (type[]){__VA_ARGS__}, sizeof(type))
|
||||
|
||||
void *gc_alloc(size_t size);
|
||||
void gc_leaf(void *ptr);
|
||||
void gc_root(void *ptr);
|
||||
void gc_unroot(void *ptr);
|
||||
void gc_resize(void *ptr, size_t size);
|
||||
void *gc_realloc(void *ptr, size_t size);
|
||||
void gc_free(void *ptr);
|
||||
void gc_pause();
|
||||
void gc_resume();
|
||||
void gc_run();
|
||||
void gc_start(void *bos);
|
||||
void gc_stop();
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "iron_input.h"
|
||||
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_string.h"
|
||||
#include "iron_system.h"
|
||||
#include <math.h>
|
||||
@@ -105,7 +105,6 @@ void input_register(void) {
|
||||
_input_occupied = false;
|
||||
|
||||
_mouse_buttons = string_array_create(0);
|
||||
gc_root(_mouse_buttons);
|
||||
string_array_push(_mouse_buttons, "left");
|
||||
string_array_push(_mouse_buttons, "right");
|
||||
string_array_push(_mouse_buttons, "middle");
|
||||
@@ -113,11 +112,8 @@ void input_register(void) {
|
||||
string_array_push(_mouse_buttons, "side2");
|
||||
|
||||
_mouse_buttons_down = u8_array_create(0);
|
||||
gc_root(_mouse_buttons_down);
|
||||
_mouse_buttons_started = u8_array_create(0);
|
||||
gc_root(_mouse_buttons_started);
|
||||
_mouse_buttons_released = u8_array_create(0);
|
||||
gc_root(_mouse_buttons_released);
|
||||
for (i32 i = 0; i < 5; ++i) {
|
||||
u8_array_push(_mouse_buttons_down, 0);
|
||||
u8_array_push(_mouse_buttons_started, 0);
|
||||
@@ -140,15 +136,11 @@ void input_register(void) {
|
||||
#endif
|
||||
|
||||
pen_buttons = string_array_create(0);
|
||||
gc_root(pen_buttons);
|
||||
string_array_push(pen_buttons, "tip");
|
||||
|
||||
pen_buttons_down = u8_array_create(0);
|
||||
gc_root(pen_buttons_down);
|
||||
pen_buttons_started = u8_array_create(0);
|
||||
gc_root(pen_buttons_started);
|
||||
pen_buttons_released = u8_array_create(0);
|
||||
gc_root(pen_buttons_released);
|
||||
u8_array_push(pen_buttons_down, 0);
|
||||
u8_array_push(pen_buttons_started, 0);
|
||||
u8_array_push(pen_buttons_released, 0);
|
||||
@@ -165,7 +157,6 @@ void input_register(void) {
|
||||
pen_last_y = -1.0f;
|
||||
|
||||
keyboard_keys = string_array_create(0);
|
||||
gc_root(keyboard_keys);
|
||||
string_array_push(keyboard_keys, "a");
|
||||
string_array_push(keyboard_keys, "b");
|
||||
string_array_push(keyboard_keys, "c");
|
||||
@@ -261,21 +252,16 @@ void input_register(void) {
|
||||
string_array_push(keyboard_keys, "f12");
|
||||
|
||||
keyboard_keys_down = i32_map_create();
|
||||
gc_root(keyboard_keys_down);
|
||||
keyboard_keys_started = i32_map_create();
|
||||
gc_root(keyboard_keys_started);
|
||||
keyboard_keys_released = i32_map_create();
|
||||
gc_root(keyboard_keys_released);
|
||||
|
||||
keyboard_keys_frame = string_array_create(0);
|
||||
gc_root(keyboard_keys_frame);
|
||||
|
||||
keyboard_repeat_key = false;
|
||||
keyboard_repeat_time = 0.0f;
|
||||
|
||||
#ifdef WITH_GAMEPAD
|
||||
gamepad_buttons_ps = string_array_create(0);
|
||||
gc_root(gamepad_buttons_ps);
|
||||
string_array_push(gamepad_buttons_ps, "cross");
|
||||
string_array_push(gamepad_buttons_ps, "circle");
|
||||
string_array_push(gamepad_buttons_ps, "square");
|
||||
@@ -296,7 +282,6 @@ void input_register(void) {
|
||||
string_array_push(gamepad_buttons_ps, "touchpad");
|
||||
|
||||
gamepad_buttons_xbox = string_array_create(0);
|
||||
gc_root(gamepad_buttons_xbox);
|
||||
string_array_push(gamepad_buttons_xbox, "a");
|
||||
string_array_push(gamepad_buttons_xbox, "b");
|
||||
string_array_push(gamepad_buttons_xbox, "x");
|
||||
@@ -319,7 +304,6 @@ void input_register(void) {
|
||||
gamepad_buttons = gamepad_buttons_ps;
|
||||
|
||||
gamepad_raws = any_array_create(0);
|
||||
gc_root(gamepad_raws);
|
||||
#endif
|
||||
|
||||
keyboard_reset();
|
||||
@@ -892,7 +876,7 @@ void keyboard_up_listener(i32 code) {
|
||||
void gamepad_end_frame(void) {}
|
||||
|
||||
gamepad_stick_t *gamepad_stick_create(void) {
|
||||
gamepad_stick_t *raw = gc_alloc(sizeof(gamepad_stick_t));
|
||||
gamepad_stick_t *raw = calloc(1, sizeof(gamepad_stick_t));
|
||||
raw->x = 0.0f;
|
||||
raw->y = 0.0f;
|
||||
raw->last_x = 0.0f;
|
||||
@@ -904,7 +888,7 @@ gamepad_stick_t *gamepad_stick_create(void) {
|
||||
}
|
||||
|
||||
gamepad_t *gamepad_create(void) {
|
||||
gamepad_t *raw = gc_alloc(sizeof(gamepad_t));
|
||||
gamepad_t *raw = calloc(1, sizeof(gamepad_t));
|
||||
raw->buttons_down = f32_array_create(0);
|
||||
raw->buttons_started = u8_array_create(0);
|
||||
raw->buttons_released = u8_array_create(0);
|
||||
@@ -915,9 +899,7 @@ gamepad_t *gamepad_create(void) {
|
||||
}
|
||||
|
||||
void gamepad_reset(void) {
|
||||
gc_unroot(gamepad_raws);
|
||||
gamepad_raws = any_array_create(0);
|
||||
gc_root(gamepad_raws);
|
||||
for (i32 i = 0; i < 4; ++i) {
|
||||
gamepad_t *g = gamepad_create();
|
||||
any_array_push(gamepad_raws, g);
|
||||
|
||||
+36
-23
@@ -7,7 +7,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *gc_alloc(size_t size);
|
||||
|
||||
#ifdef IRON_WASM
|
||||
#define PTR_SIZE 4
|
||||
@@ -286,7 +285,7 @@ void *json_parse(char *s) {
|
||||
load_tokens(s);
|
||||
|
||||
uint32_t out_size = strlen(s) * 2;
|
||||
decoded = gc_alloc(out_size);
|
||||
decoded = calloc(1, out_size);
|
||||
wi = 0;
|
||||
bottom = 0;
|
||||
array_count = 1;
|
||||
@@ -331,36 +330,48 @@ any_map_t *json_parse_to_map(char *s) {
|
||||
return m;
|
||||
}
|
||||
|
||||
static char *encoded;
|
||||
static buffer_t encoded;
|
||||
static int keys;
|
||||
static int array_nest = -1;
|
||||
static int array_length[16];
|
||||
|
||||
static void enc(char *s) {
|
||||
string_buffer_append(&encoded, s);
|
||||
}
|
||||
|
||||
void json_encode_begin() {
|
||||
encoded = "{";
|
||||
if (encoded.buffer == NULL) {
|
||||
string_buffer_init(&encoded);
|
||||
}
|
||||
string_buffer_reset(&encoded);
|
||||
enc("{");
|
||||
keys = 0;
|
||||
}
|
||||
|
||||
char *json_encode_end() {
|
||||
encoded = string("%s}", encoded);
|
||||
return encoded;
|
||||
enc("}");
|
||||
return string_copy(string_buffer_get(&encoded));
|
||||
}
|
||||
|
||||
void json_encode_key(char *k) {
|
||||
if (keys > 0) {
|
||||
encoded = string("%s,", encoded);
|
||||
enc(",");
|
||||
}
|
||||
encoded = string("%s\"%s\":", encoded, k);
|
||||
enc("\"");
|
||||
enc(k);
|
||||
enc("\":");
|
||||
keys++;
|
||||
}
|
||||
|
||||
void json_encode_null(char *k) {
|
||||
json_encode_key(k);
|
||||
encoded = string("%snull", encoded);
|
||||
enc("null");
|
||||
}
|
||||
|
||||
void json_encode_string_value(char *v) {
|
||||
encoded = string("%s\"%s\"", encoded, v);
|
||||
enc("\"");
|
||||
enc(v);
|
||||
enc("\"");
|
||||
}
|
||||
|
||||
void json_encode_string(char *k, char *v) {
|
||||
@@ -376,7 +387,7 @@ void json_encode_string_array(char *k, string_array_t *a) {
|
||||
json_encode_begin_array(k);
|
||||
for (uint32_t i = 0; i < a->length; ++i) {
|
||||
if (i > 0) {
|
||||
encoded = string("%s,", encoded);
|
||||
enc(",");
|
||||
}
|
||||
json_encode_string_value(a->buffer[i]);
|
||||
}
|
||||
@@ -385,12 +396,12 @@ void json_encode_string_array(char *k, string_array_t *a) {
|
||||
|
||||
void json_encode_f32(char *k, float f) {
|
||||
json_encode_key(k);
|
||||
encoded = string("%s%s", encoded, f32_to_string_with_zeros(f));
|
||||
enc(f32_to_string_with_zeros(f));
|
||||
}
|
||||
|
||||
void json_encode_i32(char *k, int i) {
|
||||
json_encode_key(k);
|
||||
encoded = string("%s%s", encoded, i32_to_string(i));
|
||||
enc(i32_to_string(i));
|
||||
}
|
||||
|
||||
void json_encode_f32_array(char *k, f32_array_t *a) {
|
||||
@@ -401,9 +412,9 @@ void json_encode_f32_array(char *k, f32_array_t *a) {
|
||||
json_encode_begin_array(k);
|
||||
for (uint32_t i = 0; i < a->length; ++i) {
|
||||
if (i > 0) {
|
||||
encoded = string("%s,", encoded);
|
||||
enc(",");
|
||||
}
|
||||
encoded = string("%s%s", encoded, f32_to_string_with_zeros(a->buffer[i]));
|
||||
enc(f32_to_string_with_zeros(a->buffer[i]));
|
||||
}
|
||||
json_encode_end_array();
|
||||
}
|
||||
@@ -416,43 +427,43 @@ void json_encode_i32_array(char *k, i32_array_t *a) {
|
||||
json_encode_begin_array(k);
|
||||
for (uint32_t i = 0; i < a->length; ++i) {
|
||||
if (i > 0) {
|
||||
encoded = string("%s,", encoded);
|
||||
enc(",");
|
||||
}
|
||||
encoded = string("%s%s", encoded, i32_to_string(a->buffer[i]));
|
||||
enc(i32_to_string(a->buffer[i]));
|
||||
}
|
||||
json_encode_end_array();
|
||||
}
|
||||
|
||||
void json_encode_bool(char *k, bool b) {
|
||||
json_encode_key(k);
|
||||
encoded = string("%s%s", encoded, b ? "true" : "false");
|
||||
enc(b ? "true" : "false");
|
||||
}
|
||||
|
||||
void json_encode_begin_array(char *k) {
|
||||
array_nest++;
|
||||
array_length[array_nest] = 0;
|
||||
json_encode_key(k);
|
||||
encoded = string("%s[", encoded);
|
||||
enc("[");
|
||||
}
|
||||
|
||||
void json_encode_end_array() {
|
||||
array_nest--;
|
||||
encoded = string("%s]", encoded);
|
||||
enc("]");
|
||||
}
|
||||
|
||||
void json_encode_begin_object() {
|
||||
if (array_nest > -1) {
|
||||
if (array_length[array_nest] > 0) {
|
||||
encoded = string("%s,", encoded);
|
||||
enc(",");
|
||||
}
|
||||
array_length[array_nest]++;
|
||||
}
|
||||
keys = 0;
|
||||
encoded = string("%s{", encoded);
|
||||
enc("{");
|
||||
}
|
||||
|
||||
void json_encode_end_object() {
|
||||
encoded = string("%s}", encoded);
|
||||
enc("}");
|
||||
}
|
||||
|
||||
void json_encode_map(any_map_t *m) {
|
||||
@@ -460,6 +471,8 @@ void json_encode_map(any_map_t *m) {
|
||||
for (uint32_t i = 0; i < keys->length; i++) {
|
||||
json_encode_string(keys->buffer[i], any_map_get(m, keys->buffer[i]));
|
||||
}
|
||||
array_free(keys);
|
||||
free(keys);
|
||||
}
|
||||
|
||||
static char *jenc_src;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// armorpaint/base/assets/licenses/license_lz4-wasm.md
|
||||
#include "iron_lz4.h"
|
||||
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_system.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +28,6 @@ buffer_t *lz4_encode(buffer_t *b) {
|
||||
|
||||
if (_lz4_hash_table == NULL) {
|
||||
_lz4_hash_table = i32_array_create(65536);
|
||||
gc_root(_lz4_hash_table);
|
||||
}
|
||||
for (uint32_t i = 0; i < _lz4_hash_table->length; ++i) {
|
||||
_lz4_hash_table->buffer[i] = -65536;
|
||||
@@ -136,7 +135,10 @@ buffer_t *lz4_encode(buffer_t *b) {
|
||||
obuf->buffer[opos++] = ibuf->buffer[anchor_pos++];
|
||||
}
|
||||
|
||||
return buffer_slice(obuf, 0, opos);
|
||||
buffer_t *result = buffer_slice(obuf, 0, opos);
|
||||
array_free(obuf);
|
||||
free(obuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
buffer_t *lz4_decode(buffer_t *b, uint32_t olen) {
|
||||
|
||||
+36
-19
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "iron_map.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_string.h"
|
||||
|
||||
static size_t hash(const char *k) {
|
||||
@@ -56,12 +56,9 @@ static void resize(any_map_t *m, int elem_size) {
|
||||
int cap = m->keys->capacity == 0 ? 16 : m->keys->capacity * 2;
|
||||
any_map_t *tmp = any_map_create();
|
||||
tmp->keys->capacity = cap;
|
||||
tmp->keys->buffer = gc_alloc(cap * sizeof(void *));
|
||||
tmp->keys->buffer = calloc(1, cap * sizeof(void *));
|
||||
tmp->values->capacity = cap;
|
||||
tmp->values->buffer = gc_alloc(cap * elem_size);
|
||||
if (elem_size < 8) {
|
||||
gc_leaf(tmp->values->buffer);
|
||||
}
|
||||
tmp->values->buffer = calloc(1, cap * elem_size);
|
||||
|
||||
any_array_t *old_keys = map_keys(m);
|
||||
for (int i = 0; i < old_keys->length; ++i) {
|
||||
@@ -78,8 +75,16 @@ static void resize(any_map_t *m, int elem_size) {
|
||||
}
|
||||
}
|
||||
|
||||
array_free(old_keys);
|
||||
free(old_keys);
|
||||
|
||||
array_free(m->keys);
|
||||
free(m->keys);
|
||||
array_free(m->values);
|
||||
free(m->values);
|
||||
m->keys = tmp->keys;
|
||||
m->values = tmp->values;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void i32_map_set(i32_map_t *m, char *k, int v) {
|
||||
@@ -144,7 +149,7 @@ void map_delete(any_map_t *m, char *k) {
|
||||
}
|
||||
|
||||
any_array_t *map_keys(any_map_t *m) {
|
||||
string_array_t *keys = gc_alloc(sizeof(string_array_t));
|
||||
string_array_t *keys = calloc(1, sizeof(string_array_t));
|
||||
string_array_resize(keys, m->keys->length);
|
||||
for (int i = 0; i < m->keys->capacity; ++i) {
|
||||
if (m->keys->buffer[i] != NULL) {
|
||||
@@ -154,17 +159,29 @@ any_array_t *map_keys(any_map_t *m) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Stored keys and values are not owned by the map
|
||||
void map_free(any_map_t *m) {
|
||||
if (m == NULL) {
|
||||
return;
|
||||
}
|
||||
array_free(m->keys);
|
||||
free(m->keys);
|
||||
array_free(m->values);
|
||||
free(m->values);
|
||||
free(m);
|
||||
}
|
||||
|
||||
i32_map_t *i32_map_create() {
|
||||
i32_map_t *r = gc_alloc(sizeof(i32_map_t));
|
||||
r->keys = gc_alloc(sizeof(string_array_t));
|
||||
r->values = gc_alloc(sizeof(i32_array_t));
|
||||
i32_map_t *r = calloc(1, sizeof(i32_map_t));
|
||||
r->keys = calloc(1, sizeof(string_array_t));
|
||||
r->values = calloc(1, sizeof(i32_array_t));
|
||||
return r;
|
||||
}
|
||||
|
||||
any_map_t *any_map_create() {
|
||||
any_map_t *r = gc_alloc(sizeof(any_map_t));
|
||||
r->keys = gc_alloc(sizeof(string_array_t));
|
||||
r->values = gc_alloc(sizeof(any_array_t));
|
||||
any_map_t *r = calloc(1, sizeof(any_map_t));
|
||||
r->keys = calloc(1, sizeof(string_array_t));
|
||||
r->values = calloc(1, sizeof(any_array_t));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -223,15 +240,15 @@ i32_array_t *imap_keys(any_imap_t *m) {
|
||||
}
|
||||
|
||||
i32_imap_t *i32_imap_create() {
|
||||
i32_imap_t *r = gc_alloc(sizeof(i32_imap_t));
|
||||
r->keys = gc_alloc(sizeof(i32_array_t));
|
||||
r->values = gc_alloc(sizeof(i32_array_t));
|
||||
i32_imap_t *r = calloc(1, sizeof(i32_imap_t));
|
||||
r->keys = calloc(1, sizeof(i32_array_t));
|
||||
r->values = calloc(1, sizeof(i32_array_t));
|
||||
return r;
|
||||
}
|
||||
|
||||
any_imap_t *any_imap_create() {
|
||||
any_imap_t *r = gc_alloc(sizeof(any_imap_t));
|
||||
r->keys = gc_alloc(sizeof(i32_array_t));
|
||||
r->values = gc_alloc(sizeof(any_array_t));
|
||||
any_imap_t *r = calloc(1, sizeof(any_imap_t));
|
||||
r->keys = calloc(1, sizeof(i32_array_t));
|
||||
r->values = calloc(1, sizeof(any_array_t));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ void *any_map_get(any_map_t *m, char *k);
|
||||
|
||||
void map_delete(any_map_t *m, char *k);
|
||||
any_array_t *map_keys(any_map_t *m);
|
||||
void map_free(any_map_t *m);
|
||||
|
||||
i32_map_t *i32_map_create();
|
||||
any_map_t *any_map_create();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "iron_math.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@@ -646,7 +646,8 @@ mat4_decomposed_t *mat4_decompose(mat4_t m) {
|
||||
m.m[10] *= invs;
|
||||
rot = quat_from_rot_mat(m);
|
||||
|
||||
mat4_decomposed_t *dec = gc_alloc(sizeof(mat4_decomposed_t));
|
||||
// Frame temporary..
|
||||
mat4_decomposed_t *dec = (mat4_decomposed_t *)string_tmp_alloc(sizeof(mat4_decomposed_t));
|
||||
dec->loc = loc;
|
||||
dec->rot = rot;
|
||||
dec->scl = scl;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "iron_obj.h"
|
||||
|
||||
#include "iron_array.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_math.h"
|
||||
#include "iron_string.h"
|
||||
#include <math.h>
|
||||
@@ -220,7 +220,7 @@ raw_mesh_t *obj_parse(buffer_t *file_bytes, char split_code, uint64_t start_pos,
|
||||
bytes = file_bytes->buffer;
|
||||
bytes_length = file_bytes->length;
|
||||
|
||||
part = gc_alloc(sizeof(raw_mesh_t));
|
||||
part = calloc(1, sizeof(raw_mesh_t));
|
||||
part->scale_pos = 1.0;
|
||||
part->scale_tex = 1.0;
|
||||
part->pos = start_pos;
|
||||
@@ -247,9 +247,9 @@ raw_mesh_t *obj_parse(buffer_t *file_bytes, char split_code, uint64_t start_pos,
|
||||
uv_temp = *uv_first;
|
||||
}
|
||||
else {
|
||||
memset(&pos_temp, 0, sizeof(pos_temp));
|
||||
memset(&uv_temp, 0, sizeof(uv_temp));
|
||||
memset(&nor_temp, 0, sizeof(nor_temp));
|
||||
array_free(&pos_temp);
|
||||
array_free(&uv_temp);
|
||||
array_free(&nor_temp);
|
||||
}
|
||||
|
||||
while (part->pos < bytes_length) {
|
||||
@@ -446,6 +446,7 @@ raw_mesh_t *obj_parse(buffer_t *file_bytes, char split_code, uint64_t start_pos,
|
||||
if (!udim) {
|
||||
reading_object = true;
|
||||
}
|
||||
free(part->name);
|
||||
part->name = string_copy(read_string());
|
||||
}
|
||||
else if (c0 == '\n') { // Empty line
|
||||
@@ -650,5 +651,5 @@ void obj_destroy(raw_mesh_t *part) {
|
||||
free(part->nora);
|
||||
free(part->texa);
|
||||
free(part->inda);
|
||||
gc_free(part);
|
||||
free(part);
|
||||
}
|
||||
|
||||
+110
-83
@@ -1,10 +1,11 @@
|
||||
#include "iron_path.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "iron_array.h"
|
||||
#include "iron_file.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_map.h"
|
||||
#include "iron_string.h"
|
||||
|
||||
@@ -27,7 +28,6 @@ static string_array_t *_path_displacement_ext = NULL;
|
||||
string_array_t *path_mesh_formats(void) {
|
||||
if (_path_mesh_formats == NULL) {
|
||||
_path_mesh_formats = string_array_create(0);
|
||||
gc_root(_path_mesh_formats);
|
||||
string_array_push(_path_mesh_formats, "obj");
|
||||
string_array_push(_path_mesh_formats, "blend");
|
||||
}
|
||||
@@ -37,7 +37,6 @@ string_array_t *path_mesh_formats(void) {
|
||||
string_array_t *path_texture_formats(void) {
|
||||
if (_path_texture_formats == NULL) {
|
||||
_path_texture_formats = string_array_create(0);
|
||||
gc_root(_path_texture_formats);
|
||||
string_array_push(_path_texture_formats, "jpg");
|
||||
string_array_push(_path_texture_formats, "jpeg");
|
||||
string_array_push(_path_texture_formats, "png");
|
||||
@@ -54,7 +53,6 @@ string_array_t *path_texture_formats(void) {
|
||||
string_array_t *path_sound_formats(void) {
|
||||
if (_path_sound_formats == NULL) {
|
||||
_path_sound_formats = string_array_create(0);
|
||||
gc_root(_path_sound_formats);
|
||||
string_array_push(_path_sound_formats, "wav");
|
||||
string_array_push(_path_sound_formats, "ogg");
|
||||
}
|
||||
@@ -64,7 +62,6 @@ string_array_t *path_sound_formats(void) {
|
||||
string_array_t *path_text_formats(void) {
|
||||
if (_path_text_formats == NULL) {
|
||||
_path_text_formats = string_array_create(0);
|
||||
gc_root(_path_text_formats);
|
||||
string_array_push(_path_text_formats, "txt");
|
||||
string_array_push(_path_text_formats, "json");
|
||||
}
|
||||
@@ -74,7 +71,6 @@ string_array_t *path_text_formats(void) {
|
||||
string_array_t *path_base_color_ext(void) {
|
||||
if (_path_base_color_ext == NULL) {
|
||||
_path_base_color_ext = string_array_create(0);
|
||||
gc_root(_path_base_color_ext);
|
||||
string_array_push(_path_base_color_ext, "albedo");
|
||||
string_array_push(_path_base_color_ext, "alb");
|
||||
string_array_push(_path_base_color_ext, "basecol");
|
||||
@@ -93,7 +89,6 @@ string_array_t *path_base_color_ext(void) {
|
||||
string_array_t *path_opacity_ext(void) {
|
||||
if (_path_opacity_ext == NULL) {
|
||||
_path_opacity_ext = string_array_create(0);
|
||||
gc_root(_path_opacity_ext);
|
||||
string_array_push(_path_opacity_ext, "opac");
|
||||
string_array_push(_path_opacity_ext, "opacity");
|
||||
string_array_push(_path_opacity_ext, "alpha");
|
||||
@@ -104,7 +99,6 @@ string_array_t *path_opacity_ext(void) {
|
||||
string_array_t *path_normal_map_ext(void) {
|
||||
if (_path_normal_map_ext == NULL) {
|
||||
_path_normal_map_ext = string_array_create(0);
|
||||
gc_root(_path_normal_map_ext);
|
||||
string_array_push(_path_normal_map_ext, "normal");
|
||||
string_array_push(_path_normal_map_ext, "normals");
|
||||
string_array_push(_path_normal_map_ext, "nor");
|
||||
@@ -118,7 +112,6 @@ string_array_t *path_normal_map_ext(void) {
|
||||
string_array_t *path_occlusion_ext(void) {
|
||||
if (_path_occlusion_ext == NULL) {
|
||||
_path_occlusion_ext = string_array_create(0);
|
||||
gc_root(_path_occlusion_ext);
|
||||
string_array_push(_path_occlusion_ext, "ao");
|
||||
string_array_push(_path_occlusion_ext, "occlusion");
|
||||
string_array_push(_path_occlusion_ext, "ambientOcclusion");
|
||||
@@ -131,7 +124,6 @@ string_array_t *path_occlusion_ext(void) {
|
||||
string_array_t *path_roughness_ext(void) {
|
||||
if (_path_roughness_ext == NULL) {
|
||||
_path_roughness_ext = string_array_create(0);
|
||||
gc_root(_path_roughness_ext);
|
||||
string_array_push(_path_roughness_ext, "roughness");
|
||||
string_array_push(_path_roughness_ext, "rough");
|
||||
string_array_push(_path_roughness_ext, "r");
|
||||
@@ -143,7 +135,6 @@ string_array_t *path_roughness_ext(void) {
|
||||
string_array_t *path_metallic_ext(void) {
|
||||
if (_path_metallic_ext == NULL) {
|
||||
_path_metallic_ext = string_array_create(0);
|
||||
gc_root(_path_metallic_ext);
|
||||
string_array_push(_path_metallic_ext, "metallic");
|
||||
string_array_push(_path_metallic_ext, "metal");
|
||||
string_array_push(_path_metallic_ext, "metalness");
|
||||
@@ -156,7 +147,6 @@ string_array_t *path_metallic_ext(void) {
|
||||
string_array_t *path_displacement_ext(void) {
|
||||
if (_path_displacement_ext == NULL) {
|
||||
_path_displacement_ext = string_array_create(0);
|
||||
gc_root(_path_displacement_ext);
|
||||
string_array_push(_path_displacement_ext, "displacement");
|
||||
string_array_push(_path_displacement_ext, "height");
|
||||
string_array_push(_path_displacement_ext, "h");
|
||||
@@ -165,6 +155,21 @@ string_array_t *path_displacement_ext(void) {
|
||||
return _path_displacement_ext;
|
||||
}
|
||||
|
||||
static bool has_ext(char *path, char *ext) {
|
||||
size_t len_path = strlen(path);
|
||||
size_t len_ext = strlen(ext);
|
||||
if (len_path < len_ext + 1 || path[len_path - len_ext - 1] != '.') {
|
||||
return false;
|
||||
}
|
||||
char *tail = path + len_path - len_ext;
|
||||
for (size_t i = 0; i < len_ext; ++i) {
|
||||
if (tolower((unsigned char)tail[i]) != tolower((unsigned char)ext[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *data_path(void) {
|
||||
#ifdef IRON_ANDROID
|
||||
return "data" PATH_SEP;
|
||||
@@ -181,7 +186,7 @@ char *path_to_relative(char *from, char *to) {
|
||||
any_array_t *a = string_split(from, PATH_SEP);
|
||||
any_array_t *b = string_split(to, PATH_SEP);
|
||||
if (a->length > 0 && !path_is_folder(from)) {
|
||||
array_pop(a);
|
||||
free(array_pop(a));
|
||||
}
|
||||
while (a->length > 0 && b->length > 0) {
|
||||
char *a0 = a->buffer[0];
|
||||
@@ -189,23 +194,36 @@ char *path_to_relative(char *from, char *to) {
|
||||
if (string_equals(a0, b0)) {
|
||||
array_shift(a);
|
||||
array_shift(b);
|
||||
free(a0);
|
||||
free(b0);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
char *p = "";
|
||||
|
||||
buffer_t sb;
|
||||
string_buffer_init(&sb);
|
||||
for (uint32_t i = 0; i < a->length; ++i) {
|
||||
p = string("%s.." PATH_SEP, p);
|
||||
string_buffer_append(&sb, ".." PATH_SEP);
|
||||
}
|
||||
p = string("%s%s", p, string_array_join(b, PATH_SEP));
|
||||
char *joined = string_array_join(b, PATH_SEP);
|
||||
string_buffer_append(&sb, joined);
|
||||
free(joined);
|
||||
|
||||
char *p = string_copy(string_buffer_get(&sb));
|
||||
string_buffer_free(&sb);
|
||||
string_split_free(a);
|
||||
string_split_free(b);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *path_normalize(char *path) {
|
||||
size_t path_len = strlen(path);
|
||||
char *trimmed = NULL;
|
||||
if (path_len > 0 && ends_with(path, PATH_SEP)) {
|
||||
path = substring(path, 0, path_len - 1);
|
||||
trimmed = substring(path, 0, path_len - 1);
|
||||
path = trimmed;
|
||||
}
|
||||
any_array_t *ar = string_split(path, PATH_SEP);
|
||||
uint32_t i = 0;
|
||||
@@ -214,6 +232,8 @@ char *path_normalize(char *path) {
|
||||
char *ar_i = ar->buffer[i];
|
||||
char *ar_i_1 = ar->buffer[i - 1];
|
||||
if (string_equals(ar_i, "..") && !string_equals(ar_i_1, "..")) {
|
||||
free(ar_i);
|
||||
free(ar_i_1);
|
||||
array_splice(ar, i - 1, 2);
|
||||
i--;
|
||||
}
|
||||
@@ -225,7 +245,10 @@ char *path_normalize(char *path) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return string_array_join(ar, PATH_SEP);
|
||||
char *r = string_array_join(ar, PATH_SEP);
|
||||
string_split_free(ar);
|
||||
free(trimmed);
|
||||
return r;
|
||||
}
|
||||
|
||||
char *path_base_dir(char *path) {
|
||||
@@ -239,86 +262,53 @@ char *path_base_name(char *path) {
|
||||
return substring(path, last_sep + 1, last_dot);
|
||||
}
|
||||
|
||||
bool path_is_mesh(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
string_array_t *formats = path_mesh_formats();
|
||||
static bool path_has_format(char *path, string_array_t *formats) {
|
||||
for (uint32_t i = 0; i < formats->length; ++i) {
|
||||
char *s = formats->buffer[i];
|
||||
char *ext = string(".%s", s);
|
||||
if (ends_with(p, ext)) {
|
||||
if (has_ext(path, formats->buffer[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool path_is_mesh(char *path) {
|
||||
return path_has_format(path, path_mesh_formats());
|
||||
}
|
||||
|
||||
bool path_is_texture(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
string_array_t *formats = path_texture_formats();
|
||||
for (uint32_t i = 0; i < formats->length; ++i) {
|
||||
char *s = formats->buffer[i];
|
||||
char *ext = string(".%s", s);
|
||||
if (ends_with(p, ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return path_has_format(path, path_texture_formats());
|
||||
}
|
||||
|
||||
bool path_is_sound(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
string_array_t *formats = path_sound_formats();
|
||||
for (uint32_t i = 0; i < formats->length; ++i) {
|
||||
char *s = formats->buffer[i];
|
||||
char *ext = string(".%s", s);
|
||||
if (ends_with(p, ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return path_has_format(path, path_sound_formats());
|
||||
}
|
||||
|
||||
bool path_is_font(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".ttf") || ends_with(p, ".ttc") || ends_with(p, ".otf");
|
||||
return has_ext(path, "ttf") || has_ext(path, "ttc") || has_ext(path, "otf");
|
||||
}
|
||||
|
||||
bool path_is_project(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".arm");
|
||||
return has_ext(path, "arm");
|
||||
}
|
||||
|
||||
bool path_is_plugin(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".c");
|
||||
return has_ext(path, "c");
|
||||
}
|
||||
|
||||
bool path_is_json(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".json");
|
||||
return has_ext(path, "json");
|
||||
}
|
||||
|
||||
bool path_is_text(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
string_array_t *formats = path_text_formats();
|
||||
for (uint32_t i = 0; i < formats->length; ++i) {
|
||||
char *s = formats->buffer[i];
|
||||
char *ext = string(".%s", s);
|
||||
if (ends_with(p, ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return path_has_format(path, path_text_formats());
|
||||
}
|
||||
|
||||
bool path_is_ext_format(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".stl") || ends_with(p, ".svg");
|
||||
return has_ext(path, "stl") || has_ext(path, "svg");
|
||||
}
|
||||
|
||||
bool path_is_lut(char *path) {
|
||||
char *p = to_lower_case(path);
|
||||
return ends_with(p, ".cube");
|
||||
return has_ext(path, "cube");
|
||||
}
|
||||
|
||||
bool path_is_known(char *path) {
|
||||
@@ -326,16 +316,52 @@ bool path_is_known(char *path) {
|
||||
path_is_text(path) || path_is_ext_format(path) || path_is_lut(path);
|
||||
}
|
||||
|
||||
bool path_check_ext(char *p, string_array_t *exts) {
|
||||
p = string_replace_all(p, "-", "_");
|
||||
for (uint32_t i = 0; i < exts->length; ++i) {
|
||||
char *ext = exts->buffer[i];
|
||||
char *ext_underscore = string("_%s", ext);
|
||||
if (ends_with(p, ext_underscore)) {
|
||||
static char tag_char(char c) {
|
||||
return c == '-' ? '_' : c;
|
||||
}
|
||||
|
||||
static bool ends_with_tag(char *p, char *tag) {
|
||||
size_t len_p = strlen(p);
|
||||
size_t len_tag = strlen(tag);
|
||||
if (len_p < len_tag + 1) {
|
||||
return false;
|
||||
}
|
||||
char *tail = p + len_p - len_tag;
|
||||
if (tag_char(tail[-1]) != '_') {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < len_tag; ++i) {
|
||||
if (tag_char(tail[i]) != tag[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool contains_tag(char *p, char *tag) {
|
||||
size_t len_tag = strlen(tag);
|
||||
for (char *s = p; *s != '\0'; ++s) {
|
||||
if (tag_char(*s) != '_') {
|
||||
continue;
|
||||
}
|
||||
size_t i = 0;
|
||||
while (i < len_tag && tag_char(s[1 + i]) == tag[i]) {
|
||||
++i;
|
||||
}
|
||||
if (i == len_tag && tag_char(s[1 + len_tag]) == '_') {
|
||||
return true;
|
||||
}
|
||||
char *ext_underscore_mid = string("_%s_", ext);
|
||||
if (string_index_of(p, ext_underscore_mid) >= 0 && !ends_with(p, "_preview") && !ends_with(p, "_icon")) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool path_check_ext(char *p, string_array_t *exts) {
|
||||
for (uint32_t i = 0; i < exts->length; ++i) {
|
||||
char *ext = exts->buffer[i];
|
||||
if (ends_with_tag(p, ext)) {
|
||||
return true;
|
||||
}
|
||||
if (contains_tag(p, ext) && !ends_with_tag(p, "preview") && !ends_with_tag(p, "icon")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -371,10 +397,13 @@ bool path_is_displacement_tex(char *p) {
|
||||
}
|
||||
|
||||
bool path_is_folder(char *p) {
|
||||
char *p_slash = string_replace_all(p, "\\", "/");
|
||||
any_array_t *split = string_split(p_slash, "/");
|
||||
char *last = array_pop(split);
|
||||
return string_index_of(last, ".") < 0;
|
||||
char *last = p;
|
||||
for (char *s = p; *s != '\0'; ++s) {
|
||||
if (*s == '/' || *s == '\\') {
|
||||
last = s + 1;
|
||||
}
|
||||
}
|
||||
return strchr(last, '.') == NULL;
|
||||
}
|
||||
|
||||
bool path_is_protected(void) {
|
||||
@@ -392,10 +421,8 @@ bool path_is_protected(void) {
|
||||
}
|
||||
|
||||
char *path_join(char *a, char *b) {
|
||||
char *path = a;
|
||||
if (!ends_with(path, PATH_SEP)) {
|
||||
path = string("%s" PATH_SEP, path);
|
||||
if (ends_with(a, PATH_SEP)) {
|
||||
return string("%s%s", a, b);
|
||||
}
|
||||
path = string("%s%s", path, b);
|
||||
return path;
|
||||
return string("%s" PATH_SEP "%s", a, b);
|
||||
}
|
||||
|
||||
@@ -1326,7 +1326,7 @@ static bool mesh_bounds(object_t *obj, vec4_t *center, vec4_t *extent) {
|
||||
}
|
||||
|
||||
physics_body_t *physics_body_create(object_t *obj, physics_shape_t shape, float mass) {
|
||||
physics_body_t *body = GC_ALLOC_INIT(physics_body_t, {0});
|
||||
physics_body_t *body = ALLOC_INIT(physics_body_t, {0});
|
||||
body->shape = shape;
|
||||
body->mass = mass;
|
||||
body->obj = obj;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "iron_raycast.h"
|
||||
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_math.h"
|
||||
#include <math.h>
|
||||
|
||||
@@ -87,7 +87,7 @@ vec4_t raycast_plane_intersect(vec4_t normal, vec4_t a, f32 input_x, f32 input_y
|
||||
}
|
||||
|
||||
ray_t *ray_create(vec4_t origin, vec4_t dir) {
|
||||
ray_t *raw = gc_alloc(sizeof(ray_t));
|
||||
ray_t *raw = calloc(1, sizeof(ray_t));
|
||||
raw->origin = origin;
|
||||
raw->dir = dir;
|
||||
return raw;
|
||||
|
||||
+67
-13
@@ -6,15 +6,47 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *gc_alloc(size_t size);
|
||||
void gc_leaf(void *ptr);
|
||||
|
||||
char *string_alloc(int size) {
|
||||
char *r = gc_alloc(size);
|
||||
gc_leaf(r);
|
||||
char *r = calloc(1, size);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define STRING_TMP_BUFFER_SIZE (4 * 1024 * 1024)
|
||||
static char *string_tmp_buffer = NULL;
|
||||
static size_t string_tmp_pos = 0;
|
||||
|
||||
char *string_tmp_alloc(int size) {
|
||||
if (string_tmp_buffer == NULL) {
|
||||
string_tmp_buffer = malloc(STRING_TMP_BUFFER_SIZE);
|
||||
}
|
||||
if (string_tmp_pos + size > STRING_TMP_BUFFER_SIZE) {
|
||||
return string_alloc(size);
|
||||
}
|
||||
char *r = string_tmp_buffer + string_tmp_pos;
|
||||
string_tmp_pos += ((size_t)size + 7) & ~(size_t)7;
|
||||
memset(r, 0, size);
|
||||
return r;
|
||||
}
|
||||
|
||||
void string_tmp_reset() {
|
||||
string_tmp_pos = 0;
|
||||
}
|
||||
|
||||
char *string_tmp(char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int len = vsnprintf(NULL, 0, fmt, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
char *str = string_tmp_alloc(len + 1);
|
||||
vsnprintf(str, len + 1, fmt, args);
|
||||
va_end(args);
|
||||
return str;
|
||||
}
|
||||
|
||||
char *string(char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@@ -52,14 +84,14 @@ bool string_equals(char *a, char *b) {
|
||||
|
||||
char *i32_to_string(int32_t i) {
|
||||
int l = snprintf(NULL, 0, "%d", i);
|
||||
char *r = string_alloc(l + 1);
|
||||
char *r = string_tmp_alloc(l + 1);
|
||||
sprintf(r, "%d", i);
|
||||
return r;
|
||||
}
|
||||
|
||||
char *i32_to_string_hex(int32_t i) {
|
||||
int l = snprintf(NULL, 0, "%X", i);
|
||||
char *r = string_alloc(l + 1);
|
||||
char *r = string_tmp_alloc(l + 1);
|
||||
sprintf(r, "%X", i);
|
||||
return r;
|
||||
}
|
||||
@@ -74,21 +106,21 @@ char *i32_to_string_hex(int32_t i) {
|
||||
|
||||
char *i64_to_string(int64_t i) {
|
||||
int l = snprintf(NULL, 0, PERCENT_LD, i);
|
||||
char *r = string_alloc(l + 1);
|
||||
char *r = string_tmp_alloc(l + 1);
|
||||
sprintf(r, PERCENT_LD, i);
|
||||
return r;
|
||||
}
|
||||
|
||||
char *u64_to_string(uint64_t i) {
|
||||
int l = snprintf(NULL, 0, PERCENT_LU, i);
|
||||
char *r = string_alloc(l + 1);
|
||||
char *r = string_tmp_alloc(l + 1);
|
||||
sprintf(r, PERCENT_LU, i);
|
||||
return r;
|
||||
}
|
||||
|
||||
char *f32_to_string_with_zeros(float f) {
|
||||
int l = snprintf(NULL, 0, "%f", f);
|
||||
char *r = string_alloc(l + 1);
|
||||
char *r = string_tmp_alloc(l + 1);
|
||||
sprintf(r, "%f", f);
|
||||
return r;
|
||||
}
|
||||
@@ -139,7 +171,7 @@ int32_t string_last_index_of(char *str, char *search) {
|
||||
}
|
||||
|
||||
any_array_t *string_split(char *s, char *sep) {
|
||||
any_array_t *a = gc_alloc(sizeof(any_array_t));
|
||||
any_array_t *a = calloc(1, sizeof(any_array_t));
|
||||
int sep_len = strlen(sep);
|
||||
char *pos = s;
|
||||
while (true) {
|
||||
@@ -158,6 +190,17 @@ any_array_t *string_split(char *s, char *sep) {
|
||||
return a;
|
||||
}
|
||||
|
||||
void string_split_free(any_array_t *a) {
|
||||
if (a == NULL) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < a->length; ++i) {
|
||||
free(a->buffer[i]);
|
||||
}
|
||||
array_free(a);
|
||||
free(a);
|
||||
}
|
||||
|
||||
char *string_array_join(any_array_t *a, char *separator) {
|
||||
int len = 0;
|
||||
int len_sep = strlen(separator);
|
||||
@@ -178,7 +221,7 @@ char *string_array_join(any_array_t *a, char *separator) {
|
||||
return r;
|
||||
}
|
||||
|
||||
char *string_replace_all(char *s, char *search, char *replace) {
|
||||
static char *string_replace_all_impl(char *s, char *search, char *replace, bool use_tmp) {
|
||||
size_t search_len = strlen(search);
|
||||
size_t replace_len = strlen(replace);
|
||||
size_t buffer_size = strlen(s) + 1;
|
||||
@@ -192,7 +235,7 @@ char *string_replace_all(char *s, char *search, char *replace) {
|
||||
buffer_size += count * (replace_len - search_len);
|
||||
}
|
||||
|
||||
char *buffer = string_alloc(buffer_size);
|
||||
char *buffer = use_tmp ? string_tmp_alloc(buffer_size) : string_alloc(buffer_size);
|
||||
char *buffer_pos = buffer;
|
||||
while (1) {
|
||||
char *p = strstr(s, search);
|
||||
@@ -209,6 +252,14 @@ char *string_replace_all(char *s, char *search, char *replace) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *string_replace_all(char *s, char *search, char *replace) {
|
||||
return string_replace_all_impl(s, search, replace, false);
|
||||
}
|
||||
|
||||
char *string_replace_all_tmp(char *s, char *search, char *replace) {
|
||||
return string_replace_all_impl(s, search, replace, true);
|
||||
}
|
||||
|
||||
char *substring(char *s, int32_t start, int32_t end) {
|
||||
char *buffer = string_alloc(end - start + 1);
|
||||
for (int i = 0; i < end - start; ++i) {
|
||||
@@ -242,6 +293,9 @@ bool starts_with(char *s, char *start) {
|
||||
bool ends_with(char *s, char *end) {
|
||||
size_t len_s = strlen(s);
|
||||
size_t len_end = strlen(end);
|
||||
if (len_end > len_s) {
|
||||
return false;
|
||||
}
|
||||
return strncmp(s + len_s - len_end, end, len_end) == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
char *string_alloc(int size);
|
||||
char *string(char *fmt, ...);
|
||||
char *string_copy(char *a);
|
||||
|
||||
// Frame temporary
|
||||
char *string_tmp_alloc(int size);
|
||||
char *string_tmp(char *fmt, ...);
|
||||
char *string_replace_all_tmp(char *s, char *search, char *replace);
|
||||
void string_tmp_reset();
|
||||
int string_length(char *str);
|
||||
bool string_equals(char *a, char *b);
|
||||
char *i32_to_string(int32_t i);
|
||||
@@ -22,6 +28,7 @@ int32_t string_index_of(char *s, char *search);
|
||||
int32_t string_index_of_pos(char *s, char *search, int pos);
|
||||
int32_t string_last_index_of(char *s, char *search);
|
||||
any_array_t *string_split(char *s, char *sep);
|
||||
void string_split_free(any_array_t *a);
|
||||
char *string_array_join(any_array_t *a, char *separator);
|
||||
char *string_replace_all(char *s, char *search, char *replace);
|
||||
char *substring(char *s, int32_t start, int32_t end);
|
||||
|
||||
+28
-19
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "iron_array.h"
|
||||
#include "iron_draw.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_input.h"
|
||||
#include "iron_map.h"
|
||||
#include "iron_string.h"
|
||||
@@ -33,6 +33,7 @@ i32 iron_display_frequency(i32 index);
|
||||
i32 iron_display_ppi(i32 index);
|
||||
bool iron_display_is_primary(i32 index);
|
||||
gpu_shader_t *gpu_create_shader(buffer_t *data, i32 shader_type);
|
||||
void iron_delete_blob(buffer_t *buffer);
|
||||
char *data_path(void);
|
||||
|
||||
#ifdef WITH_GAMEPAD
|
||||
@@ -66,13 +67,13 @@ static f32 _sys_time_real_delta = 0.0f;
|
||||
static i32 _sys_time_frequency = -1;
|
||||
|
||||
static sys_callback_t *_sys_callback_create(void (*f)(void)) {
|
||||
sys_callback_t *cb = gc_alloc(sizeof(sys_callback_t));
|
||||
sys_callback_t *cb = calloc(1, sizeof(sys_callback_t));
|
||||
cb->f = f;
|
||||
return cb;
|
||||
}
|
||||
|
||||
static callback_t *_callback_create(void (*f)(void *data), void *data) {
|
||||
callback_t *cb = gc_alloc(sizeof(callback_t));
|
||||
callback_t *cb = calloc(1, sizeof(callback_t));
|
||||
cb->f = f;
|
||||
cb->data = data;
|
||||
return cb;
|
||||
@@ -80,21 +81,13 @@ static callback_t *_callback_create(void (*f)(void *data), void *data) {
|
||||
|
||||
void sys_start(iron_window_options_t *ops) {
|
||||
_sys_foreground_listeners = any_array_create(0);
|
||||
gc_root(_sys_foreground_listeners);
|
||||
_sys_background_listeners = any_array_create(0);
|
||||
gc_root(_sys_background_listeners);
|
||||
_sys_shutdown_listeners = any_array_create(0);
|
||||
gc_root(_sys_shutdown_listeners);
|
||||
_sys_drop_files_listeners = any_array_create(0);
|
||||
gc_root(_sys_drop_files_listeners);
|
||||
_sys_on_next_frames = any_array_create(0);
|
||||
gc_root(_sys_on_next_frames);
|
||||
_sys_on_end_frames = any_array_create(0);
|
||||
gc_root(_sys_on_end_frames);
|
||||
_sys_on_updates = any_array_create(0);
|
||||
gc_root(_sys_on_updates);
|
||||
_sys_shaders = any_map_create();
|
||||
gc_root(_sys_shaders);
|
||||
|
||||
_iron_init(ops);
|
||||
|
||||
@@ -137,8 +130,13 @@ void sys_start(iron_window_options_t *ops) {
|
||||
strcat(path_text_frag, "draw_text.frag");
|
||||
strcat(path_text_frag, ext);
|
||||
|
||||
draw_init(iron_load_blob(path_image_vert), iron_load_blob(path_image_frag), iron_load_blob(path_rect_vert), iron_load_blob(path_rect_frag),
|
||||
iron_load_blob(path_tris_vert), iron_load_blob(path_tris_frag), iron_load_blob(path_text_vert), iron_load_blob(path_text_frag));
|
||||
buffer_t *draw_blobs[8] = {iron_load_blob(path_image_vert), iron_load_blob(path_image_frag), iron_load_blob(path_rect_vert),
|
||||
iron_load_blob(path_rect_frag), iron_load_blob(path_tris_vert), iron_load_blob(path_tris_frag),
|
||||
iron_load_blob(path_text_vert), iron_load_blob(path_text_frag)};
|
||||
draw_init(draw_blobs[0], draw_blobs[1], draw_blobs[2], draw_blobs[3], draw_blobs[4], draw_blobs[5], draw_blobs[6], draw_blobs[7]);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
iron_delete_blob(draw_blobs[i]);
|
||||
}
|
||||
|
||||
_iron_set_update_callback(sys_render);
|
||||
_iron_set_drop_files_callback(sys_drop_files_callback);
|
||||
@@ -175,7 +173,7 @@ void sys_notify_on_app_state(void (*on_foreground)(void), void (*on_background)(
|
||||
}
|
||||
|
||||
void sys_notify_on_drop_files(void (*drop_files_listener)(char *s)) {
|
||||
sys_string_callback_t *cb = gc_alloc(sizeof(sys_string_callback_t));
|
||||
sys_string_callback_t *cb = calloc(1, sizeof(sys_string_callback_t));
|
||||
cb->f = drop_files_listener;
|
||||
any_array_push(_sys_drop_files_listeners, cb);
|
||||
}
|
||||
@@ -349,7 +347,9 @@ gpu_shader_t *sys_get_shader(char *name) {
|
||||
strcat(path, name);
|
||||
strcat(path, ext);
|
||||
gpu_shader_type_t shader_type = ends_with(name, ".frag") ? GPU_SHADER_TYPE_FRAGMENT : GPU_SHADER_TYPE_VERTEX;
|
||||
shader = gpu_create_shader(iron_load_blob(path), (i32)shader_type);
|
||||
buffer_t *blob = iron_load_blob(path);
|
||||
shader = gpu_create_shader(blob, (i32)shader_type);
|
||||
iron_delete_blob(blob);
|
||||
any_map_set(_sys_shaders, name, shader);
|
||||
}
|
||||
return shader;
|
||||
@@ -403,17 +403,26 @@ static void _sys_run_callbacks(any_array_t *cbs, i32 len) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _sys_run_callbacks_once(any_array_t *cbs, i32 len) {
|
||||
for (i32 i = 0; i < len; ++i) {
|
||||
callback_t *cb = cbs->buffer[i];
|
||||
if (cb != NULL) {
|
||||
cb->f(cb->data);
|
||||
free(cb);
|
||||
}
|
||||
}
|
||||
array_splice(cbs, 0, len);
|
||||
}
|
||||
|
||||
void sys_render(void) {
|
||||
i32 len = _sys_on_next_frames->length;
|
||||
_sys_run_callbacks(_sys_on_next_frames, len);
|
||||
array_splice(_sys_on_next_frames, 0, len);
|
||||
_sys_run_callbacks_once(_sys_on_next_frames, len);
|
||||
|
||||
scene_render_frame();
|
||||
_sys_run_callbacks(_sys_on_updates, _sys_on_updates->length);
|
||||
|
||||
len = _sys_on_end_frames->length;
|
||||
_sys_run_callbacks(_sys_on_end_frames, len);
|
||||
array_splice(_sys_on_end_frames, 0, len);
|
||||
_sys_run_callbacks_once(_sys_on_end_frames, len);
|
||||
|
||||
input_end_frame();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "iron_tween.h"
|
||||
|
||||
#include "iron_array.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -14,7 +14,6 @@ void sys_notify_on_update(void (*f)(void *data), void *data);
|
||||
static void _tween_register(void) {
|
||||
_tween_registered = true;
|
||||
_tween_anims = any_array_create(0);
|
||||
gc_root(_tween_anims);
|
||||
sys_notify_on_update(tween_update, NULL);
|
||||
}
|
||||
|
||||
@@ -30,7 +29,7 @@ tween_anim_t *tween_to(tween_anim_t *anim) {
|
||||
}
|
||||
|
||||
tween_anim_t *tween_timer(f32 delay, void (*done)(void *data), void *data) {
|
||||
tween_anim_t *a = gc_alloc(sizeof(tween_anim_t));
|
||||
tween_anim_t *a = calloc(1, sizeof(tween_anim_t));
|
||||
a->target = NULL;
|
||||
a->to = 0.0f;
|
||||
a->duration = 0.0f;
|
||||
@@ -49,9 +48,7 @@ void tween_stop(tween_anim_t *anim) {
|
||||
}
|
||||
|
||||
void tween_reset(void) {
|
||||
gc_unroot(_tween_anims);
|
||||
_tween_anims = any_array_create(0);
|
||||
gc_root(_tween_anims);
|
||||
}
|
||||
|
||||
static f32 _tween_ease_linear(f32 k) {
|
||||
|
||||
+17
-11
@@ -1,7 +1,7 @@
|
||||
#include "iron_ui.h"
|
||||
#include "iron_draw.h"
|
||||
#include "iron_file.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_gpu.h"
|
||||
#include "iron_string.h"
|
||||
#include "iron_system.h"
|
||||
@@ -114,7 +114,7 @@ void ui_set_current(ui_t *_current) {
|
||||
}
|
||||
|
||||
ui_handle_t *ui_handle_create() {
|
||||
ui_handle_t *h = (ui_handle_t *)gc_alloc(sizeof(ui_handle_t));
|
||||
ui_handle_t *h = (ui_handle_t *)calloc(1, sizeof(ui_handle_t));
|
||||
memset(h, 0, sizeof(ui_handle_t));
|
||||
h->redraws = 2;
|
||||
h->color = 0xffffffff;
|
||||
@@ -1703,7 +1703,6 @@ void ui_init(ui_t *ui, ui_options_t *ops) {
|
||||
current->input_y = -1;
|
||||
if (ui_combo_search_handle == NULL) {
|
||||
ui_combo_search_handle = ui_handle_create();
|
||||
gc_root(ui_combo_search_handle);
|
||||
}
|
||||
if (_ui_row2 == NULL) {
|
||||
_ui_row2 = f32_array_create_from_raw((float[]){1.0 / 2.0, 1.0 / 2.0}, 2);
|
||||
@@ -1712,12 +1711,6 @@ void ui_init(ui_t *ui, ui_options_t *ops) {
|
||||
_ui_row5 = f32_array_create_from_raw((float[]){1.0 / 5.0, 1.0 / 5.0, 1.0 / 5.0, 1.0 / 5.0, 1.0 / 5.0}, 5);
|
||||
_ui_row6 = f32_array_create_from_raw((float[]){1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0}, 6);
|
||||
_ui_row7 = f32_array_create_from_raw((float[]){1.0 / 7.0, 1.0 / 7.0, 1.0 / 7.0, 1.0 / 7.0, 1.0 / 7.0, 1.0 / 7.0, 1.0 / 7.0}, 7);
|
||||
gc_root(_ui_row2);
|
||||
gc_root(_ui_row3);
|
||||
gc_root(_ui_row4);
|
||||
gc_root(_ui_row5);
|
||||
gc_root(_ui_row6);
|
||||
gc_root(_ui_row7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2262,13 +2255,26 @@ int ui_combo(ui_handle_t *handle, string_array_t *texts, char *label, bool show_
|
||||
}
|
||||
if (ui_get_released(UI_ELEMENT_H())) {
|
||||
if (current->combo_selected_handle == NULL) {
|
||||
static string_array_t texts_copy = {0};
|
||||
static char label_copy[256];
|
||||
for (int i = 0; i < texts_copy.length; ++i) {
|
||||
free(texts_copy.buffer[i]);
|
||||
}
|
||||
texts_copy.length = 0;
|
||||
for (int i = 0; i < texts->length; ++i) {
|
||||
string_array_push(&texts_copy, string_copy(texts->buffer[i]));
|
||||
}
|
||||
if (label != NULL) {
|
||||
strncpy(label_copy, label, sizeof(label_copy) - 1);
|
||||
label_copy[sizeof(label_copy) - 1] = '\0';
|
||||
}
|
||||
current->input_enabled = false;
|
||||
current->combo_selected_handle = handle;
|
||||
current->combo_selected_window = current->current_window;
|
||||
current->combo_selected_align = align;
|
||||
current->combo_selected_texts = texts;
|
||||
current->combo_selected_texts = &texts_copy;
|
||||
current->combo_selected_images = NULL;
|
||||
current->combo_selected_label = label;
|
||||
current->combo_selected_label = label != NULL ? label_copy : NULL;
|
||||
current->combo_selected_x = current->_x + current->_window_x;
|
||||
current->combo_selected_y = current->_y + current->_window_y + UI_ELEMENT_H();
|
||||
current->combo_selected_w = current->_w;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "iron_draw.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_string.h"
|
||||
#include "iron_system.h"
|
||||
#include "iron_ui.h"
|
||||
@@ -1014,7 +1014,7 @@ ui_handle_t *ui_handle(char *s) {
|
||||
ui_handle_t *h = any_map_get(ui_children, s);
|
||||
if (h == NULL) {
|
||||
h = ui_handle_create();
|
||||
any_map_set(ui_children, s, h);
|
||||
any_map_set(ui_children, string_copy(s), h);
|
||||
return h;
|
||||
}
|
||||
h->init = false;
|
||||
@@ -1022,13 +1022,13 @@ ui_handle_t *ui_handle(char *s) {
|
||||
}
|
||||
|
||||
ui_t *ui_create(ui_options_t *ops) {
|
||||
ui_t *raw = GC_ALLOC_INIT(ui_t, {0});
|
||||
ui_t *raw = ALLOC_INIT(ui_t, {0});
|
||||
ui_init(raw, ops);
|
||||
return raw;
|
||||
}
|
||||
|
||||
ui_theme_t *ui_theme_create() {
|
||||
ui_theme_t *raw = GC_ALLOC_INIT(ui_theme_t, {0});
|
||||
ui_theme_t *raw = ALLOC_INIT(ui_theme_t, {0});
|
||||
ui_theme_default(raw);
|
||||
return raw;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "iron_armpack.h"
|
||||
#include "iron_array.h"
|
||||
#include "iron_draw.h"
|
||||
#include "iron_gc.h"
|
||||
#include "iron_alloc.h"
|
||||
#include "iron_gpu.h"
|
||||
#include "iron_json.h"
|
||||
#include "iron_string.h"
|
||||
@@ -66,7 +66,7 @@ void ui_nodes_init(ui_nodes_t *nodes) {
|
||||
nodes->snap_from_id = -1;
|
||||
nodes->snap_to_id = -1;
|
||||
nodes->link_drag_id = -1;
|
||||
nodes->nodes_selected_id = gc_alloc(sizeof(i32_array_t));
|
||||
nodes->nodes_selected_id = calloc(1, sizeof(i32_array_t));
|
||||
nodes->handle = ui_handle_create();
|
||||
}
|
||||
|
||||
@@ -561,9 +561,7 @@ void ui_node_draw_body(ui_node_t *node, ui_node_canvas_t *canvas, float nx, floa
|
||||
ar->length = texts_count;
|
||||
}
|
||||
else {
|
||||
gc_unroot(ar);
|
||||
ar = (*ui_nodes_enum_texts)(node->type);
|
||||
gc_root(ar);
|
||||
}
|
||||
|
||||
strcpy(label, ui_tr(but->name));
|
||||
@@ -842,8 +840,7 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) {
|
||||
draw_begin(current, false, 0);
|
||||
}
|
||||
if (ui_nodes_exclude_remove == NULL) {
|
||||
ui_nodes_exclude_remove = gc_alloc(sizeof(string_array_t));
|
||||
gc_root(ui_nodes_exclude_remove);
|
||||
ui_nodes_exclude_remove = calloc(1, sizeof(string_array_t));
|
||||
}
|
||||
|
||||
float wx = current->_window_x;
|
||||
@@ -1271,9 +1268,7 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) {
|
||||
ui_node_link_array_t links = {.buffer = copy_links, .length = copy_links_count};
|
||||
copy_canvas.nodes = &nodes;
|
||||
copy_canvas.links = &links;
|
||||
gc_unroot(ui_clipboard);
|
||||
ui_clipboard = ui_node_canvas_to_json(©_canvas);
|
||||
gc_root(ui_clipboard);
|
||||
iron_copy_to_clipboard(ui_clipboard);
|
||||
}
|
||||
cut_selected = ui_is_cut;
|
||||
@@ -1288,7 +1283,6 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) {
|
||||
if (is_json) {
|
||||
|
||||
ui_node_canvas_t *paste_canvas = json_parse(ui_clipboard);
|
||||
gc_root(paste_canvas); // TODO
|
||||
|
||||
// Convert button data from string to u8 array
|
||||
for (int i = 0; i < paste_canvas->nodes->length; ++i) {
|
||||
@@ -1758,9 +1752,8 @@ void nodes_on_custom_button(i32 node_id, char *button_name) {
|
||||
}
|
||||
|
||||
ui_nodes_t *ui_nodes_create() {
|
||||
ui_nodes_t *raw = GC_ALLOC_INIT(ui_nodes_t, {0});
|
||||
ui_nodes_t *raw = ALLOC_INIT(ui_nodes_t, {0});
|
||||
ui_nodes_init(raw);
|
||||
gc_unroot(ui_nodes_exclude_remove);
|
||||
ui_nodes_exclude_remove = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
"OUTPUT_MATERIAL_PBR",
|
||||
@@ -1769,7 +1762,6 @@ ui_nodes_t *ui_nodes_create() {
|
||||
"brush_output_node",
|
||||
},
|
||||
4);
|
||||
gc_root(ui_nodes_exclude_remove);
|
||||
ui_nodes_on_custom_button = nodes_on_custom_button;
|
||||
return raw;
|
||||
}
|
||||
|
||||
@@ -63,19 +63,10 @@ typedef struct {
|
||||
minic_token_t cur;
|
||||
} minic_lexer_t;
|
||||
|
||||
void *gc_alloc(size_t size);
|
||||
void gc_root(void *ptr);
|
||||
void gc_unroot(void *ptr);
|
||||
void gc_free(void *ptr);
|
||||
void gc_resize(void *ptr, size_t size);
|
||||
|
||||
static minic_u8 *minic_active_mem = NULL;
|
||||
static int *minic_active_mem_used = NULL;
|
||||
|
||||
static void minic_mem_sync(void) {
|
||||
gc_resize(minic_active_mem, (size_t)*minic_active_mem_used);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *kw;
|
||||
minic_tok_type_t tok;
|
||||
@@ -222,7 +213,6 @@ static void minic_lex_next(minic_lexer_t *l) {
|
||||
}
|
||||
minic_active_mem[wi++] = '\0';
|
||||
*minic_active_mem_used = (wi + 7) & ~7;
|
||||
minic_mem_sync();
|
||||
if (l->src[l->pos] == '"') {
|
||||
l->pos++; // Consume closing '"'
|
||||
}
|
||||
@@ -298,7 +288,6 @@ void *minic_alloc(int size) {
|
||||
// Align to 8 bytes
|
||||
int aligned = (*minic_active_mem_used + 7) & ~7;
|
||||
*minic_active_mem_used = aligned + size;
|
||||
minic_mem_sync();
|
||||
return &minic_active_mem[aligned];
|
||||
}
|
||||
|
||||
@@ -853,7 +842,6 @@ static minic_val_t minic_call_in_ctx(minic_ctx_t *ctx, minic_func_t *fn, minic_v
|
||||
int saved_used = ctx->mem_used;
|
||||
minic_val_t r = minic_call(&ctx->e, fn, args, argc);
|
||||
ctx->mem_used = saved_used;
|
||||
minic_mem_sync();
|
||||
minic_active_mem = prev_mem;
|
||||
minic_active_mem_used = prev_mem_used;
|
||||
return r;
|
||||
@@ -2049,12 +2037,8 @@ static void minic_register_funcs(minic_env_t *e) {
|
||||
minic_ctx_t *minic_eval_named(const char *src, const char *filename) {
|
||||
minic_register_builtins();
|
||||
|
||||
// The arena stores every script variable, including pointers to GC-managed host objects
|
||||
minic_ctx_t *ctx = (minic_ctx_t *)gc_alloc(sizeof(minic_ctx_t));
|
||||
gc_root(ctx);
|
||||
ctx->mem = (minic_u8 *)gc_alloc(MINIC_MEM_SIZE);
|
||||
gc_root(ctx->mem);
|
||||
gc_resize(ctx->mem, 0);
|
||||
minic_ctx_t *ctx = (minic_ctx_t *)calloc(1, sizeof(minic_ctx_t));
|
||||
ctx->mem = (minic_u8 *)calloc(1, MINIC_MEM_SIZE);
|
||||
// Copy the source so the context stays valid after the caller frees its buffer
|
||||
int src_len = (int)strlen(src);
|
||||
ctx->src_copy = (char *)malloc(src_len + 1);
|
||||
@@ -2113,11 +2097,9 @@ minic_ctx_t *minic_eval(const char *src) {
|
||||
|
||||
void minic_ctx_free(minic_ctx_t *ctx) {
|
||||
if (ctx != NULL) {
|
||||
gc_unroot(ctx->mem);
|
||||
gc_free(ctx->mem);
|
||||
free(ctx->mem);
|
||||
free(ctx->src_copy);
|
||||
gc_unroot(ctx);
|
||||
gc_free(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,37 +25,36 @@ void scene_ready() {
|
||||
|
||||
void ready() {
|
||||
render_path_commands = render_commands;
|
||||
gc_root(render_path_commands);
|
||||
|
||||
scene_t *scene = GC_ALLOC_INIT(
|
||||
scene_t *scene = ALLOC_INIT(
|
||||
scene_t,
|
||||
{.name = "Scene",
|
||||
.objects = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(
|
||||
ALLOC_INIT(
|
||||
obj_t, {.name = "Cube", .type = "mesh_object", .data_ref = "cube.arm/Cube", .material_ref = "MyMaterial", .visible = true, .spawn = true}),
|
||||
GC_ALLOC_INIT(obj_t, {.name = "Camera", .type = "camera_object", .data_ref = "MyCamera", .visible = true, .spawn = true}),
|
||||
ALLOC_INIT(obj_t, {.name = "Camera", .type = "camera_object", .data_ref = "MyCamera", .visible = true, .spawn = true}),
|
||||
},
|
||||
2),
|
||||
.camera_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(camera_data_t, {.name = "MyCamera", .near_plane = 0.1, .far_plane = 100.0, .fov = 0.85}),
|
||||
ALLOC_INIT(camera_data_t, {.name = "MyCamera", .near_plane = 0.1, .far_plane = 100.0, .fov = 0.85}),
|
||||
},
|
||||
1),
|
||||
.camera_ref = "Camera",
|
||||
.world_ref = "MyWorld",
|
||||
.world_datas = any_array_create_from_raw((void *[]){GC_ALLOC_INIT(world_data_t, {.name = "MyWorld", .color = 0xff000000})}, 1),
|
||||
.world_datas = any_array_create_from_raw((void *[]){ALLOC_INIT(world_data_t, {.name = "MyWorld", .color = 0xff000000})}, 1),
|
||||
.material_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(material_data_t,
|
||||
ALLOC_INIT(material_data_t,
|
||||
{.name = "MyMaterial",
|
||||
.shader = "MyShader",
|
||||
.contexts = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(material_context_t, {.name = "mesh",
|
||||
ALLOC_INIT(material_context_t, {.name = "mesh",
|
||||
.bind_textures = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(bind_tex_t, {.name = "my_texture", .file = "texture.k"}),
|
||||
ALLOC_INIT(bind_tex_t, {.name = "my_texture", .file = "texture.k"}),
|
||||
},
|
||||
1)}),
|
||||
},
|
||||
@@ -64,10 +63,10 @@ void ready() {
|
||||
1),
|
||||
.shader_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(shader_data_t, {.name = "MyShader",
|
||||
ALLOC_INIT(shader_data_t, {.name = "MyShader",
|
||||
.contexts = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(shader_context_t,
|
||||
ALLOC_INIT(shader_context_t,
|
||||
{.name = "mesh",
|
||||
.vertex_shader = "mesh.vert",
|
||||
.fragment_shader = "mesh.frag",
|
||||
@@ -76,19 +75,19 @@ void ready() {
|
||||
.depth_write = true,
|
||||
.vertex_elements = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "pos", .data = "short4norm"}),
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "tex", .data = "short2norm"}),
|
||||
ALLOC_INIT(vertex_element_t, {.name = "pos", .data = "short4norm"}),
|
||||
ALLOC_INIT(vertex_element_t, {.name = "tex", .data = "short2norm"}),
|
||||
},
|
||||
2),
|
||||
.constants = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(shader_const_t,
|
||||
ALLOC_INIT(shader_const_t,
|
||||
{.name = "WVP", .type = "float4x4", .link = "_world_view_proj_matrix"}),
|
||||
},
|
||||
1),
|
||||
.texture_units = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(tex_unit_t, {.name = "my_texture"}),
|
||||
ALLOC_INIT(tex_unit_t, {.name = "my_texture"}),
|
||||
},
|
||||
1),
|
||||
.depth_attachment = "D32"}),
|
||||
@@ -98,7 +97,6 @@ void ready() {
|
||||
1)});
|
||||
|
||||
data_cached_scene_raws = any_map_create();
|
||||
gc_root(data_cached_scene_raws);
|
||||
any_map_set(data_cached_scene_raws, scene->name, scene);
|
||||
|
||||
// Instantiate scene
|
||||
@@ -108,7 +106,7 @@ void ready() {
|
||||
|
||||
void _kickstart() {
|
||||
iron_window_options_t *ops =
|
||||
GC_ALLOC_INIT(iron_window_options_t, {.title = "Empty",
|
||||
ALLOC_INIT(iron_window_options_t, {.title = "Empty",
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.x = -1,
|
||||
|
||||
@@ -45,41 +45,39 @@ void scene_ready() {
|
||||
}
|
||||
|
||||
void ready() {
|
||||
gc_unroot(render_path_commands);
|
||||
render_path_commands = render_commands;
|
||||
gc_root(render_path_commands);
|
||||
scene_t *scene = GC_ALLOC_INIT(
|
||||
scene_t *scene = ALLOC_INIT(
|
||||
scene_t,
|
||||
{.name = "Scene",
|
||||
.objects = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(
|
||||
ALLOC_INIT(
|
||||
obj_t, {.name = "Cube", .type = "mesh_object", .data_ref = "cube.arm/Cube", .material_ref = "MyMaterial", .visible = true, .spawn = true}),
|
||||
GC_ALLOC_INIT(
|
||||
ALLOC_INIT(
|
||||
obj_t,
|
||||
{.name = "Sphere", .type = "mesh_object", .data_ref = "sphere.arm/Sphere", .material_ref = "MyMaterial", .visible = true, .spawn = true}),
|
||||
GC_ALLOC_INIT(obj_t, {.name = "Camera", .type = "camera_object", .data_ref = "MyCamera", .visible = true, .spawn = true}),
|
||||
ALLOC_INIT(obj_t, {.name = "Camera", .type = "camera_object", .data_ref = "MyCamera", .visible = true, .spawn = true}),
|
||||
},
|
||||
3),
|
||||
.camera_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(camera_data_t, {.name = "MyCamera", .near_plane = 0.1, .far_plane = 100.0, .fov = 0.85}),
|
||||
ALLOC_INIT(camera_data_t, {.name = "MyCamera", .near_plane = 0.1, .far_plane = 100.0, .fov = 0.85}),
|
||||
},
|
||||
1),
|
||||
.camera_ref = "Camera",
|
||||
.world_ref = "MyWorld",
|
||||
.world_datas = any_array_create_from_raw((void *[]){GC_ALLOC_INIT(world_data_t, {.name = "MyWorld", .color = 0xff000000})}, 1),
|
||||
.world_datas = any_array_create_from_raw((void *[]){ALLOC_INIT(world_data_t, {.name = "MyWorld", .color = 0xff000000})}, 1),
|
||||
.material_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(material_data_t,
|
||||
ALLOC_INIT(material_data_t,
|
||||
{.name = "MyMaterial",
|
||||
.shader = "MyShader",
|
||||
.contexts = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(material_context_t, {.name = "mesh",
|
||||
ALLOC_INIT(material_context_t, {.name = "mesh",
|
||||
.bind_textures = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(bind_tex_t, {.name = "my_texture", .file = "texture.k"}),
|
||||
ALLOC_INIT(bind_tex_t, {.name = "my_texture", .file = "texture.k"}),
|
||||
},
|
||||
1)}),
|
||||
},
|
||||
@@ -88,12 +86,12 @@ void ready() {
|
||||
1),
|
||||
.shader_datas = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(
|
||||
ALLOC_INIT(
|
||||
shader_data_t,
|
||||
{.name = "MyShader",
|
||||
.contexts = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(shader_context_t,
|
||||
ALLOC_INIT(shader_context_t,
|
||||
{.name = "mesh",
|
||||
.vertex_shader = "mesh.vert",
|
||||
.fragment_shader = "mesh.frag",
|
||||
@@ -102,19 +100,19 @@ void ready() {
|
||||
.depth_write = true,
|
||||
.vertex_elements = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "pos", .data = "short4norm"}),
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "nor", .data = "short2norm"}),
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "tex", .data = "short2norm"}),
|
||||
ALLOC_INIT(vertex_element_t, {.name = "pos", .data = "short4norm"}),
|
||||
ALLOC_INIT(vertex_element_t, {.name = "nor", .data = "short2norm"}),
|
||||
ALLOC_INIT(vertex_element_t, {.name = "tex", .data = "short2norm"}),
|
||||
},
|
||||
3),
|
||||
.constants = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(shader_const_t, {.name = "WVP", .type = "float4x4", .link = "_world_view_proj_matrix"}),
|
||||
ALLOC_INIT(shader_const_t, {.name = "WVP", .type = "float4x4", .link = "_world_view_proj_matrix"}),
|
||||
},
|
||||
1),
|
||||
.texture_units = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(tex_unit_t, {.name = "my_texture"}),
|
||||
ALLOC_INIT(tex_unit_t, {.name = "my_texture"}),
|
||||
},
|
||||
1),
|
||||
.depth_attachment = "D32"}),
|
||||
@@ -124,7 +122,6 @@ void ready() {
|
||||
1)});
|
||||
|
||||
data_cached_scene_raws = any_map_create();
|
||||
gc_root(data_cached_scene_raws);
|
||||
any_map_set(data_cached_scene_raws, scene->name, scene);
|
||||
|
||||
// Instantiate scene
|
||||
@@ -134,7 +131,7 @@ void ready() {
|
||||
|
||||
void _kickstart() {
|
||||
iron_window_options_t *ops =
|
||||
GC_ALLOC_INIT(iron_window_options_t, {.title = "Empty",
|
||||
ALLOC_INIT(iron_window_options_t, {.title = "Empty",
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.x = -1,
|
||||
|
||||
@@ -18,7 +18,7 @@ void render() {
|
||||
|
||||
void _kickstart() {
|
||||
iron_window_options_t *ops =
|
||||
GC_ALLOC_INIT(iron_window_options_t, {.title = "Iron",
|
||||
ALLOC_INIT(iron_window_options_t, {.title = "Iron",
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.x = -1,
|
||||
@@ -31,9 +31,8 @@ void _kickstart() {
|
||||
_iron_init(ops);
|
||||
|
||||
pipeline = gpu_create_pipeline();
|
||||
gc_root(pipeline);
|
||||
|
||||
gpu_vertex_structure_t *vs = GC_ALLOC_INIT(gpu_vertex_structure_t, {0});
|
||||
gpu_vertex_structure_t *vs = ALLOC_INIT(gpu_vertex_structure_t, {0});
|
||||
gpu_vertex_structure_add(vs, "pos", GPU_VERTEX_DATA_F32_3X);
|
||||
buffer_t *vs_buffer = iron_load_blob(string("./data/test.vert%s", sys_shader_ext()));
|
||||
buffer_t *fs_buffer = iron_load_blob(string("./data/test.frag%s", sys_shader_ext()));
|
||||
@@ -68,7 +67,6 @@ void _kickstart() {
|
||||
3);
|
||||
|
||||
vb = gpu_create_vertex_buffer(vertices->length / (float)3, vs->elements);
|
||||
gc_root(vb);
|
||||
|
||||
float *vb_data = gpu_vertex_buffer_lock(vb);
|
||||
for (i32 i = 0; i < vertices->length; i++) {
|
||||
@@ -77,7 +75,6 @@ void _kickstart() {
|
||||
gpu_vertex_buffer_unlock(vb);
|
||||
|
||||
ib = gpu_create_index_buffer(indices->length);
|
||||
gc_root(ib);
|
||||
|
||||
uint32_t *ib_data = gpu_index_buffer_lock(ib);
|
||||
for (i32 i = 0; i < indices->length; i++) {
|
||||
|
||||
@@ -5,8 +5,6 @@ project.add_define('AMAKE');
|
||||
project.add_include_dir("../../sources");
|
||||
project.add_cfiles("../../sources/iron_string.c");
|
||||
project.add_cfiles("../../sources/iron_array.c");
|
||||
project.add_cfiles("../../sources/iron_gc.c");
|
||||
project.add_define("NO_GC");
|
||||
|
||||
project.add_cfiles("quickjs-amalgam.c");
|
||||
project.add_define("JS_DEFAULT_STACK_SIZE=8388608"); // 8 * 1024 * 1024
|
||||
|
||||
Reference in New Issue
Block a user