d_define_method(map, insert)(struct s_object *self, struct s_object *key, struct s_object *value) { d_using(map); struct s_hash_bucket previous_content; struct s_object *retained_key = d_retain(key), *retained_value = d_retain(value); if (f_hash_insert(map_attributes->hash, (void *)retained_key, (void *)retained_value, d_true, &previous_content)) { /* if the value already exists, hash table keeps the previous key */ d_delete(retained_key); d_delete((struct s_object *)previous_content.value); } return self; }
d_define_method(illuminable_bitmap, set_lights)(struct s_object *self, struct s_object *lights) { d_using(illuminable_bitmap); if (illuminable_bitmap_attributes->lights) d_delete(illuminable_bitmap_attributes->lights); illuminable_bitmap_attributes->lights = d_retain(lights); return self; }
struct s_object *f_stream_new_file(struct s_object *self, struct s_object *string_name, const char *action, int permission) { struct s_stream_attributes *attributes = p_stream_alloc(self); char buffer[d_string_buffer_size]; attributes->string_name = d_retain(string_name); attributes->parameters = -1; switch(action[0]) { case 'r': case 'R': attributes->parameters = d_stream_flag_read; if ((action[1] == 'w') || (action[1] == 'W')) attributes->parameters = d_stream_flag_write_read; break; case 'w': case 'W': attributes->parameters = d_stream_flag_truncate; if ((action[1] == 'a') || (action[1] == 'A')) attributes->parameters = d_stream_flag_append; } if (attributes->parameters != -1) { if ((attributes->descriptor = open(d_string_cstring(attributes->string_name), attributes->parameters, permission)) > -1) attributes->flags = e_stream_flag_opened; else { snprintf(buffer, d_string_buffer_size, "unreachable file %s exception", d_string_cstring(attributes->string_name)); d_throw(v_exception_unreachable, buffer); } } else d_throw(v_exception_malformed, "malformed action format"); return self; }
struct s_object *f_stream_new(struct s_object *self, struct s_object *string_name, int descriptor) { struct s_stream_attributes *attributes = p_stream_alloc(self); attributes->string_name = d_retain(string_name); attributes->descriptor = descriptor; attributes->parameters = fcntl(attributes->descriptor, F_GETFL); attributes->flags = (e_stream_flag_supplied|e_stream_flag_opened); return self; }
struct s_object * f_particle_new(struct s_object *self, struct s_object *drawable_particle, struct s_object *environment, struct s_particle_configuration *configuration) { struct s_particle_attributes *attributes = p_particle_alloc(self); attributes->drawable_core = d_retain(drawable_particle); memcpy(&(attributes->configuration), configuration, sizeof(struct s_particle_configuration)); memset(&(attributes->particles), 0, (sizeof(struct s_particle_information) * d_particle_cores)); d_call(attributes->drawable_core, m_drawable_set_blend, attributes->configuration.blend); attributes->single_shoot = attributes->configuration.single_shoot; attributes->initialized = d_false; return self; }
d_define_method(uiable, set)(struct s_object *self, struct s_object *drawable, enum e_uiable_components component) { d_using(uiable); if (uiable_attributes->background[component]) d_delete(uiable_attributes->background[component]); uiable_attributes->background[component] = d_retain(drawable); if (uiable_attributes->last_blend != e_drawable_blend_undefined) d_call(uiable_attributes->background[component], m_drawable_set_blend, uiable_attributes->last_blend); d_call(uiable_attributes->background[component], m_drawable_set_maskRGB, (unsigned int)uiable_attributes->last_mask_R, (unsigned int)uiable_attributes->last_mask_G, (unsigned int)uiable_attributes->last_mask_B); d_call(uiable_attributes->background[component], m_drawable_set_maskA, (unsigned int)uiable_attributes->last_mask_A); return self; }
d_define_method(container, add_drawable)(struct s_object *self, struct s_object *drawable, double position_x, double position_y) { d_using(container); struct s_container_drawable *current_container; if ((current_container = (struct s_container_drawable *)d_malloc(sizeof(struct s_container_drawable)))) { current_container->drawable = d_retain(drawable); current_container->position_x = position_x; current_container->position_y = position_y; f_list_append(&(container_attributes->entries), (struct s_list_node *)current_container, e_list_insert_tail); } else d_die(d_error_malloc); return self; }
d_define_method(illuminable_bitmap, set_light_mask)(struct s_object *self, struct s_object *drawable_mask, enum e_illuminable_bitmap_sides side) { d_using(illuminable_bitmap); double mask_width, mask_height, image_width, image_height; if (illuminable_bitmap_attributes->drawable_mask[side]) d_delete(illuminable_bitmap_attributes->drawable_mask[side]); illuminable_bitmap_attributes->drawable_mask[side] = d_retain(drawable_mask); d_call(illuminable_bitmap_attributes->drawable_mask[side], m_drawable_set_blend, e_drawable_blend_add); d_call(illuminable_bitmap_attributes->drawable_mask[side], m_drawable_get_dimension, &mask_width, &mask_height); d_call(self, m_drawable_get_dimension, &image_width, &image_height); d_assert((image_width == mask_width)); d_assert((image_height == mask_height)); return self; }
struct s_object *f_stream_new_temporary(struct s_object *self, struct s_object *string_name) { struct s_stream_attributes *attributes = p_stream_alloc(self); char file_name[] = "magrathea_XXXXXX.tmp"; attributes->string_name = d_retain(string_name); attributes->parameters = d_stream_flag_write_read; /* (from man): [...] the last six characters of template must be "XXXXXX" and these are replaced with a string that makes the filename unique. * Since it will be modified, template must not be a string constant, but should be declared as a character array. */ if ((attributes->descriptor = mkstemp(file_name)) >= 0) attributes->flags = (e_stream_flag_temporary|e_stream_flag_opened); else d_throw(v_exception_unreachable, "unreachable temporary file exception"); return self; }
d_define_method(label, set_content)(struct s_object *self, struct s_object *string_content, TTF_Font *font, struct s_object *environment) { d_using(label); struct s_drawable_attributes *drawable_attributes = d_cast(self, drawable); struct s_environment_attributes *environment_attributes = d_cast(environment, environment); char buffer[d_string_buffer_size]; int width, height; SDL_Surface *unoptimized_surface; SDL_Color white = { 255, 255, 255, 255 }; if (label_attributes->string_content) d_delete(label_attributes->string_content); label_attributes->string_content = d_retain(string_content); if (label_attributes->image) SDL_DestroyTexture(label_attributes->image); if ((unoptimized_surface = TTF_RenderText_Blended(font, d_string_cstring(string_content), white))) { label_attributes->image = SDL_CreateTextureFromSurface(environment_attributes->renderer, unoptimized_surface); if (SDL_QueryTexture(label_attributes->image, NULL, NULL, &width, &height) == 0) { d_call(&(drawable_attributes->point_dimension), m_point_set_x, (double)width); d_call(&(drawable_attributes->point_dimension), m_point_set_y, (double)height); d_call(&(drawable_attributes->point_center), m_point_set_x, (double)(width/2.0)); d_call(&(drawable_attributes->point_center), m_point_set_y, (double)(height/2.0)); if (label_attributes->last_blend != e_drawable_blend_undefined) d_call(self, m_drawable_set_blend, label_attributes->last_blend); d_call(self, m_drawable_set_maskRGB, (unsigned int)label_attributes->last_mask_R, (unsigned int)label_attributes->last_mask_G, (unsigned int)label_attributes->last_mask_B); d_call(self, m_drawable_set_maskA, (unsigned int)label_attributes->last_mask_A); } else { snprintf(buffer, d_string_buffer_size, "unable to retrieve informations for label \"%s\" exception", d_string_cstring(string_content)); d_throw(v_exception_texture, buffer); } SDL_FreeSurface(unoptimized_surface); } else { snprintf(buffer, d_string_buffer_size, "ungenerable texture for label \"%s\" exception", d_string_cstring(string_content)); d_throw(v_exception_texture, buffer); } return self; }
d_define_method(checkbox, set_drawable)(struct s_object *self, struct s_object *checked, struct s_object *unchecked) { d_using(checkbox); checkbox_attributes->checked = d_retain(checked); checkbox_attributes->unchecked = d_retain(unchecked); return self; }