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

📄 vrml_route.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Scene Graph sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/scenegraph_dev.h>/*MPEG4 & X3D tags (for node tables & script handling)*/#include <gpac/nodes_mpeg4.h>#include <gpac/nodes_x3d.h>GF_EXPORTGF_Route *gf_sg_route_new(GF_SceneGraph *sg, GF_Node *fromNode, u32 fromField, GF_Node *toNode, u32 toField){	GF_Route *r;	if (!sg || !toNode || !fromNode) return NULL;	GF_SAFEALLOC(r, GF_Route)	if (!r) return NULL;	r->FromNode = fromNode;	r->FromField.fieldIndex = fromField;	r->ToNode = toNode;	r->ToField.fieldIndex = toField;	r->graph = sg;	if (!fromNode->sgprivate->interact) GF_SAFEALLOC(fromNode->sgprivate->interact, struct _node_interactive_ext);	if (!fromNode->sgprivate->interact->events) fromNode->sgprivate->interact->events = gf_list_new();	gf_list_add(fromNode->sgprivate->interact->events, r);	gf_list_add(sg->Routes, r);	return r;}void gf_sg_route_del(GF_Route *r){	GF_SceneGraph *sg;	s32 ind;	gf_sg_route_unqueue(r->graph, r);	/*remove declared routes*/	ind = gf_list_del_item(r->graph->Routes, r);	/*remove route from node*/	if (r->FromNode && r->FromNode->sgprivate->interact && r->FromNode->sgprivate->interact->events) {		gf_list_del_item(r->FromNode->sgprivate->interact->events, r);		if (!gf_list_count(r->FromNode->sgprivate->interact->events)) {			gf_list_del(r->FromNode->sgprivate->interact->events);			r->FromNode->sgprivate->interact->events = NULL;		}	}	r->is_setup = 0;	sg = r->graph;	while (sg->parent_scene) sg = sg->parent_scene;	gf_list_add(sg->routes_to_destroy, r);}GF_Err gf_sg_route_del_by_id(GF_SceneGraph *sg,u32 routeID){	GF_Route *r;	if(!sg) return GF_BAD_PARAM;	r = gf_sg_route_find(sg, routeID);	if (!r) return GF_BAD_PARAM;	gf_sg_route_del(r);	return GF_OK;}GF_Route *gf_sg_route_find(GF_SceneGraph *sg, u32 RouteID){	GF_Route *r;	u32 i=0;	while ((r = (GF_Route*)gf_list_enum(sg->Routes, &i))) {		if (r->ID == RouteID) return r;	}	return NULL;}GF_Route *gf_sg_route_find_by_name(GF_SceneGraph *sg, char *name){	GF_Route *r;	u32 i;	if (!sg || !name) return NULL;	i=0;	while ((r = (GF_Route*)gf_list_enum(sg->Routes, &i))) {		if (r->name && !strcmp(r->name, name)) return r;	}	return NULL;}GF_Err gf_sg_route_set_id(GF_Route *route, u32 ID){	GF_Route *ptr;	if (!route || !ID) return GF_BAD_PARAM;	ptr = gf_sg_route_find(route->graph, ID);	if (ptr) return GF_BAD_PARAM;	route->ID = ID;	return GF_OK;}u32 gf_sg_route_get_id(GF_Route *route) {	return route->ID;}GF_Err gf_sg_route_set_name(GF_Route *route, char *name){	GF_Route *ptr;	if (!name || !route) return GF_BAD_PARAM;	ptr = gf_sg_route_find_by_name(route->graph, name);	if (ptr) return GF_BAD_PARAM;	if (route->name) free(route->name);	route->name = strdup(name);	return GF_OK;}char *gf_sg_route_get_name(GF_Route *route){	return route->name;}static void gf_sg_route_setup(GF_Route *r) {	gf_node_get_field(r->FromNode, r->FromField.fieldIndex, &r->FromField);	gf_node_get_field(r->ToNode, r->ToField.fieldIndex, &r->ToField);	r->is_setup = 1;}Bool gf_sg_route_activate(GF_Route *r){	Bool ret;	/*URL/String conversion clone*/	void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type);	if (!r->is_setup) {		gf_sg_route_setup(r);		/*special case when initing ISed routes on eventOuts: skip*/		if (r->IS_route) {			if (r->FromField.eventType == GF_SG_EVENT_OUT) return 0;		}	}#ifndef GPAC_DISABLE_LOG	if (r->IS_route) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[VRML Event] executing %s.%s IS %s.%s\n", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name));	} else {		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[VRML Event] executing ROUTE %s.%s TO %s.%s\n", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name));	}#endif	ret = 1;	switch (r->FromField.fieldType) {	case GF_SG_VRML_SFNODE:		if (* (GF_Node **) r->ToField.far_ptr != * (GF_Node **) r->FromField.far_ptr) {			GF_Node *n = * (GF_Node **) r->ToField.far_ptr;			/*delete instance*/			if (n) gf_node_unregister(n, r->ToNode);			/*and use the node*/			* (GF_Node **) r->ToField.far_ptr = * (GF_Node **) r->FromField.far_ptr;			n = * (GF_Node **) r->FromField.far_ptr;			gf_node_register(n, r->ToNode);		}		break;	/*move all pointers to dest*/	case GF_SG_VRML_MFNODE:	{		GF_ChildNodeItem *last = NULL;		GF_ChildNodeItem *orig = *(GF_ChildNodeItem **)r->FromField.far_ptr;		/*empty list*/		gf_node_unregister_children(r->ToNode, *(GF_ChildNodeItem **)r->ToField.far_ptr );		*(GF_ChildNodeItem **)r->ToField.far_ptr = NULL;		while (orig) {			gf_node_list_add_child_last( (GF_ChildNodeItem **)r->ToField.far_ptr, orig->node, &last);			gf_node_register(orig->node, r->ToNode);			orig = orig->next;		}	}		break;	default:		if (r->ToField.fieldType==r->FromField.fieldType) {			/*if unchanged don't invalidate dst node*/			if (gf_sg_vrml_field_equal(r->ToField.far_ptr, r->FromField.far_ptr, r->FromField.fieldType)) {				ret = 0;			} else {				gf_sg_vrml_field_copy(r->ToField.far_ptr, r->FromField.far_ptr, r->FromField.fieldType);			}		} 		/*typecast URL <-> string if needed*/		else {			VRML_FieldCopyCast(r->ToField.far_ptr, r->ToField.fieldType, r->FromField.far_ptr, r->FromField.fieldType);		}		break;	}	//if this is a supported eventIn call watcher	if (r->ToField.on_event_in) {		r->ToField.on_event_in(r->ToNode);	}	//if this is a script eventIn call directly script	else if (((r->ToNode->sgprivate->tag==TAG_MPEG4_Script) || (r->ToNode->sgprivate->tag==TAG_X3D_Script) ) 		&& ((r->ToField.eventType==GF_SG_EVENT_IN) /*|| (r->ToField.eventType==GF_SG_EVENT_FIELD)*/) ) {		gf_sg_script_event_in(r->ToNode, &r->ToField);	}	//check if ISed or not - this will notify the node of any changes	else {		gf_sg_proto_check_field_change(r->ToNode, r->ToField.fieldIndex);		/*only happen on proto, an eventOut may route to an eventOut*/		if (r->IS_route && r->ToField.eventType==GF_SG_EVENT_OUT) 			gf_node_event_out(r->ToNode, r->ToField.fieldIndex);	}	/*and signal routes on exposed fields if field changed*/	if (r->ToField.eventType == GF_SG_EVENT_EXPOSED_FIELD)		gf_node_event_out(r->ToNode, r->ToField.fieldIndex);	return ret;}void gf_node_event_out(GF_Node *node, u32 FieldIndex){	u32 i;	GF_Route *r;	if (!node) return;		//this is not an ISed	if (!(node->sgprivate->flags & GF_NODE_IS_DEF) && !node->sgprivate->scenegraph->pOwningProto) return;	if (!node->sgprivate->interact) return;		//search for routes to activate in the order they where declared	i=0;	while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->events, &i))) {		if (r->FromNode != node) continue;		if (r->FromField.fieldIndex != FieldIndex) continue;		/*no postpone for IS routes*/		if (r->IS_route) {			if (gf_sg_route_activate(r)) 				gf_node_changed(r->ToNode, &r->ToField);		}		//queue		else {			gf_sg_route_queue(node->sgprivate->scenegraph, r);		}	}}GF_EXPORTvoid gf_node_event_out_str(GF_Node *node, const char *eventName){	u32 i;	GF_Route *r;	/*node is being deleted ignore event*/	if (!node->sgprivate->interact) return;	//this is not an ISed	if (!(node->sgprivate->flags & GF_NODE_IS_DEF) && !node->sgprivate->scenegraph->pOwningProto) return;		//search for routes to activate in the order they where declared	i=0;	while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->events, &i))) {		if (!r->is_setup) gf_sg_route_setup(r);		if (stricmp(r->FromField.name, eventName)) continue;		//no postpone		if (r->IS_route) {			gf_sg_route_activate(r);		}		//queue		else {			gf_sg_route_queue(node->sgprivate->scenegraph, r);		}	}}

⌨️ 快捷键说明

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