📄 base_scenegraph.c
字号:
while (list) { if (pos==cur_pos) return list->node; if ((pos<0) && !list->next) return list->node; list = list->next; cur_pos++; } return NULL;}GF_EXPORTs32 gf_node_list_find_child(GF_ChildNodeItem *list, GF_Node *n){ s32 res = 0; while (list) { if (list->node==n) return res; list = list->next; res++; } return -1;}GF_EXPORTGF_Err gf_node_list_add_child(GF_ChildNodeItem **list, GF_Node *n){ GF_ChildNodeItem *child, *cur; child = *list; cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); if (!cur) return GF_OUT_OF_MEM; cur->node = n; cur->next = NULL; if (child) { while (child->next) child = child->next; child->next = cur; } else { *list = cur; } return GF_OK;}GF_EXPORTGF_Err gf_node_list_add_child_last(GF_ChildNodeItem **list, GF_Node *n, GF_ChildNodeItem **last_child){ GF_ChildNodeItem *child, *cur; child = *list; cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); if (!cur) return GF_OUT_OF_MEM; cur->node = n; cur->next = NULL; if (child) { if (last_child && (*last_child) ) { while ((*last_child)->next) (*last_child) = (*last_child)->next; (*last_child)->next = cur; (*last_child) = (*last_child)->next; } else { while (child->next) child = child->next; child->next = cur; if (last_child) *last_child = child->next; } } else { *list = cur; if (last_child) *last_child = *list; } return GF_OK;}GF_EXPORTBool gf_node_list_del_child(GF_ChildNodeItem **list, GF_Node *n){ GF_ChildNodeItem *child, *cur; child = *list; if (!child) return 0; if (child->node==n) { *list = child->next; free(child); return 1; } while (child->next) { if (child->next->node!=n) { child = child->next; continue; } cur = child->next; child->next = cur->next; free(cur); return 1; } return 0;}GF_EXPORTGF_Node *gf_node_list_del_child_idx(GF_ChildNodeItem **list, u32 pos){ u32 cur_pos = 0; GF_Node *ret = NULL; GF_ChildNodeItem *child, *cur; child = *list; if (!child) return 0; if (!pos) { *list = child->next; ret = child->node; free(child); return ret; } while (child->next) { if (cur_pos+1 != pos) { child = child->next; cur_pos++; continue; } cur = child->next; child->next = cur->next; ret = cur->node; free(cur); return ret; } return NULL;}GF_EXPORTu32 gf_node_list_get_count(GF_ChildNodeItem *list){ u32 count = 0; while (list) { count++; list = list->next; } return count;}void gf_sg_parent_reset(GF_Node *node){ gf_node_unregister_children(node, ((GF_ParentNode *)node)->children); ((GF_ParentNode *)node)->children = NULL;}void gf_node_free(GF_Node *node){ if (!node) return; if (node->sgprivate->UserCallback) node->sgprivate->UserCallback(node, NULL, 1); if (node->sgprivate->interact) { if (node->sgprivate->interact->events) { /*true for VRML-based graphs, not true for SVG yet*/ //assert(gf_list_count(node->sgprivate->events)==0); gf_list_del(node->sgprivate->interact->events); } if (node->sgprivate->interact->animations) { gf_list_del(node->sgprivate->interact->animations); } free(node->sgprivate->interact); } assert(! node->sgprivate->parents); free(node->sgprivate); free(node);}GF_EXPORTu32 gf_node_get_parent_count(GF_Node *node){ u32 count = 0; GF_ParentList *nlist = node->sgprivate->parents; while (nlist) { count++; nlist = nlist->next; } return count;}GF_EXPORTGF_Node *gf_node_get_parent(GF_Node *node, u32 idx){ GF_ParentList *nlist = node->sgprivate->parents; if (!nlist) return NULL; while (idx) { nlist = nlist->next; idx--;} return nlist->node;}static GFINLINE void dirty_children(GF_Node *node, u32 val){ u32 i, count; GF_FieldInfo info; if (!node) return; node->sgprivate->flags |= val; if (node->sgprivate->tag>=GF_NODE_RANGE_LAST_VRML) { GF_ChildNodeItem *child = ((GF_ParentNode*)node)->children; while (child) { dirty_children(child->node, val); child = child->next; } } else { count = gf_node_get_field_count(node); for (i=0; i<count; i++) { gf_node_get_field(node, i, &info); if (info.fieldType==GF_SG_VRML_SFNODE) dirty_children(*(GF_Node **)info.far_ptr, val); else if (info.fieldType==GF_SG_VRML_MFNODE) { GF_ChildNodeItem *list = *(GF_ChildNodeItem **) info.far_ptr; while (list) { dirty_children(list->node, val); list = list->next; } } } }}static void dirty_parents(GF_Node *node){ Bool check_root = 1; GF_ParentList *nlist = node->sgprivate->parents; while (nlist) { GF_Node *p = nlist->node; if (! (p->sgprivate->flags & GF_SG_CHILD_DIRTY)) { p->sgprivate->flags |= GF_SG_CHILD_DIRTY; dirty_parents(p); } check_root = 0; nlist = nlist->next; } if (check_root && (node==node->sgprivate->scenegraph->RootNode) && node->sgprivate->scenegraph->NodeCallback) node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_GRAPH_DIRTY, NULL, NULL);}GF_EXPORTvoid gf_node_dirty_set(GF_Node *node, u32 flags, Bool and_dirty_parents){ if (!node) return; if (flags) node->sgprivate->flags |= (flags & (~GF_NODE_INTERNAL_FLAGS) ); else node->sgprivate->flags |= GF_SG_NODE_DIRTY; if (and_dirty_parents) dirty_parents(node);}GF_EXPORTvoid gf_node_dirty_clear(GF_Node *node, u32 flag_to_remove){ if (!node) return; if (flag_to_remove) node->sgprivate->flags &= ~ (flag_to_remove & ~GF_NODE_INTERNAL_FLAGS); else node->sgprivate->flags &= GF_NODE_INTERNAL_FLAGS;}GF_EXPORTu32 gf_node_dirty_get(GF_Node *node){ if (node) return (node->sgprivate->flags & ~GF_NODE_INTERNAL_FLAGS); return 0;}GF_EXPORTvoid gf_node_dirty_reset(GF_Node *node){ if (!node) return; if (node->sgprivate->flags & ~GF_NODE_INTERNAL_FLAGS) { node->sgprivate->flags &= GF_NODE_INTERNAL_FLAGS; dirty_children(node, 0); }}GF_EXPORTvoid gf_node_init(GF_Node *node){ GF_SceneGraph *pSG = node->sgprivate->scenegraph; assert(pSG); /*no user-defined init, consider the scenegraph is only used for parsing/encoding/decoding*/ if (!pSG->NodeCallback) return; /*internal nodes*/ if (gf_sg_vrml_node_init(node)) return;#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (gf_svg_sa_node_init(node)) return;#endif#ifdef GPAC_ENABLE_SVG_SANI else if (gf_svg_sani_node_init(node)) return;#endif else if (gf_svg_node_init(node)) return;#endif /*user defined init*/ else pSG->NodeCallback(pSG->userpriv, GF_SG_CALLBACK_INIT, node, NULL);}GF_EXPORTvoid gf_node_changed(GF_Node *node, GF_FieldInfo *field){ GF_SceneGraph *sg; if (!node) return; sg = node->sgprivate->scenegraph; assert(sg); /*internal nodes*/ if (gf_sg_vrml_node_changed(node, field)) return;#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (gf_svg_sa_node_changed(node, field)) return;#endif#ifdef GPAC_ENABLE_SVG_SANI else if (gf_svg_sani_node_changed(node, field)) return;#endif else if (gf_svg_node_changed(node, field)) return;#endif /*force child dirty tag*/ if (field && ((field->fieldType==GF_SG_VRML_SFNODE) || (field->fieldType==GF_SG_VRML_MFNODE))) node->sgprivate->flags |= GF_SG_CHILD_DIRTY; if (sg->NodeCallback) sg->NodeCallback(sg->userpriv, GF_SG_CALLBACK_MODIFIED, node, field);}void gf_node_del(GF_Node *node){#ifdef GF_NODE_USE_POINTERS node->sgprivate->node_del(node);#else if (node->sgprivate->tag==TAG_UndefinedNode) gf_node_free(node); else if (node->sgprivate->tag==TAG_DOMText) { GF_DOMText *t = (GF_DOMText *)node; if (t->textContent) free(t->textContent); gf_sg_parent_reset(node); gf_node_free(node); } else if (node->sgprivate->tag==TAG_DOMUpdates) { u32 i, count; GF_DOMUpdates *up = (GF_DOMUpdates *)node; if (up->data) free(up->data); count = gf_list_count(up->updates); for (i=0; i<count; i++) { GF_Command *com = gf_list_get(up->updates, i); gf_sg_command_del(com); } gf_list_del(up->updates); gf_sg_parent_reset(node); gf_node_free(node); } else if (node->sgprivate->tag == TAG_DOMFullNode) { GF_DOMFullNode *n = (GF_DOMFullNode *)node; while (n->attributes) { GF_DOMAttribute *att = n->attributes; n->attributes = att->next; if (att->tag==TAG_DOM_ATTRIBUTE_FULL) { GF_DOMFullAttribute *fa = (GF_DOMFullAttribute *)att; free(fa->data); free(fa->name); } free(att); } if (n->name) free(n->name); if (n->ns) free(n->ns); gf_sg_parent_reset(node); gf_node_free(node); } else if (node->sgprivate->tag == TAG_ProtoNode) gf_sg_proto_del_instance((GF_ProtoInstance *)node); else if (node->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) gf_sg_mpeg4_node_del(node); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) gf_sg_x3d_node_del(node);#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SA) gf_svg_sa_element_del((SVG_SA_Element *) node);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SANI) gf_svg_sani_element_del((SVG_SANI_Element *) node);#endif else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) gf_svg_node_del(node);#endif else gf_node_free(node);#endif}GF_EXPORTu32 gf_node_get_field_count(GF_Node *node){ assert(node); if (node->sgprivate->tag <= TAG_UndefinedNode) return 0; /*for both MPEG4 & X3D*/ else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SA) return gf_svg_sa_get_attribute_count(node);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SANI) return gf_svg_sani_get_attribute_count(node);#endif else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) return 0;#endif return 0;}GF_EXPORTconst char *gf_node_get_class_name(GF_Node *node){ assert(node && node->sgprivate->tag);#ifdef GF_NODE_USE_POINTERS return node->sgprivate->name;#else if (node->sgprivate->tag==TAG_UndefinedNode) return "UndefinedNode"; else if (node->sgprivate->tag==TAG_ProtoNode) return ((GF_ProtoInstance*)node)->proto_name; else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_class_name(node->sgprivate->tag); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_class_name(node->sgprivate->tag); else if (node->sgprivate->tag==TAG_DOMText) return ""; else if (node->sgprivate->tag==TAG_DOMFullNode) return ((GF_DOMFullNode*)node)->name;#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SA) return gf_svg_sa_get_element_name(node->sgprivate->tag);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SANI) return gf_svg_sani_get_element_name(node->sgprivate->tag);#endif else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) return gf_svg_get_element_name(node->sgprivate->tag);#endif else return "UnsupportedNode";#endif}GF_EXPORTGF_Node *gf_node_new(GF_SceneGraph *inScene, u32 tag){ GF_Node *node;// if (!inScene) return NULL; /*cannot create proto this way*/ if (tag==TAG_ProtoNode) return NULL; else if (tag==TAG_UndefinedNode) node = gf_sg_new_base_node(); else if (tag <= GF_NODE_RANGE_LAST_MPEG4) node = gf_sg_mpeg4_node_new(tag); else if (tag <= GF_NODE_RANGE_LAST_X3D) node = gf_sg_x3d_node_new(tag); else if (tag == TAG_DOMText) { GF_DOMText *n; GF_SAFEALLOC(n, GF_DOMText); node = (GF_Node*)n; gf_node_setup(node, TAG_DOMText); } else if (tag == TAG_DOMFullNode) { GF_DOMFullNode*n; GF_SAFEALLOC(n, GF_DOMFullNode); node = (GF_Node*)n; gf_node_setup(node, TAG_DOMFullNode); }#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (tag <= GF_NODE_RANGE_LAST_SVG_SA) node = (GF_Node *) gf_svg_sa_create_node(tag);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (tag <= GF_NODE_RANGE_LAST_SVG_SANI) node = (GF_Node *) gf_svg_sani_create_node(tag);#endif else if (tag <= GF_NODE_RANGE_LAST_SVG) node = (GF_Node *) gf_svg_create_node(tag);#endif else node = NULL; if (node) node->sgprivate->scenegraph = inScene; /*script is inited as soon as created since fields are dynamically added*/ if ((tag==TAG_MPEG4_Script) || (tag==TAG_X3D_Script) ) gf_sg_script_init(node); return node;}GF_EXPORTGF_Err gf_node_get_field(GF_Node *node, u32 FieldIndex, GF_FieldInfo *info){ assert(node); assert(info); memset(info, 0, sizeof(GF_FieldInfo)); info->fieldIndex = FieldIndex;#ifdef GF_NODE_USE_POINTERS return node->sgprivate->get_field(node, info);#else if (node->sgprivate->tag==TAG_UndefinedNode) return GF_BAD_PARAM; else if (node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_field(NULL, node, info); else if ((node->sgprivate->tag == TAG_MPEG4_Script) || (node->sgprivate->tag == TAG_X3D_Script) ) return gf_sg_script_get_field(node, info); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field(node, info); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field(node, info);#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SA) return gf_svg_sa_get_attribute_info(node, info);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SANI) return gf_svg_sani_get_attribute_info(node, info);#endif else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) return GF_NOT_SUPPORTED;#endif#endif return GF_NOT_SUPPORTED;}u32 gf_node_get_num_instances(GF_Node *node){ return node->sgprivate->num_instances;}static GF_Err gf_node_get_field_by_name_enum(GF_Node *node, char *name, GF_FieldInfo *field){ u32 i, count; assert(node); count = gf_node_get_field_count(node); memset(field, 0, sizeof(GF_FieldInfo)); for (i=0; i<count;i++) { gf_node_get_field(node, i, field); if (!strcmp(field->name, name)) return GF_OK; } return GF_BAD_PARAM;}GF_Err gf_node_get_field_by_name(GF_Node *node, char *name, GF_FieldInfo *field){#ifdef GF_NODE_USE_POINTERS return gf_node_get_field_by_name_enum(node, name, field);#else s32 res = -1; if (node->sgprivate->tag==TAG_UndefinedNode) return GF_BAD_PARAM; else if (node->sgprivate->tag == TAG_ProtoNode) { res = gf_sg_proto_get_field_index_by_name(NULL, node, name); } else if ((node->sgprivate->tag == TAG_MPEG4_Script) || (node->sgprivate->tag == TAG_X3D_Script) ) { return gf_node_get_field_by_name_enum(node, name, field); } else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) res = gf_sg_mpeg4_node_get_field_index_by_name(node, name); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) res = gf_sg_x3d_node_get_field_index_by_name(node, name);#ifndef GPAC_DISABLE_SVG else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) return gf_svg_get_attribute_by_name(node, name, 1, 0, field);#ifdef GPAC_ENABLE_SVG_SA else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SA) res = gf_svg_sa_get_attribute_index_by_name(node, name);#endif#ifdef GPAC_ENABLE_SVG_SANI else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG_SANI) return gf_node_get_field_by_name_enum(node, name, field);#endif#endif if (res==-1) return GF_BAD_PARAM; return gf_node_get_field(node, (u32) res, field);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -