base: merge gc remove

This commit is contained in:
luboslenco
2026-08-21 22:35:30 +02:00
parent 2d394ca334
commit 4c77755da0
37 changed files with 635 additions and 965 deletions
-23
View File
@@ -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
-1
View File
@@ -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/*");
+1 -2
View File
@@ -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) {
+4 -1
View File
@@ -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
View File
@@ -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,18 +2584,14 @@ 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) {
// Full-screen triangle
@@ -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 -1
View File
@@ -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
View File
@@ -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;
}
+10
View File
@@ -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))
+4 -5
View File
@@ -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
View File
@@ -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;
+4 -1
View File
@@ -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);
+13 -7
View File
@@ -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;
+6 -11
View File
@@ -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);
}
-448
View File
@@ -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
-21
View File
@@ -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();
+3 -21
View File
@@ -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
View File
@@ -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;
+5 -3
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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();
+3 -2
View File
@@ -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;
+7 -6
View File
@@ -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
View File
@@ -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;
}
char *ext_underscore_mid = string("_%s_", ext);
if (string_index_of(p, ext_underscore_mid) >= 0 && !ends_with(p, "_preview") && !ends_with(p, "_icon")) {
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;
}
}
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);
}
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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
View File
@@ -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;
}
+7
View File
@@ -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
View File
@@ -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();
+2 -5
View File
@@ -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
View File
@@ -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;
+4 -4
View File
@@ -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;
}
+4 -12
View File
@@ -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(&copy_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;
}
+4 -22
View File
@@ -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);
}
}
+15 -17
View File
@@ -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,
+17 -20
View File
@@ -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,
+2 -5
View File
@@ -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++) {
-2
View File
@@ -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