diff options
author | Tavian Barnes <tavianator@gmail.com> | 2010-05-08 23:21:48 -0600 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2010-05-08 23:21:48 -0600 |
commit | 7a21db5914dd7a5666e603d66ed3948b659ba2fc (patch) | |
tree | bde8e00a1677ba865adae8a82780d1cc832ece8e | |
parent | 152362a57dc7fe9dce830ef69118984f854d6375 (diff) | |
download | dimension-7a21db5914dd7a5666e603d66ed3948b659ba2fc.tar.xz |
New DMNSN_ARRAY_FOREACH() macro, faster than iterating with dmnsn_array_get().
-rw-r--r-- | dimension/common.rules | 16 | ||||
-rw-r--r-- | dimension/lexer.l | 17 | ||||
-rw-r--r-- | dimension/parse.c | 48 | ||||
-rw-r--r-- | dimension/realize.c | 199 | ||||
-rw-r--r-- | dimension/tokenize.c | 6 | ||||
-rw-r--r-- | libdimension/canvas.c | 15 | ||||
-rw-r--r-- | libdimension/dimension/array.h | 22 | ||||
-rw-r--r-- | libdimension/gl.c | 15 | ||||
-rw-r--r-- | libdimension/png.c | 12 | ||||
-rw-r--r-- | libdimension/prtree.c | 13 | ||||
-rw-r--r-- | libdimension/raytrace.c | 10 | ||||
-rw-r--r-- | libdimension/scene.c | 14 |
12 files changed, 169 insertions, 218 deletions
diff --git a/dimension/common.rules b/dimension/common.rules index 4644627..d897eb3 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -152,11 +152,9 @@ OBJECT: FINITE_SOLID_OBJECT *modifiers = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @4); dmnsn_copy_children(*modifiers, orig_modifiers); - for (size_t i = 0; i < dmnsn_array_size($4.children); ++i) { - dmnsn_astnode astnode; - dmnsn_array_get($4.children, i, &astnode); - ++*astnode.refcount; - dmnsn_array_push(modifiers->children, &astnode); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { + ++*astnode->refcount; + dmnsn_array_push(modifiers->children, astnode); } dmnsn_delete_astnode($4); break; @@ -185,11 +183,9 @@ OBJECT: FINITE_SOLID_OBJECT dmnsn_array_size($$.children) - 1, &modifiers); - for (size_t i = 0; i < dmnsn_array_size($4.children); ++i) { - dmnsn_astnode astnode; - dmnsn_array_get($4.children, i, &astnode); - ++*astnode.refcount; - dmnsn_array_push(modifiers.children, &astnode); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { + ++*astnode->refcount; + dmnsn_array_push(modifiers.children, astnode); } dmnsn_delete_astnode($4); diff --git a/dimension/lexer.l b/dimension/lexer.l index 6198fea..a3dc683 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -421,10 +421,8 @@ dmnsn_delete_token(dmnsn_token token) void dmnsn_delete_tokens(dmnsn_array *tokens) { - dmnsn_token token; - for (size_t i = 0; i < dmnsn_array_size(tokens); ++i) { - dmnsn_array_get(tokens, i, &token); - dmnsn_delete_token(token); + DMNSN_ARRAY_FOREACH (dmnsn_token *, token, tokens) { + dmnsn_delete_token(*token); } dmnsn_delete_array(tokens); } @@ -453,19 +451,16 @@ dmnsn_print_token(FILE *file, dmnsn_token token) void dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens) { - dmnsn_token token; - if (dmnsn_array_size(tokens) == 0) { fprintf(file, "()"); } else { fprintf(file, "("); - dmnsn_array_get(tokens, 0, &token); - dmnsn_print_token(file, token); + dmnsn_token *token = dmnsn_array_first(tokens); + dmnsn_print_token(file, *token); - for (size_t i = 1; i < dmnsn_array_size(tokens); ++i) { + for (++token; token <= (dmnsn_token *)dmnsn_array_last(tokens); ++token) { fprintf(file, " "); - dmnsn_array_get(tokens, i, &token); - dmnsn_print_token(file, token); + dmnsn_print_token(file, *token); } fprintf(file, ")"); diff --git a/dimension/parse.c b/dimension/parse.c index 54b5880..efb208f 100644 --- a/dimension/parse.c +++ b/dimension/parse.c @@ -288,10 +288,8 @@ dmnsn_declare_symbol(dmnsn_symbol_table *symtable, void dmnsn_undef_symbol(dmnsn_symbol_table *symtable, const char *id) { - for (size_t i = 0; i < dmnsn_array_size(symtable); ++i) { - dmnsn_patricia_trie *trie; - dmnsn_array_get(symtable, dmnsn_array_size(symtable) - i - 1, &trie); - if (dmnsn_patricia_remove(trie, id)) + DMNSN_ARRAY_FOREACH (dmnsn_patricia_trie **, trie, symtable) { + if (dmnsn_patricia_remove(*trie, id)) break; } } @@ -301,11 +299,11 @@ dmnsn_find_symbol(dmnsn_symbol_table *symtable, const char *id) { dmnsn_astnode *symbol = NULL; - for (size_t i = 0; i < dmnsn_array_size(symtable); ++i) { - dmnsn_patricia_trie *trie; - dmnsn_array_get(symtable, dmnsn_array_size(symtable) - i - 1, &trie); - - symbol = dmnsn_patricia_find(trie, id); + for (dmnsn_patricia_trie **trie = dmnsn_array_last(symtable); + trie >= (dmnsn_patricia_trie **)dmnsn_array_first(symtable); + --trie) + { + symbol = dmnsn_patricia_find(*trie, id); if (symbol) break; } @@ -469,10 +467,8 @@ void dmnsn_delete_astree(dmnsn_astree *astree) { if (astree) { - for (size_t i = 0; i < dmnsn_array_size(astree); ++i) { - dmnsn_astnode node; - dmnsn_array_get(astree, i, &node); - dmnsn_delete_astnode(node); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, node, astree) { + dmnsn_delete_astnode(*node); } dmnsn_delete_array(astree); } @@ -514,9 +510,8 @@ dmnsn_vector_promote(dmnsn_astnode astnode, dmnsn_symbol_table *symtable) if (astnode.type == DMNSN_AST_VECTOR) { dmnsn_astnode component; - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_array_get(astnode.children, i, &component); - component = dmnsn_eval_scalar(component, symtable); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, i, astnode.children) { + component = dmnsn_eval_scalar(*i, symtable); if (component.type == DMNSN_AST_NONE) { dmnsn_delete_astnode(promoted); @@ -1773,15 +1768,12 @@ dmnsn_print_astnode(FILE *file, dmnsn_astnode astnode) static void dmnsn_print_astree(FILE *file, dmnsn_astnode astnode) { - dmnsn_astnode child; - if (astnode.children && dmnsn_array_size(astnode.children) > 0) { fprintf(file, "("); dmnsn_print_astnode(file, astnode); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_array_get(astnode.children, i, &child); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, child, astnode.children) { fprintf(file, " "); - dmnsn_print_astree(file, child); + dmnsn_print_astree(file, *child); } fprintf(file, ")"); } else { @@ -1792,19 +1784,19 @@ dmnsn_print_astree(FILE *file, dmnsn_astnode astnode) void dmnsn_print_astree_sexpr(FILE *file, const dmnsn_astree *astree) { - dmnsn_astnode astnode; - if (dmnsn_array_size(astree) == 0) { fprintf(file, "()"); } else { fprintf(file, "("); - dmnsn_array_get(astree, 0, &astnode); - dmnsn_print_astree(file, astnode); + dmnsn_astnode *astnode = dmnsn_array_first(astree); + dmnsn_print_astree(file, *astnode); - for (size_t i = 1; i < dmnsn_array_size(astree); ++i) { + for (++astnode; + astnode <= (dmnsn_astnode *)dmnsn_array_last(astree); + ++astnode) + { fprintf(file, " "); - dmnsn_array_get(astree, i, &astnode); - dmnsn_print_astree(file, astnode); + dmnsn_print_astree(file, *astnode); } fprintf(file, ")"); diff --git a/dimension/realize.c b/dimension/realize.c index 05eae07..ec0819f 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -190,17 +190,16 @@ dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene) dmnsn_assert(astnode.type == DMNSN_AST_GLOBAL_SETTINGS, "Expected global settings."); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode item, child; - dmnsn_array_get(astnode.children, i, &item); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + dmnsn_astnode child; - switch (item.type) { + switch (item->type) { case DMNSN_AST_ASSUMED_GAMMA: /* assumed_gamma not supported */ break; case DMNSN_AST_MAX_TRACE_LEVEL: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); scene->reclimit = dmnsn_realize_integer(child); break; @@ -227,44 +226,43 @@ dmnsn_realize_camera(dmnsn_astnode astnode) dmnsn_camera *camera = NULL; - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode item; - dmnsn_array_get(astnode.children, i, &item); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + dmnsn_astnode child; - switch (item.type) { + switch (item->type) { /* Camera types */ case DMNSN_AST_PERSPECTIVE: - camera_type = item.type; + camera_type = item->type; break; /* Camera vectors */ case DMNSN_AST_LOCATION: - dmnsn_array_get(item.children, 0, &item); - location = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + location = dmnsn_realize_vector(child); break; case DMNSN_AST_RIGHT: - dmnsn_array_get(item.children, 0, &item); - right = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + right = dmnsn_realize_vector(child); break; case DMNSN_AST_UP: - dmnsn_array_get(item.children, 0, &item); - right = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + right = dmnsn_realize_vector(child); break; case DMNSN_AST_SKY: - dmnsn_array_get(item.children, 0, &item); - sky = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + sky = dmnsn_realize_vector(child); break; case DMNSN_AST_DIRECTION: - dmnsn_array_get(item.children, 0, &item); - direction = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + direction = dmnsn_realize_vector(child); break; /* Camera modifiers */ case DMNSN_AST_LOOK_AT: { - dmnsn_array_get(item.children, 0, &item); - dmnsn_vector look_at = dmnsn_realize_vector(item); + dmnsn_array_get(item->children, 0, &child); + dmnsn_vector look_at = dmnsn_realize_vector(child); /* Line the camera up with the sky */ @@ -312,8 +310,8 @@ dmnsn_realize_camera(dmnsn_astnode astnode) case DMNSN_AST_ANGLE: { - dmnsn_array_get(item.children, 0, &item); - double angle = deg2rad*dmnsn_realize_float(item); + dmnsn_array_get(item->children, 0, &child); + double angle = deg2rad*dmnsn_realize_float(child); direction = dmnsn_vector_mul( 0.5*dmnsn_vector_norm(right)/tan(angle/2.0), dmnsn_vector_normalize(direction) @@ -325,7 +323,7 @@ dmnsn_realize_camera(dmnsn_astnode astnode) case DMNSN_AST_ROTATION: case DMNSN_AST_SCALE: case DMNSN_AST_TRANSLATION: - trans = dmnsn_matrix_mul(dmnsn_realize_transformation(item), trans); + trans = dmnsn_matrix_mul(dmnsn_realize_transformation(*item), trans); break; default: @@ -408,16 +406,13 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment) dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MODIFIERS, "Expected pigment modifiers."); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode modifier; - dmnsn_array_get(astnode.children, i, &modifier); - - switch (modifier.type) { + DMNSN_ARRAY_FOREACH(dmnsn_astnode *, modifier, astnode.children) { + switch (modifier->type) { case DMNSN_AST_ROTATION: case DMNSN_AST_SCALE: case DMNSN_AST_TRANSLATION: pigment->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(modifier), + dmnsn_realize_transformation(*modifier), pigment->trans ); break; @@ -507,13 +502,12 @@ dmnsn_realize_reflection(dmnsn_astnode astnode) dmnsn_astnode items; dmnsn_array_get(astnode.children, 2, &items); - for (size_t i = 0; i < dmnsn_array_size(items.children); ++i) { - dmnsn_astnode item, child; - dmnsn_array_get(items.children, i, &item); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, items.children) { + dmnsn_astnode child; - switch (item.type) { + switch (item->type) { case DMNSN_AST_FALLOFF: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); falloff = dmnsn_realize_float(child); break; @@ -545,35 +539,34 @@ dmnsn_realize_finish(dmnsn_astnode astnode) dmnsn_finish *reflection = NULL; - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode item, child; - dmnsn_array_get(astnode.children, i, &item); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + dmnsn_astnode child; - switch (item.type) { + switch (item->type) { case DMNSN_AST_AMBIENT: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); ambient = dmnsn_realize_color(child); ambient_set = true; break; case DMNSN_AST_DIFFUSE: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); diffuse = dmnsn_realize_float(child); diffuse_set = true; break; case DMNSN_AST_PHONG: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); phong = dmnsn_realize_float(child); break; case DMNSN_AST_PHONG_SIZE: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); phong_size = dmnsn_realize_float(child); break; case DMNSN_AST_REFLECTION: dmnsn_delete_finish(reflection); - reflection = dmnsn_realize_reflection(item); + reflection = dmnsn_realize_reflection(*item); break; default: @@ -616,26 +609,25 @@ dmnsn_realize_texture(dmnsn_astnode astnode) dmnsn_texture *texture = dmnsn_new_texture(); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode item; - dmnsn_array_get(astnode.children, i, &item); - - switch (item.type) { + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + switch (item->type) { case DMNSN_AST_PIGMENT: dmnsn_delete_pigment(texture->pigment); - texture->pigment = dmnsn_realize_pigment(item); + texture->pigment = dmnsn_realize_pigment(*item); break; case DMNSN_AST_FINISH: dmnsn_delete_finish(texture->finish); - texture->finish = dmnsn_realize_finish(item); + texture->finish = dmnsn_realize_finish(*item); break; case DMNSN_AST_ROTATION: case DMNSN_AST_SCALE: case DMNSN_AST_TRANSLATION: - texture->trans = dmnsn_matrix_mul(dmnsn_realize_transformation(item), - texture->trans); + texture->trans = dmnsn_matrix_mul( + dmnsn_realize_transformation(*item), + texture->trans + ); break; default: @@ -653,13 +645,12 @@ dmnsn_realize_interior(dmnsn_astnode astnode) dmnsn_interior *interior = dmnsn_new_interior(); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode item, child; - dmnsn_array_get(astnode.children, i, &item); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + dmnsn_astnode child; - switch (item.type) { + switch (item->type) { case DMNSN_AST_IOR: - dmnsn_array_get(item.children, 0, &child); + dmnsn_array_get(item->children, 0, &child); interior->ior = dmnsn_realize_float(child); break; @@ -680,40 +671,37 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object) /* Save the pre-existing transformations */ dmnsn_matrix existing_trans = dmnsn_matrix_inverse(object->trans); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode modifier; - dmnsn_array_get(astnode.children, i, &modifier); - - switch (modifier.type) { + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { + switch (modifier->type) { case DMNSN_AST_ROTATION: case DMNSN_AST_SCALE: case DMNSN_AST_TRANSLATION: object->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(modifier), + dmnsn_realize_transformation(*modifier), object->trans ); break; case DMNSN_AST_TEXTURE: dmnsn_delete_texture(object->texture); - object->texture = dmnsn_realize_texture(modifier); + object->texture = dmnsn_realize_texture(*modifier); break; case DMNSN_AST_PIGMENT: if (!object->texture) object->texture = dmnsn_new_texture(); dmnsn_delete_pigment(object->texture->pigment); - object->texture->pigment = dmnsn_realize_pigment(modifier); + object->texture->pigment = dmnsn_realize_pigment(*modifier); break; case DMNSN_AST_FINISH: if (!object->texture) object->texture = dmnsn_new_texture(); dmnsn_delete_finish(object->texture->finish); - object->texture->finish = dmnsn_realize_finish(modifier); + object->texture->finish = dmnsn_realize_finish(*modifier); break; case DMNSN_AST_INTERIOR: dmnsn_delete_interior(object->interior); - object->interior = dmnsn_realize_interior(modifier); + object->interior = dmnsn_realize_interior(*modifier); break; default: @@ -738,26 +726,13 @@ dmnsn_realize_light_source_modifiers(dmnsn_astnode astnode, dmnsn_light *light) dmnsn_assert(astnode.type == DMNSN_AST_OBJECT_MODIFIERS, "Expected object modifiers."); - for (size_t i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_astnode modifier; - dmnsn_array_get(astnode.children, i, &modifier); - - switch (modifier.type) { + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { + switch (modifier->type) { case DMNSN_AST_ROTATION: - light->x0 = dmnsn_transform_vector( - dmnsn_realize_rotation(modifier), - light->x0 - ); - break; case DMNSN_AST_SCALE: - light->x0 = dmnsn_transform_vector( - dmnsn_realize_scale(modifier), - light->x0 - ); - break; case DMNSN_AST_TRANSLATION: light->x0 = dmnsn_transform_vector( - dmnsn_realize_translation(modifier), + dmnsn_realize_transformation(*modifier), light->x0 ); break; @@ -890,31 +865,32 @@ dmnsn_realize_csg(dmnsn_astnode astnode, dmnsn_array *lights, dmnsn_array_get(astnode.children, 0, &objects); dmnsn_array_get(astnode.children, 1, &modifiers); - size_t i; dmnsn_object *csg = NULL; - for (i = 0; i < dmnsn_array_size(objects.children) && !csg; ++i) { - dmnsn_astnode onode; - dmnsn_array_get(objects.children, i, &onode); - - if (onode.type == DMNSN_AST_LIGHT_SOURCE) { - dmnsn_light *light = dmnsn_realize_light_source(onode); + dmnsn_astnode *onode; + for (onode = dmnsn_array_first(objects.children); + onode <= (dmnsn_astnode *)dmnsn_array_last(objects.children); + ++onode) + { + if (onode->type == DMNSN_AST_LIGHT_SOURCE) { + dmnsn_light *light = dmnsn_realize_light_source(*onode); dmnsn_realize_light_source_modifiers(modifiers, light); dmnsn_array_push(lights, &light); } else { - csg = dmnsn_realize_object(onode, lights); + csg = dmnsn_realize_object(*onode, lights); + break; } } - for (; i < dmnsn_array_size(objects.children); ++i) { - dmnsn_astnode onode; - dmnsn_array_get(objects.children, i, &onode); - - if (onode.type == DMNSN_AST_LIGHT_SOURCE) { - dmnsn_light *light = dmnsn_realize_light_source(onode); + for (++onode; + onode <= (dmnsn_astnode *)dmnsn_array_last(objects.children); + ++onode) + { + if (onode->type == DMNSN_AST_LIGHT_SOURCE) { + dmnsn_light *light = dmnsn_realize_light_source(*onode); dmnsn_realize_light_source_modifiers(modifiers, light); dmnsn_array_push(lights, &light); } else { - dmnsn_object *object = dmnsn_realize_object(onode, lights); + dmnsn_object *object = dmnsn_realize_object(*onode, lights); csg = (*csg_object_fn)(csg, object); } } @@ -1009,25 +985,24 @@ dmnsn_realize_astree(const dmnsn_astree *astree) * Now parse the abstract syntax tree */ - dmnsn_astnode astnode; - for (size_t i = 0; i < dmnsn_array_size(astree); ++i) { - dmnsn_array_get(astree, i, &astnode); - - dmnsn_light *light; + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, astree) { + dmnsn_astnode child; + dmnsn_light *light; dmnsn_object *object; - switch (astnode.type) { + + switch (astnode->type) { case DMNSN_AST_GLOBAL_SETTINGS: - dmnsn_realize_global_settings(astnode, scene); + dmnsn_realize_global_settings(*astnode, scene); break; case DMNSN_AST_BACKGROUND: - dmnsn_array_get(astnode.children, 0, &astnode); - scene->background = dmnsn_realize_color(astnode); + dmnsn_array_get(astnode->children, 0, &child); + scene->background = dmnsn_realize_color(child); break; case DMNSN_AST_CAMERA: dmnsn_delete_camera(scene->camera); - scene->camera = dmnsn_realize_camera(astnode); + scene->camera = dmnsn_realize_camera(*astnode); break; case DMNSN_AST_BOX: @@ -1037,13 +1012,13 @@ dmnsn_realize_astree(const dmnsn_astree *astree) case DMNSN_AST_PLANE: case DMNSN_AST_SPHERE: case DMNSN_AST_UNION: - object = dmnsn_realize_object(astnode, scene->lights); + object = dmnsn_realize_object(*astnode, scene->lights); if (object) dmnsn_array_push(scene->objects, &object); break; case DMNSN_AST_LIGHT_SOURCE: - light = dmnsn_realize_light_source(astnode); + light = dmnsn_realize_light_source(*astnode); dmnsn_array_push(scene->lights, &light); break; diff --git a/dimension/tokenize.c b/dimension/tokenize.c index efa1064..98253ce 100644 --- a/dimension/tokenize.c +++ b/dimension/tokenize.c @@ -67,10 +67,8 @@ dmnsn_delete_token_buffer(void *ptr) { dmnsn_token_buffer *tbuffer = ptr; if (tbuffer) { - for (size_t i = 0; i < dmnsn_array_size(tbuffer->buffered); ++i) { - dmnsn_buffered_token buffered; - dmnsn_array_get(tbuffer->buffered, i, &buffered); - free(buffered.lval.value); + DMNSN_ARRAY_FOREACH (dmnsn_buffered_token *, buffered, tbuffer->buffered) { + free(buffered->lval.value); } dmnsn_delete_array(tbuffer->buffered); diff --git a/libdimension/canvas.c b/libdimension/canvas.c index 4ed7fd5..2c60c60 100644 --- a/libdimension/canvas.c +++ b/libdimension/canvas.c @@ -48,11 +48,9 @@ dmnsn_delete_canvas(dmnsn_canvas *canvas) { if (canvas) { /* Free the optimizers */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_canvas_optimizer optimizer; - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.free_fn) { - (*optimizer.free_fn)(optimizer.ptr); + DMNSN_ARRAY_FOREACH(dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->free_fn) { + (*i->free_fn)(i->ptr); } } dmnsn_delete_array(canvas->optimizers); @@ -75,15 +73,12 @@ void dmnsn_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y, dmnsn_color color) { - dmnsn_canvas_optimizer optimizer; - /* Set the pixel */ canvas->pixels[y*canvas->x + x] = color; /* Call the optimizers */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - (*optimizer.optimizer_fn)(canvas, optimizer, x, y); + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + (*i->optimizer_fn)(canvas, *i, x, y); } } diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index e3dc7b4..afd5e16 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -100,7 +100,21 @@ dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj) memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); } -/* Element access */ +/* First element */ +DMNSN_INLINE void * +dmnsn_array_first(const dmnsn_array *array) +{ + return array->ptr; +} + +/* Last element */ +DMNSN_INLINE void * +dmnsn_array_last(const dmnsn_array *array) +{ + return (char *)array->ptr + array->obj_size*(array->length - 1); +} + +/* Arbitrary element access */ DMNSN_INLINE void * dmnsn_array_at(const dmnsn_array *array, size_t i) { @@ -156,4 +170,10 @@ dmnsn_array_remove(dmnsn_array *array, size_t i) dmnsn_array_resize(array, size - 1); } +/* Macro to shorten array iteration */ +#define DMNSN_ARRAY_FOREACH(type, i, array) \ + for (type i = dmnsn_array_first(array); \ + i <= (type)dmnsn_array_last(array); \ + ++i) + #endif /* DIMENSION_ARRAY_H */ diff --git a/libdimension/gl.c b/libdimension/gl.c index 84dcc91..d07465f 100644 --- a/libdimension/gl.c +++ b/libdimension/gl.c @@ -32,16 +32,14 @@ static void dmnsn_gl_optimizer_fn(dmnsn_canvas *canvas, int dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas) { - dmnsn_canvas_optimizer optimizer; - /* Check if we've already optimized this canvas */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) { return 0; } } + dmnsn_canvas_optimizer optimizer; optimizer.optimizer_fn = &dmnsn_gl_optimizer_fn; optimizer.free_fn = &free; @@ -67,10 +65,9 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas) size_t height = canvas->y; /* Check if we can optimize this */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) { - glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, optimizer.ptr); + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) { + glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, i->ptr); return glGetError() == GL_NO_ERROR ? 0 : 1; } } diff --git a/libdimension/png.c b/libdimension/png.c index 021b9f2..177293c 100644 --- a/libdimension/png.c +++ b/libdimension/png.c @@ -39,9 +39,8 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas) dmnsn_canvas_optimizer optimizer; /* Check if we've already optimized this canvas */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_png_optimizer_fn) { return 0; } } @@ -287,12 +286,11 @@ dmnsn_png_write_canvas_impl(dmnsn_progress *progress, } /* Check if we can optimize this */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_png_optimizer_fn) { for (size_t y = 0; y < height; ++y) { /* Invert the rows. PNG coordinates are fourth quadrant. */ - uint16_t *row = (uint16_t *)optimizer.ptr + 4*(height - y - 1)*width; + uint16_t *row = (uint16_t *)i->ptr + 4*(height - y - 1)*width; png_write_row(png_ptr, (png_bytep)row); dmnsn_increment_progress(progress); } diff --git a/libdimension/prtree.c b/libdimension/prtree.c index 04d8cc4..dc3ed38 100644 --- a/libdimension/prtree.c +++ b/libdimension/prtree.c @@ -430,10 +430,8 @@ dmnsn_pseudo_prtree_leaves(const dmnsn_pseudo_prtree *pseudo) static void dmnsn_precompute_objects(const dmnsn_array *objects) { - for (size_t i = 0; i < dmnsn_array_size(objects); ++i) { - dmnsn_object *object; - dmnsn_array_get(objects, i, &object); - dmnsn_object_precompute(object); + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) { + dmnsn_object_precompute(*object); } } @@ -555,12 +553,9 @@ dmnsn_prtree_search(const dmnsn_prtree *tree, dmnsn_line ray, double t = -1.0; /* Search the unbounded objects */ - for (size_t i = 0; i < dmnsn_array_size(tree->unbounded); ++i) { - dmnsn_object *object; - dmnsn_array_get(tree->unbounded, i, &object); - + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, tree->unbounded) { dmnsn_intersection local_intersection; - if ((*object->intersection_fn)(object, ray, &local_intersection)) { + if ((*(*object)->intersection_fn)(*object, ray, &local_intersection)) { if (t < 0.0 || local_intersection.t < t) { *intersection = local_intersection; t = local_intersection.t; diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index f5d0885..0c3b738 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -315,17 +315,13 @@ dmnsn_raytrace_lighting(dmnsn_raytrace_state *state) return; } - const dmnsn_light *light; - /* Iterate over each light */ - for (size_t i = 0; i < dmnsn_array_size(state->scene->lights); ++i) { - dmnsn_array_get(state->scene->lights, i, &light); - - dmnsn_color light_color = dmnsn_raytrace_light_ray(state, light); + DMNSN_ARRAY_FOREACH (dmnsn_light **, light, state->scene->lights) { + dmnsn_color light_color = dmnsn_raytrace_light_ray(state, *light); if (!dmnsn_color_is_black(light_color)) { if (state->scene->quality & DMNSN_RENDER_FINISH) { dmnsn_vector ray = dmnsn_vector_normalize( - dmnsn_vector_sub(light->x0, state->r) + dmnsn_vector_sub((*light)->x0, state->r) ); /* Get this light's color contribution to the object */ diff --git a/libdimension/scene.c b/libdimension/scene.c index 177e7fe..58d2eda 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -50,17 +50,11 @@ void dmnsn_delete_scene(dmnsn_scene *scene) { if (scene) { - dmnsn_light *light; - dmnsn_object *object; - - for (size_t i = 0; i < dmnsn_array_size(scene->lights); ++i) { - dmnsn_array_get(scene->lights, i, &light); - dmnsn_delete_light(light); + DMNSN_ARRAY_FOREACH (dmnsn_light **, light, scene->lights) { + dmnsn_delete_light(*light); } - - for (size_t i = 0; i < dmnsn_array_size(scene->objects); ++i) { - dmnsn_array_get(scene->objects, i, &object); - dmnsn_delete_object(object); + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, scene->objects) { + dmnsn_delete_object(*object); } dmnsn_delete_array(scene->lights); |