📄 loader_bt.c
字号:
goto err; } parser->last_error = GF_OK; str = gf_bt_get_next(parser, 0); sf = gf_sg_script_field_new(node, eType, fType, str); parser->last_error = gf_node_get_field_by_name(node, str, &info); if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue; if ((eType == GF_SG_SCRIPT_TYPE_EVENT_IN) || (eType == GF_SG_SCRIPT_TYPE_EVENT_OUT)) continue; } if (parser->last_error) { gf_bt_report(parser, GF_OK, "%s: Unknown field", str); goto err; } if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue; switch (info.fieldType) { case GF_SG_VRML_SFNODE: /*if redefining node reset it - this happens with CreateVrmlFromString*/ if (* ((GF_Node **)info.far_ptr) ) { gf_node_unregister(* ((GF_Node **)info.far_ptr), node); * ((GF_Node **)info.far_ptr) = NULL; } newnode = gf_bt_sf_node(parser, NULL, node, NULL); if (!newnode && parser->last_error) goto err; if (newnode) { if (!gf_bt_check_ndt(parser, &info, newnode, node)) goto err; * ((GF_Node **)info.far_ptr) = newnode; } break; case GF_SG_VRML_MFNODE: { GF_ChildNodeItem *last = NULL; Bool single_child = 0; if (!gf_bt_check_code(parser, '[')) { if (parser->is_wrl) single_child = 1; else break; } /*if redefining node reset it - this happens with CreateVrmlFromString*/ if (undef_node==node) { gf_node_unregister_children(node, *(GF_ChildNodeItem **)info.far_ptr); *(GF_ChildNodeItem **)info.far_ptr = NULL; } while (single_child || !gf_bt_check_code(parser, ']')) { /*VRML seems to allow that*/ gf_bt_check_code(parser, ','); newnode = gf_bt_sf_node(parser, NULL, node, NULL); if (!newnode && parser->last_error) goto err; if (newnode) { if (!gf_bt_check_ndt(parser, &info, newnode, node)) goto err; gf_node_list_add_child_last( (GF_ChildNodeItem **)info.far_ptr, newnode, &last); } if (single_child) break; } } break; default: if (gf_sg_vrml_is_sf_field(info.fieldType)) { gf_bt_sffield(parser, &info, node); } else { gf_bt_mffield(parser, &info, node); } if (parser->last_error) goto err; break; } /*VRML seems to allow that*/ gf_bt_check_code(parser, ','); if (proto) gf_sg_proto_mark_field_loaded(node, &info); } } /*VRML seems to allow that*/ gf_bt_check_code(parser, ','); /*we must init the node once ID is set in case we're creating rendering stacks*/ if (init_node && (gf_node_get_tag(node)!=TAG_ProtoNode) ) gf_node_init(node); /*remove temp node*/ if (replace_prev) { gf_node_replace(undef_node, node, 0); gf_list_del_item(parser->undef_nodes, undef_node); } if (!parser->parsing_proto && is_script && (parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) ) { if (parser->cur_com) { if (!parser->cur_com->scripts_to_load) parser->cur_com->scripts_to_load = gf_list_new(); gf_list_add(parser->cur_com->scripts_to_load, node); } else { /*postpone script init since it may use routes/nodes not yet defined ...*/ gf_list_add(parser->scripts, node); } } return node;err: gf_node_unregister(node, parent); if (name) free(name); return NULL;}/* locate node, if not defined yet parse ahead in current AU optimization: we actually peek ALL DEF NODES till end of AU*/GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID){ GF_Node *n, *the_node; u32 tag, ID; Bool prev_is_insert = 0; char *str, *ret; char nName[1000]; u32 pos, line, line_pos, i, count; n = gf_sg_find_node_by_name(parser->load->scene_graph, defID); if (n) return n; count = gf_list_count(parser->peeked_nodes); for (i=0; i<count; i++) { n = (GF_Node *)gf_list_get(parser->peeked_nodes, i); if (!strcmp(gf_node_get_name(n), defID)) return n; } the_node = NULL; pos = parser->line_start_pos; line_pos = parser->line_pos; line = parser->line; strcpy(nName, defID); n = NULL; while (!parser->done && !the_node) { str = gf_bt_get_next(parser, 0); gf_bt_check_code(parser, '['); gf_bt_check_code(parser, ']'); gf_bt_check_code(parser, '{'); gf_bt_check_code(parser, '}'); gf_bt_check_code(parser, ','); gf_bt_check_code(parser, '.'); if ( (!prev_is_insert && !strcmp(str, "AT")) || !strcmp(str, "PROTO") ) { /*only check in current command (but be aware of conditionals..)*/ if (!the_node && gf_list_find(parser->bifs_au->commands, parser->cur_com)) { gf_bt_report(parser, GF_BAD_PARAM, "Cannot find node %s\n", nName); break; } continue; } if (!strcmp(str, "INSERT")) prev_is_insert = 1; else prev_is_insert = 0; if (strcmp(str, "DEF")) continue; str = gf_bt_get_next(parser, 0); ret = strdup(str); str = gf_bt_get_next(parser, 0); if (!strcmp(str, "ROUTE")) { free(ret); continue; } tag = gf_bt_get_node_tag(parser, str); if (!tag) { GF_Proto *p; GF_SceneGraph *sg = parser->load->scene_graph; while (1) { p = gf_sg_find_proto(sg, 0, str); if (p) break; sg = sg->parent_scene; if (!sg) break; } if (!p) { /*locate proto*/ gf_bt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported node", str); free(ret); return NULL; } n = gf_sg_proto_create_instance(parser->load->scene_graph, p); } else { n = gf_bt_new_node(parser, tag); } ID = gf_bt_get_def_id(parser, ret); if (n) { gf_node_set_id(n, ID, ret); gf_list_add(parser->peeked_nodes, n); if (!parser->parsing_proto) gf_node_init(n); if (!strcmp(ret, nName)) the_node = n; } free(ret); /*NO REGISTER on peek (both scene graph or DEF list) because peek is only used to get node type and fields, never to insert in the graph*/ /*go on till end of AU*/ } /*restore context*/ parser->done = 0; gzrewind(parser->gz_in); gzseek(parser->gz_in, pos, SEEK_SET); parser->line_pos = parser->line_size; gf_bt_check_line(parser); parser->line = line; parser->line_pos = line_pos; return the_node;}u32 gf_bt_get_route(GF_BTParser *parser, char *name) { u32 i; GF_Command *com; GF_Route *r = gf_sg_route_find_by_name(parser->load->scene_graph, name); if (r) return r->ID; i=0; while ((com = (GF_Command *)gf_list_enum(parser->inserted_routes, &i))) { if (com->def_name && !strcmp(com->def_name, name)) return com->RouteID; } return 0;}Bool gf_bt_route_id_used(GF_BTParser *parser, u32 ID) { u32 i; GF_Command *com; GF_Route *r = gf_sg_route_find(parser->load->scene_graph, ID); if (r) return 1; i=0; while ((com = (GF_Command *)gf_list_enum(parser->inserted_routes, &i))) { if (com->RouteID == ID) return 1; } return 0;}static u32 get_evt_type(char *eventName){ if (!strcmp(eventName, "eventIn") || !strcmp(eventName, "inputOnly")) return GF_SG_EVENT_IN; else if (!strcmp(eventName, "eventOut") || !strcmp(eventName, "outputOnly")) return GF_SG_EVENT_OUT; else if (!strcmp(eventName, "field") || !strcmp(eventName, "initializeOnly")) return GF_SG_EVENT_FIELD; else if (!strcmp(eventName, "exposedField") || !strcmp(eventName, "inputOutput")) return GF_SG_EVENT_EXPOSED_FIELD; else return GF_SG_EVENT_UNKNOWN;}GF_Err gf_bt_parse_proto(GF_BTParser *parser, char *proto_code, GF_List *proto_list){ GF_FieldInfo info; u32 fType, eType, QPType, pID; Bool externProto; GF_Proto *proto, *prevproto; GF_ProtoFieldInterface *pfield; GF_SceneGraph *sg; char *str, *name; char szDefName[1024]; Bool isDEF; if (proto_code) str = proto_code; else str = gf_bt_get_next(parser, 0); externProto = !strcmp(str, "EXTERNPROTO") ? 1 : 0; str = gf_bt_get_next(parser, 0); name = strdup(str); if (!gf_bt_check_code(parser, '[')) { return gf_bt_report(parser, GF_BAD_PARAM, "[ expected in proto declare"); } pID = gf_bt_get_next_proto_id(parser); /*if redefinition remove it - WRL only, may be used by loadVRMLFormString*/ if (!proto_list && parser->is_wrl) { proto = gf_sg_find_proto(parser->load->scene_graph, pID, name); if (proto) gf_sg_proto_del(proto); } proto = gf_sg_proto_new(parser->load->scene_graph, pID, name, proto_list ? 1 : 0); if (proto_list) gf_list_add(proto_list, proto); if (parser->load->ctx && (parser->load->ctx->max_proto_id<pID)) parser->load->ctx->max_proto_id = pID; /*hack for VRML, where externProto default field values are not mandatory*/ parser->is_extern_proto_field = externProto; free(name); /*get all fields*/ while (!parser->last_error && !gf_bt_check_code(parser, ']')) { str = gf_bt_get_next(parser, 0);next_field: if (gf_bt_check_code(parser, ']')) break; eType = get_evt_type(str); if (eType==GF_SG_EVENT_UNKNOWN) { gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown event type", str); goto err; } str = gf_bt_get_next(parser, 0); fType = gf_sg_field_type_by_name(str); if (fType==GF_SG_VRML_UNKNOWN) { gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown field type", str); goto err; } str = gf_bt_get_next(parser, 0); pfield = gf_sg_proto_field_new(proto, fType, eType, str); if ((eType==GF_SG_EVENT_IN) || (eType==GF_SG_EVENT_OUT)) continue; gf_sg_proto_field_get_field(pfield, &info); if (fType==GF_SG_VRML_SFNODE) { str = gf_bt_get_next(parser, 0); if (strcmp(str, "NULL")) { if ( (!strlen(str) || (get_evt_type(str)!=GF_SG_EVENT_UNKNOWN)) && parser->is_extern_proto_field) goto next_field; pfield->def_sfnode_value = gf_bt_sf_node(parser, str, NULL, NULL); } } else if (fType==GF_SG_VRML_MFNODE) { GF_ChildNodeItem *last = NULL; if (gf_bt_check_code(parser, '[')) { while (1) { GF_Node *pf_node; if (gf_bt_check_code(parser, ']')) break; pf_node = gf_bt_sf_node(parser, NULL, NULL, NULL); if (pf_node) gf_node_list_add_child_last( &pfield->def_mfnode_value, pf_node, &last); } } } else if (gf_sg_vrml_is_sf_field(fType)) { gf_bt_sffield(parser, &info, NULL); if (parser->last_error==GF_EOS) { gf_sg_proto_field_set_value_undefined(pfield); parser->last_error=GF_OK; goto next_field; } } else { gf_bt_mffield(parser, &info, NULL); } /*check QP info*/ if (!gf_bt_check_code(parser, '{')) continue; if (gf_bt_check_code(parser, '}')) continue; str = gf_bt_get_next(parser, 0); if (!strcmp(str, "QP")) { u32 nbBits, hasMin; Fixed ftMin, ftMax; gf_bt_parse_int(parser, "QPType", (SFInt32*)&QPType); nbBits = 0; str = gf_bt_get_next(parser, 0); if (!strcmp(str, "nbBits")) { gf_bt_parse_int(parser, "nbBits", (SFInt32*)&nbBits); str = gf_bt_get_next(parser, 0); } hasMin = 0; eType = 0; if (!strcmp(str, "b")) { hasMin = 1; if (!gf_bt_check_code(parser, '{')) { gf_bt_report(parser, GF_BAD_PARAM, "%s: Invalid proto coding parameter declare", str); goto err; } gf_bt_parse_float(parser, "min", &ftMin); gf_bt_parse_float(parser, "max", &ftMax); if (!gf_bt_check_code(parser, '}')) { gf_bt_report(parser, GF_BAD_PARAM, "Invalid proto coding parameter declare"); goto err; } if (gf_sg_vrml_get_sf_type(fType) == GF_SG_VRML_SFINT32) { eType = GF_SG_VRML_SFINT32; } else { eType = GF_SG_VRML_SFFLOAT; } } gf_bifs_proto_field_set_aq_info(pfield, QPType, hasMin, eType, &ftMin, &ftMax, nbBits); if (!gf_bt_check_code(parser, '}')) { gf_bt_report(parser, GF_BAD_PARAM, "Invalid proto coding parameter declare"); goto err; } } } parser->is_extern_proto_field = 0; if (externProto) { SFURL *url; u32 nb_urls; Bool has_urls = 0; if (gf_bt_check_code(parser, '[')) has_urls = 1; gf_sg_vrml_mf_reset(&proto->ExternProto, GF_SG_VRML_MFURL); nb_urls = 0; do { str = gf_bt_get_next(parser, 0); gf_sg_vrml_mf_append(&proto->ExternProto, GF_SG_VRML_MFURL, (void **) &url); if (!strnicmp(str, "od:", 3)) { sscanf(str, "od:%d", &url->OD_ID); } else { if (!sscanf(str, "%d", &url->OD_ID)) { url->url = strdup(str); } else { char szURL[20]; sprintf(szURL, "%d", url->OD_ID); if (strcmp(szURL, str)) { url->OD_ID = 0; url->url = strdup(str); } } } if (has_urls) { gf_bt_check_code(parser, ','); if (gf_bt_check_code(parser, ']')) has_urls = 0; } } while (has_urls); return GF_OK; } /*parse proto code */ if (!gf_bt_check_code(parser, '{')) { gf_bt_report(parser, GF_OK, "empty proto body"); return GF_OK; } prevproto = parser->parsing_proto; sg = parser->load->scene_graph; parser->parsing_proto = proto; parser->load->scene_graph = gf_sg_proto_get_graph(proto); isDEF = 0; while (!gf_bt_check_code(parser, '}')) { str = gf_bt_get_next(parser, 0); if (!strcmp(str, "PROTO") || !strcmp(str, "EXTERNPROTO")) { gf_bt_parse_proto(parser, str, NULL); } else if (!strcmp(str, "DEF")) { isDEF = 1; str = gf_bt_get_next(parser, 0); strcpy(szDefName, str); } else if (!strcmp(str, "ROUTE")) { GF_Route *r = gf_bt_parse_route(parser, 1, 0, NULL); if (isDEF) { u32 rID = gf_bt_get_route(parser, szDefName); if (!rID) rID = gf_bt_get_next_route_id(parser); parser->last_error = gf_sg_route_set_id(r, rID); gf_sg_route_set_name(r, szDefName); isDEF = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -