#include #include struct object_node { listnode_t node; object_t *object; }; scene_t * scene_new( void ) { scene_t *scene = calloc( 1, sizeof(scene_t) ); assert( scene != NULL ); scene->objects = list_new(); return scene; } void scene_free( scene_t *scene ) { assert( scene != NULL ); assert( scene->objects != NULL ); list_free( scene->objects ); free( scene ); } static int scene_cmp_object( const listnode_t *a, const listnode_t *b ) { assert( a != NULL ); assert( b != NULL ); struct object_node *i, *j; i = (struct object_node *)a; j = (struct object_node *)b; assert( i->object != NULL ); assert( j->object != NULL ); if ( i->object->depth < j->object->depth ) return -1; else if ( i->object->depth == j->object->depth ) return 0; else return 1; } static int scene_cmp_object_reverse( const listnode_t *a, const listnode_t *b ) { return -1 * scene_cmp_object( a, b ); } void scene_add_object( scene_t *scene, object_t *object ) { assert( scene != NULL ); assert( object != NULL ); struct object_node node; node.node.next = node.node.prev = NULL; node.object = object; list_insert_in_order( scene->objects, node, scene_cmp_object_reverse ); } void scene_render( scene_t *scene, surface_t *surface ) { assert( scene != NULL ); assert( surface != NULL ); struct object_node *node; for_each_list_element( scene->objects, node ) { object_draw( node->object, surface ); } } /** * Free every object from the scene, also clears it. */ void scene_free_objects( scene_t *scene ) { assert( scene != NULL ); struct object_node *node; for_each_list_element( scene->objects, node ) { object_free( node->object ); node->object = NULL; } scene_clear_objects( scene ); } /** * Remove every object from scene. */ void scene_clear_objects( scene_t *scene ) { assert( scene != NULL ); list_clear( scene->objects ); }