⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vrml_proto.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
			last = NULL;			list = *( (GF_ChildNodeItem **) field_orig.far_ptr);			while (list) {				child = gf_node_clone(inScene, list->node, node);				gf_node_list_add_child_last((GF_ChildNodeItem **) field.far_ptr, child, &last);				list = list->next;			}			break;		case GF_SG_VRML_SFTIME:			gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType);			if (!inScene->GetSceneTime) break;			/*update SFTime that must be updated when cloning the node*/			if (orig->sgprivate->tag == TAG_ProtoNode) {				if (gf_sg_proto_field_is_sftime_offset(orig, &field_orig))					*((SFTime *)field.far_ptr) += inScene->GetSceneTime(inScene->userpriv);			} else if (!stricmp(field_orig.name, "startTime") || !stricmp(field_orig.name, "startTime") ) {				*((SFTime *)field.far_ptr) += inScene->GetSceneTime(inScene->userpriv);			}			break;		default:			gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType);			break;		}	}	if (node->sgprivate->tag==TAG_MPEG4_InputSensor) {		GF_Command *com_o, *com_f;		u32 k = 0;		M_InputSensor *clone_is = (M_InputSensor *)node;		M_InputSensor *orig_is = (M_InputSensor *)orig;		while ( (com_o = (GF_Command *)gf_list_enum(orig_is->buffer.commandList, &k) ) ) {			com_f = gf_sg_command_clone(com_o, node->sgprivate->scenegraph);			gf_list_add(clone_is->buffer.commandList, com_f);		}	}	/*register node*/	if (id ) {		gf_node_set_id(node, id, orig_name);	}	gf_node_register(node, cloned_parent);#ifndef GPAC_READ_ONLY	/*init node before creating ISed routes so the eventIn handler are in place*/	if (node->sgprivate->tag == TAG_MPEG4_Conditional) BIFS_SetupConditionalClone(node, orig);	else #endif		if (node->sgprivate->tag != TAG_ProtoNode) gf_node_init(node);	if (!inScene->pOwningProto) return node;	proto = inScene->pOwningProto;		/*create Routes for ISed fields*/	i=0;	while ((r1 = (GF_Route*)gf_list_enum(proto->proto_interface->sub_graph->Routes, &i))) {		r2 = NULL;		/*locate only ISed routes*/		if (!r1->IS_route) continue;				/*eventOut*/		if (r1->FromNode == orig) {			r2 = gf_sg_route_new(inScene, node, r1->FromField.fieldIndex, (GF_Node *) proto, r1->ToField.fieldIndex);			r2->IS_route = 1;		}		/*eventIn or exposedField*/		else if (r1->ToNode == orig) {			r2 = gf_sg_route_new(inScene, (GF_Node *) proto, r1->FromField.fieldIndex, node, r1->ToField.fieldIndex);			r2->IS_route = 1;			/*activate the route now so that proto instanciation works properly, otherwise we may load scripts with wrong field values			Note: we don't activate eventOut routes upon instanciation since no event has been triggered yet*/			gf_sg_route_activate(r2);		}	}		/*remember scripts*/	if (is_script) gf_list_add(proto->scripts_to_load, node);	/*this is a proto node, init our internal stuff*/	if (node->sgprivate->tag == TAG_ProtoNode) {		node->sgprivate->UserCallback = NULL;		node->sgprivate->UserPrivate = NULL;		/*NO RENDER, this is filtered at the generic gf_node_render to cope with instanciations and externProto*/		/*load code*/		gf_sg_proto_instanciate((GF_ProtoInstance *)node);	}	return node;}#ifdef GF_NODE_USE_POINTERSstatic GF_Err protoinst_get_field(GF_Node *node, GF_FieldInfo *info){	info->NDTtype = NDT_SFWorldNode;	return gf_sg_proto_get_field(NULL, node, info);}static void protoinst_del(GF_Node *n){	gf_sg_proto_del_instance((GF_ProtoInstance *)n);}#endifGF_Err gf_sg_proto_get_field_ind_static(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField){	return gf_sg_proto_get_field_index((GF_ProtoInstance *)Node, inField, IndexMode, allField);}static Bool is_same_proto(GF_Proto *p1, GF_Proto *p2){	u32 i, count;	if (gf_list_count(p1->proto_fields) != gf_list_count(p2->proto_fields)) return 0;	count = gf_list_count(p1->proto_fields);	for (i=0; i<count; i++) {		GF_ProtoFieldInterface *pf1 = (GF_ProtoFieldInterface*)gf_list_get(p1->proto_fields, i);		GF_ProtoFieldInterface *pf2 = (GF_ProtoFieldInterface*)gf_list_get(p2->proto_fields, i);		if (pf1->EventType != pf2->EventType) return 0;		if (pf1->FieldType != pf2->FieldType) return 0;		/*note we don't check names since we're not sure both protos use name coding (MPEG4 only)*/	}	return 1;}static GF_Proto *SG_FindProtoByInterface(GF_SceneGraph *sg, GF_Proto *the_proto){	GF_Proto *proto;	u32 i, count;	assert(sg);	/*browse all top-level */	i=0;	while ((proto = (GF_Proto*)gf_list_enum(sg->protos, &i))) {		if (is_same_proto(proto, the_proto)) return proto;	}	/*browse all top-level unregistered in reverse order*/	count = gf_list_count(sg->unregistered_protos);	for (i=count; i>0; i--) {		proto = (GF_Proto*)gf_list_get(sg->unregistered_protos, i-1);		if (is_same_proto(proto, the_proto)) return proto;	}	return NULL;}/*performs common initialization of routes ISed fields and protos once everything is loaded*/void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node){	GF_Node *node, *orig;	GF_Route *route, *r2;	u32 i;	GF_Proto *proto = proto_node->proto_interface;	GF_Proto *owner = proto;	if (!proto) return;	if (owner->ExternProto.count) {		GF_ProtoFieldInterface *pfi;		GF_SceneGraph *extern_lib;		if (!owner->parent_graph->GetExternProtoLib) return;		extern_lib = owner->parent_graph->GetExternProtoLib(proto->parent_graph->userpriv, &owner->ExternProto);		if (!extern_lib) return;		/*this is an hardcoded proto - all routes, node modifications and co are handled internally*/		if (extern_lib == GF_SG_INTERNAL_PROTO) {			owner->parent_graph->NodeCallback(owner->parent_graph->userpriv, GF_SG_CALLBACK_INIT, (GF_Node *) proto_node, NULL);			return;		}		/*not loaded yet*/		if (!gf_list_count(extern_lib->protos)) return;		/*overwrite this proto by external one*/		proto = NULL;		/*start with proto v2 addressing*/		if (owner->ExternProto.vals[0].url) {			u32 ID = (u32) -1;			char *szName = strrchr(owner->ExternProto.vals[0].url, '#');			if (szName) {				szName++;				if (sscanf(szName, "%d", &ID)) ID = (u32) -1;			}			proto = gf_sg_find_proto(extern_lib, ID, szName);		}		if (!proto) proto = gf_sg_find_proto(extern_lib, owner->ID, NULL);		if (!proto) proto = SG_FindProtoByInterface(extern_lib, owner);		/*couldn't find proto in the given lib, consider the proto as loaded (give up)*/		if (!proto) {			proto_node->is_loaded = 1;			return;		}		i=0;		while ((pfi = (GF_ProtoFieldInterface*)gf_list_enum(owner->proto_fields, &i))) {			GF_ProtoField *pf = (GF_ProtoField *)gf_list_get(proto_node->fields, i);			if (pfi->val_not_loaded && !pf->has_been_accessed) {				pfi = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, i);				gf_sg_vrml_field_copy(pf->field_pointer, pfi->def_value, pfi->FieldType);			}		}		/*unregister from prev and reg with real proto*/		gf_list_del_item(owner->instances, proto_node);		gf_list_add(proto->instances, proto_node);	}	/*OVERRIDE the proto instance (eg don't instanciate an empty externproto...)*/	proto_node->proto_interface = proto;	/*clone all nodes*/	i=0;	while ((orig = (GF_Node*)gf_list_enum(proto->node_code, &i))) {		/*node is cloned in the new scenegraph and its parent is NULL */		node = gf_node_clone(proto_node->sgprivate->scenegraph, orig, NULL);		assert(node);		/*assign first rendering node*/		if (i==1) proto_node->RenderingNode = node;		gf_list_add(proto_node->node_code, node);	}	/*instantiate routes (not ISed ones)*/	i=0;	while ((route = (GF_Route*)gf_list_enum(proto->sub_graph->Routes, &i))) {		if (route->IS_route) continue;		r2 = gf_sg_route_new(proto_node->sgprivate->scenegraph, 				gf_sg_find_node(proto_node->sgprivate->scenegraph, gf_node_get_id(route->FromNode) ), 				route->FromField.fieldIndex, 				gf_sg_find_node(proto_node->sgprivate->scenegraph, gf_node_get_id(route->ToNode) ), 				route->ToField.fieldIndex);		if (route->ID) gf_sg_route_set_id(r2, route->ID);		if (route->name) gf_sg_route_set_name(r2, route->name);	}	/*activate all ISed fields so that inits on events is properly done*/	i=0;	while ((route = (GF_Route*)gf_list_enum(proto_node->sgprivate->scenegraph->Routes, &i))) {		if (!route->IS_route) continue;		/*do not activate eventIn to eventIn routes*/		if (route->is_setup) {			if ((route->ToField.eventType == GF_SG_EVENT_IN) && (route->FromField.eventType == GF_SG_EVENT_IN) ) continue;		}		gf_sg_route_activate(route);	}	/*and load all scripts (this must be done once all fields are routed for the "initialize" method)*/	while (gf_list_count(proto_node->scripts_to_load)) {		node = (GF_Node*)gf_list_get(proto_node->scripts_to_load, 0);		gf_list_rem(proto_node->scripts_to_load, 0);		gf_sg_script_load(node);	}	/*re-activate all ISed fields pointing to scripts once scripts are loaded (eventIns)*/	i=0;	while ((route = (GF_Route*)gf_list_enum(proto_node->sgprivate->scenegraph->Routes, &i))) {		if (!route->IS_route || !route->ToNode) continue;/*		assert(route->is_setup);		if ((route->FromField.eventType == GF_SG_EVENT_OUT) || (route->FromField.eventType == GF_SG_EVENT_IN) ) continue;*/		if ((route->ToNode->sgprivate->tag==TAG_MPEG4_Script) || (route->ToNode->sgprivate->tag==TAG_X3D_Script) )			gf_sg_route_activate(route);	}	proto_node->is_loaded = 1;}GF_Node *gf_sg_proto_create_node(GF_SceneGraph *scene, GF_Proto *proto, GF_ProtoInstance *from_inst){	u32 i;	GF_ProtoField *inst, *from_field;	GF_ProtoFieldInterface *field;	GF_ProtoInstance *proto_node;	GF_SAFEALLOC(proto_node, GF_ProtoInstance)	if (!proto_node) return NULL;	gf_node_setup((GF_Node *)proto_node, TAG_ProtoNode);	proto_node->node_code = gf_list_new();	proto_node->fields = gf_list_new();	proto_node->scripts_to_load = gf_list_new();	proto_node->proto_interface = proto;	gf_list_add(proto->instances, proto_node);#ifdef GF_NODE_USE_POINTERS	proto_node->sgprivate->node_del = protoinst_del;	proto_node->sgprivate->get_field = protoinst_get_field;	proto_node->sgprivate->get_field_count = gf_sg_proto_get_num_fields;	proto_node->sgprivate->name = strdup(proto->Name);#else	proto_node->proto_name = strdup(proto->Name);#endif	/*create the namespace*/	proto_node->sgprivate->scenegraph = gf_sg_new_subscene(scene);	/*set this proto as owner of the new graph*/	proto_node->sgprivate->scenegraph->pOwningProto = proto_node;	/*instanciate fields*/	i=0;	while ((field = (GF_ProtoFieldInterface*)gf_list_enum(proto->proto_fields, &i))) {		inst = (GF_ProtoField *)malloc(sizeof(GF_ProtoField));		inst->EventType = field->EventType;		inst->FieldType = field->FieldType;		inst->has_been_accessed = 0;		/*this is OK to call on GF_Node (returns NULL) and MFNode (returns gf_list_new() )*/		inst->field_pointer = gf_sg_vrml_field_pointer_new(inst->FieldType);		/*regular field, duplicate from default value or instanciated one if specified (since		a proto may be partially instanciated when used in another proto)*/		if (gf_sg_vrml_get_sf_type(inst->FieldType) != GF_SG_VRML_SFNODE) {			if (from_inst) {				from_field = (GF_ProtoField *)gf_list_get(from_inst->fields, i-1);				gf_sg_vrml_field_copy(inst->field_pointer, from_field->field_pointer, inst->FieldType);			} else {				gf_sg_vrml_field_copy(inst->field_pointer, field->def_value, inst->FieldType);			}		}		/*No default values for SFNodes as interfaces ...*/		gf_list_add(proto_node->fields, inst);	}	return (GF_Node *) proto_node;}GF_Node *gf_sg_proto_create_instance(GF_SceneGraph *sg, GF_Proto *proto){	return gf_sg_proto_create_node(sg, proto, NULL);}GF_Err gf_sg_proto_load_code(GF_Node *node){	GF_ProtoInstance *inst;	if (node->sgprivate->tag != TAG_ProtoNode) return GF_BAD_PARAM;	inst = (GF_ProtoInstance *) node;	if (!inst->proto_interface) return GF_BAD_PARAM;	if (inst->is_loaded) return GF_OK;	gf_sg_proto_instanciate(inst);	return GF_OK;}u32 gf_sg_proto_get_num_fields(GF_Node *node, u8 code_mode){	GF_ProtoInstance *proto;	if (!node) return 0;	proto = (GF_ProtoInstance *)node;	/*watchout for deletion case*/	switch (code_mode) {	case GF_SG_FIELD_CODING_IN: return proto->proto_interface ? proto->proto_interface->NumIn : 0;	case GF_SG_FIELD_CODING_OUT: return proto->proto_interface ? proto->proto_interface->NumOut : 0;	case GF_SG_FIELD_CODING_DEF: return proto->proto_interface ? proto->proto_interface->NumDef : 0;	case GF_SG_FIELD_CODING_ALL: return gf_list_count(proto->proto_interface ? proto->proto_interface->proto_fields : proto->fields);	/*BIFS-ANIM not supported*/	case GF_SG_FIELD_CODING_DYN:	default:		return 0;	}}void gf_sg_proto_del_instance(GF_ProtoInstance *inst){	GF_ProtoField *field;	GF_Node *node;	u32 index;	index = 0;	while (gf_list_count(inst->fields)) {		field = (GF_ProtoField *)gf_list_get(inst->fields, 0);		gf_list_rem(inst->fields, 0);		/*regular type*/		if ( (field->FieldType!=GF_SG_VRML_SFNODE) && (field->FieldType!=GF_SG_VRML_MFNODE)) {			gf_sg_vrml_field_pointer_del(field->field_pointer, field->FieldType);		}		/*node types: delete instances*/		else if (field->field_pointer) {			if (field->FieldType == GF_SG_VRML_SFNODE) {				gf_node_unregister((GF_Node *) field->field_pointer, (GF_Node *) inst);			} else {				GF_ChildNodeItem *list = (GF_ChildNodeItem *)field->field_pointer;				while (list) {					GF_ChildNodeItem *cur = list;					gf_node_unregister(list->node, (GF_Node *) inst);					list = list->next;					free(cur);				}			}		}		free(field);		index++;	}	gf_list_del(inst->fields);	/*destroy the code*/	while (gf_list_count(inst->node_code)) {		node = (GF_Node*)gf_list_get(inst->node_code, 0);		gf_node_unregister(node, (GF_Node*) inst);		gf_list_rem(inst->node_code, 0);	}	gf_list_del(inst->node_code);	assert(!gf_list_count(inst->scripts_to_load));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -