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

📄 commands.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			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 tags (for internal nodes)*/#include <gpac/nodes_mpeg4.h>#include <gpac/nodes_svg_sa.h>#include <gpac/internal/laser_dev.h>GF_Command *gf_sg_command_new(GF_SceneGraph *graph, u32 tag){	GF_Command *ptr;	GF_SAFEALLOC(ptr, GF_Command);	if (!ptr) return NULL;	ptr->tag = tag;	ptr->in_scene = graph;	ptr->command_fields = gf_list_new();	if (tag < GF_SG_LAST_BIFS_COMMAND) ptr->new_proto_list = gf_list_new();	return ptr;}static void SG_CheckNodeUnregister(GF_Command *com){	NodeIDedItem *reg_node;	switch (com->tag) {	case GF_SG_SCENE_REPLACE:	case GF_SG_LSR_NEW_SCENE:	case GF_SG_LSR_REFRESH_SCENE:		gf_node_unregister(com->node, NULL);		break;	default:		/*check if node is in registry - do NOT check the node's internals, because it may have been destroyed		when cyclic references are found (only happens with conditional replacing self/other conditional buffer)		note that we're sure the node has an ID since this is not a replace scene*/		reg_node = com->in_scene->id_node;		while (reg_node) {			if (reg_node->node == com->node) {				gf_node_unregister(com->node, NULL);				return;			}			reg_node = reg_node->next;		}		break;	}}GF_EXPORTvoid gf_sg_command_del(GF_Command *com){	u32 i;	GF_Proto *proto;	if (!com) return;	if (com->tag < GF_SG_LAST_BIFS_COMMAND) {		while (gf_list_count(com->command_fields)) {			GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);			gf_list_rem(com->command_fields, 0);			switch (inf->fieldType) {			case GF_SG_VRML_SFNODE:				if (inf->new_node) gf_node_unregister(inf->new_node, com->node);				break;			case GF_SG_VRML_MFNODE:				if (inf->field_ptr) {					GF_ChildNodeItem *cur, *child;					child = inf->node_list;					while (child) {						cur = child;						gf_node_unregister(child->node, com->node);						child = child->next;						free(cur);					}				}				break;			default:				if (inf->field_ptr) gf_sg_vrml_field_pointer_del(inf->field_ptr, inf->fieldType);				break;			}			free(inf);		}	} else {#ifndef GPAC_DISABLE_SVG		while (gf_list_count(com->command_fields)) {			GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);			gf_list_rem(com->command_fields, 0);			if (inf->new_node) gf_node_unregister(inf->new_node, com->node);			else if (inf->node_list) {				gf_node_unregister_children(com->node, inf->node_list);			} else if (inf->field_ptr) {				gf_svg_delete_attribute_value(inf->fieldType, inf->field_ptr, com->in_scene);			}			free(inf);		}#endif	}	gf_list_del(com->command_fields);	i=0;	while ((proto = (GF_Proto*)gf_list_enum(com->new_proto_list, &i))) {		gf_sg_proto_del(proto);	}	gf_list_del(com->new_proto_list);	if (com->node) {		if (!com->in_scene) gf_node_unregister(com->node, NULL);		else SG_CheckNodeUnregister(com);	}	if (com->del_proto_list) free(com->del_proto_list);	if (com->def_name) free(com->def_name);	if (com->scripts_to_load) gf_list_del(com->scripts_to_load);	free(com);}static void SG_CheckFieldChange(GF_Node *node, GF_FieldInfo *field){	/*and propagate eventIn if any*/	if (field->on_event_in) {		field->on_event_in(node);	} else if ((field->eventType==GF_SG_EVENT_IN) && (gf_node_get_tag(node) == TAG_MPEG4_Script)) {		gf_sg_script_event_in(node, field);	} else {		/*Notify eventOut in all cases to handle protos*/		gf_node_event_out(node, field->fieldIndex);	}	/*signal node modif*/	gf_node_changed(node, field);}static void gf_node_unregister_children_deactivate(GF_Node *container, GF_ChildNodeItem *child){	GF_ChildNodeItem *cur;	while (child) {		gf_node_unregister(child->node, container);		gf_node_deactivate(child->node);		cur = child;		child = child->next;		free(cur);	}}GF_EXPORTGF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset){	GF_Err e;	GF_CommandField *inf;	GF_FieldInfo field;	GF_Node *def, *node;	void *slot_ptr;	if (!com || !graph) return GF_BAD_PARAM;	e = GF_OK;	switch (com->tag) {	case GF_SG_SCENE_REPLACE:		/*unregister root*/		gf_node_unregister(graph->RootNode, NULL);		/*remove all protos and routes*/		while (gf_list_count(graph->routes_to_activate)) 			gf_list_rem(graph->routes_to_activate, 0);				/*destroy all routes*/		while (gf_list_count(graph->Routes)) {			GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0);			/*this will unregister the route from the graph, so don't delete the chain entry*/			gf_sg_route_del(r);		}		/*destroy all proto*/		while (gf_list_count(graph->protos)) {			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);			/*this will unregister the proto from the graph, so don't delete the chain entry*/			gf_sg_proto_del(p);		}		/*DO NOT TOUCH node registry*/		/*DO NOT TOUCH UNREGISTERED PROTOS*/		/*move all protos in graph*/		while (gf_list_count(com->new_proto_list)) {			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);			gf_list_rem(com->new_proto_list, 0);			gf_list_del_item(graph->unregistered_protos, p);			gf_list_add(graph->protos, p);		}		/*assign new root (no need to register/unregister)*/		graph->RootNode = com->node;		com->node = NULL;		break;	case GF_SG_NODE_REPLACE:		if (!gf_list_count(com->command_fields)) return GF_OK;		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);		e = gf_node_replace(com->node, inf->new_node, 0);		if (inf->new_node) gf_node_register(inf->new_node, NULL);		break;	case GF_SG_MULTIPLE_REPLACE:	case GF_SG_FIELD_REPLACE:	{		u32 j;		GF_ChildNodeItem *list, *cur, *prev;		j=0;		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) {			e = gf_node_get_field(com->node, inf->fieldIndex, &field);			if (e) return e;			switch (field.fieldType) {			case GF_SG_VRML_SFNODE:			{				node = *((GF_Node **) field.far_ptr);				e = gf_node_unregister(node, com->node);				*((GF_Node **) field.far_ptr) = inf->new_node;				if (!e) gf_node_register(inf->new_node, com->node);				break;			}			case GF_SG_VRML_MFNODE:				gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr));				* ((GF_ChildNodeItem **) field.far_ptr) = NULL;				list = * ((GF_ChildNodeItem **) inf->field_ptr);				prev=NULL;				while (list) {					cur = malloc(sizeof(GF_ChildNodeItem));					cur->next = NULL;					cur->node = list->node;					if (prev) {						prev->next = cur;					} else {						* ((GF_ChildNodeItem **) field.far_ptr) = cur;					}					gf_node_register(list->node, com->node);					prev = cur;					list = list->next;				}				break;			default:				/*this is a regular field, reset it and clone - we cannot switch pointers since the				original fields are NOT pointers*/				if (!gf_sg_vrml_is_sf_field(field.fieldType)) {					e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType);				}				if (e) return e;				gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType);				if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset;				break;			}			SG_CheckFieldChange(com->node, &field);		}		break;	}	case GF_SG_MULTIPLE_INDEXED_REPLACE:	case GF_SG_INDEXED_REPLACE:	{		u32 sftype, i=0;		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) {			e = gf_node_get_field(com->node, inf->fieldIndex, &field);			if (e) return e;			/*if MFNode remove the child and set new node*/			if (field.fieldType == GF_SG_VRML_MFNODE) {				/*we must remove the node before in case the new node uses the same ID (not forbidden) and this				command removes the last instance of the node with the same ID*/				gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node);				if (inf->new_node) gf_node_register(inf->new_node, NULL);			}			/*erase the field item*/			else {				if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {					inf->pos = ((GenMFField *)field.far_ptr)->count - 1;					/*may happen with text and default value*/					if (inf->pos < 0) {						inf->pos = 0;						gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1);					}				}				e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);				if (e) return e;				sftype = gf_sg_vrml_get_sf_type(field.fieldType);				gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);				/*note we don't add time offset, since there's no MFTime*/			}			SG_CheckFieldChange(com->node, &field);		}		break;	}	case GF_SG_ROUTE_REPLACE:	{		GF_Route *r;		char *name;		r = gf_sg_route_find(graph, com->RouteID);		def = gf_sg_find_node(graph, com->fromNodeID);		node = gf_sg_find_node(graph, com->toNodeID);		if (!node || !def) return GF_SG_UNKNOWN_NODE;		name = NULL;		if (r) {			name = r->name;			r->name = NULL;			gf_sg_route_del(r);		}		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);		gf_sg_route_set_id(r, com->RouteID);		if (name) {			gf_sg_route_set_name(r, name);			free(name);		}		break;	}	case GF_SG_NODE_DELETE_EX:	case GF_SG_NODE_DELETE:	{		if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0);		break;	}	case GF_SG_ROUTE_DELETE:	{		return gf_sg_route_del_by_id(graph, com->RouteID);	}	case GF_SG_INDEXED_DELETE:	{		if (!gf_list_count(com->command_fields)) return GF_OK;		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);		e = gf_node_get_field(com->node, inf->fieldIndex, &field);		if (e) return e;		if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;		/*then we need special handling in case of a node*/		if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) {			e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL);		} else {			if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {				inf->pos = ((GenMFField *)field.far_ptr)->count - 1;			}			/*this is a regular MFField, just remove the item (realloc)*/			e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos);		}		/*deletion -> node has changed*/		if (!e) SG_CheckFieldChange(com->node, &field);		break;	}	case GF_SG_NODE_INSERT:	{		if (!gf_list_count(com->command_fields)) return GF_OK;		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);		e = gf_node_insert_child(com->node, inf->new_node, inf->pos);		if (!e) gf_node_register(inf->new_node, com->node);		if (!e) gf_node_event_out(com->node, inf->fieldIndex);		if (!e) gf_node_changed(com->node, NULL);		break;	}	case GF_SG_ROUTE_INSERT:	{		GF_Route *r;		def = gf_sg_find_node(graph, com->fromNodeID);		node = gf_sg_find_node(graph, com->toNodeID);		if (!node || !def) return GF_SG_UNKNOWN_NODE;		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);		if (com->RouteID) gf_sg_route_set_id(r, com->RouteID);		if (com->def_name) {

⌨️ 快捷键说明

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