void rut_graphable_add_child (RutObject *parent, RutObject *child) { RutGraphableProps *parent_props = rut_object_get_properties (parent, RUT_INTERFACE_ID_GRAPHABLE); RutGraphableVTable *parent_vtable = rut_object_get_vtable (parent, RUT_INTERFACE_ID_GRAPHABLE); RutGraphableProps *child_props = rut_object_get_properties (child, RUT_INTERFACE_ID_GRAPHABLE); RutGraphableVTable *child_vtable = rut_object_get_vtable (child, RUT_INTERFACE_ID_GRAPHABLE); RutObject *old_parent = child_props->parent; rut_refable_claim (child, parent); if (old_parent) rut_graphable_remove_child (child); child_props->parent = parent; if (child_vtable && child_vtable->parent_changed) child_vtable->parent_changed (child, old_parent, parent); if (parent_vtable && parent_vtable->child_added) parent_vtable->child_added (parent, child); /* XXX: maybe this should be deferred to parent_vtable->child_added ? */ g_queue_push_tail (&parent_props->children, child); }
void rut_graphable_remove_child (RutObject *child) { RutGraphableProps *child_props = rut_object_get_properties (child, RUT_INTERFACE_ID_GRAPHABLE); RutObject *parent = child_props->parent; RutGraphableVTable *parent_vtable; RutGraphableProps *parent_props; if (!parent) return; parent_vtable = rut_object_get_vtable (parent, RUT_INTERFACE_ID_GRAPHABLE); parent_props = rut_object_get_properties (parent, RUT_INTERFACE_ID_GRAPHABLE); /* Note: we set ->parent to NULL here to avoid re-entrancy so * ->child_removed can be a general function for removing a child * that might itself call rut_graphable_remove_child() */ child_props->parent = NULL; if (parent_vtable->child_removed) parent_vtable->child_removed (parent, child); g_queue_remove (&parent_props->children, child); rut_refable_release (child, parent); }
void * rut_refable_simple_ref (void *object) { int *ref_count = rut_object_get_properties (object, RUT_INTERFACE_ID_REF_COUNTABLE); (*ref_count)++; return object; }
static RutObject * _rut_graphable_get_parent (RutObject *child) { RutGraphableProps *child_props = rut_object_get_properties (child, RUT_INTERFACE_ID_GRAPHABLE); return child_props->parent; }
static void reshape_cb (RutShape *shape, void *user_data) { RutComponentableProps *componentable = rut_object_get_properties (shape, RUT_INTERFACE_ID_COMPONENTABLE); RutEntity *entity = componentable->entity; rig_dirty_entity_pipelines (entity); }
void rut_graphable_remove_all_children (RutObject *parent) { RutGraphableProps *parent_props = rut_object_get_properties (parent, RUT_INTERFACE_ID_GRAPHABLE); RutObject *child; while ((child = g_queue_pop_tail (&parent_props->children))) rut_graphable_remove_child (child); }
void rut_graphable_init (RutObject *object) { RutGraphableProps *props = rut_object_get_properties (object, RUT_INTERFACE_ID_GRAPHABLE); props->parent = NULL; props->children.head = NULL; props->children.tail = NULL; props->children.length = 0; }
void rut_simple_introspectable_destroy (RutObject *object) { RutSimpleIntrospectableProps *props = rut_object_get_properties (object, RUT_INTERFACE_ID_SIMPLE_INTROSPECTABLE); RutProperty *properties = props->first_property; int i; for (i = 0; i < props->n_properties; i++) rut_property_destroy (&properties[i]); }
RutObject * rut_graphable_first (RutObject *parent) { RutGraphableProps *graphable = rut_object_get_properties (parent, RUT_INTERFACE_ID_GRAPHABLE); if (graphable->children.head) return graphable->children.head->data; else return NULL; }
void rut_graphable_destroy (RutObject *object) { RutGraphableProps *props = rut_object_get_properties (object, RUT_INTERFACE_ID_GRAPHABLE); /* The node shouldn't have a parent, because if it did then it would * still have a reference and it shouldn't be being destroyed */ g_warn_if_fail (props->parent == NULL); rut_graphable_remove_all_children (object); }
void rut_graphable_apply_transform (RutObject *graphable, CoglMatrix *transform_matrix) { int depth = 0; RutObject **transform_nodes; RutObject *node = graphable; int i; do { RutGraphableProps *graphable_priv = rut_object_get_properties (node, RUT_INTERFACE_ID_GRAPHABLE); depth++; node = graphable_priv->parent; } while (node); transform_nodes = g_alloca (sizeof (RutObject *) * depth); node = graphable; i = 0; do { RutGraphableProps *graphable_priv; if (rut_object_is (node, RUT_INTERFACE_ID_TRANSFORMABLE)) transform_nodes[i++] = node; graphable_priv = rut_object_get_properties (node, RUT_INTERFACE_ID_GRAPHABLE); node = graphable_priv->parent; } while (node); for (i--; i >= 0; i--) { const CoglMatrix *matrix = rut_transformable_get_matrix (transform_nodes[i]); cogl_matrix_multiply (transform_matrix, transform_matrix, matrix); } }
void rut_refable_simple_unref (void *object) { int *ref_count = rut_object_get_properties (object, RUT_INTERFACE_ID_REF_COUNTABLE); if (--(*ref_count) < 1) { RutRefableVTable *vtable = rut_object_get_vtable (object, RUT_INTERFACE_ID_REF_COUNTABLE); g_assert (*ref_count == 0); vtable->free (object); } }
void rut_simple_introspectable_foreach_property (RutObject *object, RutIntrospectablePropertyCallback callback, void *user_data) { RutSimpleIntrospectableProps *priv = rut_object_get_properties (object, RUT_INTERFACE_ID_SIMPLE_INTROSPECTABLE); int i; for (i = 0; i < priv->n_properties; i++) { RutProperty *property = priv->first_property + i; callback (property, user_data); } }
void rut_simple_introspectable_register_properties (RutObject *object, RutProperty *first_property) { RutSimpleIntrospectableProps *props = rut_object_get_properties (object, RUT_INTERFACE_ID_SIMPLE_INTROSPECTABLE); RutPropertySpec *first_spec = first_property->spec; int n; for (n = 0; first_spec[n].name; n++) ; props->first_property = first_property; props->n_properties = n; }
RutObject * rut_graphable_nth (RutObject *parent, int n) { RutGraphableProps *graphable = rut_object_get_properties (parent, RUT_INTERFACE_ID_GRAPHABLE); GList *l; int i; for (l = graphable->children.head, i = 0; l && i < n; l = l->next, i++) ; if (l) return l->data; else return NULL; }
RutProperty * rut_simple_introspectable_lookup_property (RutObject *object, const char *name) { RutSimpleIntrospectableProps *priv = rut_object_get_properties (object, RUT_INTERFACE_ID_SIMPLE_INTROSPECTABLE); int i; for (i = 0; i < priv->n_properties; i++) { RutProperty *property = priv->first_property + i; if (strcmp (property->spec->name, name) == 0) return property; } return NULL; }
RutCamera * rut_graphable_find_camera (RutObject *object) { do { RutGraphableProps *graphable_priv; if (rut_object_get_type (object) == &rut_camera_type) return RUT_CAMERA (object); graphable_priv = rut_object_get_properties (object, RUT_INTERFACE_ID_GRAPHABLE); object = graphable_priv->parent; } while (object); return NULL; }
void rut_light_set_uniforms (RutLight *light, CoglPipeline *pipeline) { RutComponentableProps *component = rut_object_get_properties (light, RUT_INTERFACE_ID_COMPONENTABLE); RutEntity *entity = component->entity; float origin[3] = {0, 0, 0}; float norm_direction[3] = {0, 0, 1}; int location; rut_entity_get_transformed_position (entity, origin); rut_entity_get_transformed_position (entity, norm_direction); cogl_vector3_subtract (norm_direction, norm_direction, origin); cogl_vector3_normalize (norm_direction); location = cogl_pipeline_get_uniform_location (pipeline, "light0_direction_norm"); cogl_pipeline_set_uniform_float (pipeline, location, 3, 1, norm_direction); location = cogl_pipeline_get_uniform_location (pipeline, "light0_ambient"); cogl_pipeline_set_uniform_float (pipeline, location, 4, 1, get_color_array (&light->ambient)); location = cogl_pipeline_get_uniform_location (pipeline, "light0_diffuse"); cogl_pipeline_set_uniform_float (pipeline, location, 4, 1, get_color_array (&light->diffuse)); location = cogl_pipeline_get_uniform_location (pipeline, "light0_specular"); cogl_pipeline_set_uniform_float (pipeline, location, 4, 1, get_color_array (&light->specular)); }
void rut_simple_introspectable_init (RutObject *object, RutPropertySpec *specs, RutProperty *properties) { RutSimpleIntrospectableProps *props = rut_object_get_properties (object, RUT_INTERFACE_ID_SIMPLE_INTROSPECTABLE); int n; for (n = 0; specs[n].name; n++) { rut_property_init (&properties[n], &specs[n], object); } props->first_property = properties; props->n_properties = n; }
static RutTraverseVisitFlags _rut_graphable_traverse_breadth (RutObject *graphable, RutTraverseCallback callback, void *user_data) { GQueue *queue = g_queue_new (); int dummy; int current_depth = 0; RutTraverseVisitFlags flags = 0; g_queue_push_tail (queue, graphable); g_queue_push_tail (queue, &dummy); /* use to delimit depth changes */ while ((graphable = g_queue_pop_head (queue))) { if (graphable == &dummy) { current_depth++; g_queue_push_tail (queue, &dummy); continue; } flags = callback (graphable, current_depth, user_data); if (flags & RUT_TRAVERSE_VISIT_BREAK) break; else if (!(flags & RUT_TRAVERSE_VISIT_SKIP_CHILDREN)) { RutGraphableProps *props = rut_object_get_properties (graphable, RUT_INTERFACE_ID_GRAPHABLE); GList *l; for (l = props->children.head; l; l = l->next) g_queue_push_tail (queue, l->data); } } g_queue_free (queue); return flags; }
static RutTraverseVisitFlags _rut_graphable_traverse_depth (RutObject *graphable, RutTraverseCallback before_children_callback, RutTraverseCallback after_children_callback, int current_depth, void *user_data) { RutTraverseVisitFlags flags; flags = before_children_callback (graphable, current_depth, user_data); if (flags & RUT_TRAVERSE_VISIT_BREAK) return RUT_TRAVERSE_VISIT_BREAK; if (!(flags & RUT_TRAVERSE_VISIT_SKIP_CHILDREN)) { RutGraphableProps *props = rut_object_get_properties (graphable, RUT_INTERFACE_ID_GRAPHABLE); GList *l; for (l = props->children.head; l; l = l->next) { flags = _rut_graphable_traverse_depth (l->data, before_children_callback, after_children_callback, current_depth + 1, user_data); if (flags & RUT_TRAVERSE_VISIT_BREAK) return RUT_TRAVERSE_VISIT_BREAK; } } if (after_children_callback) return after_children_callback (graphable, current_depth, user_data); else return RUT_TRAVERSE_VISIT_CONTINUE; }