📄 main.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / X3D Scene Graph Generator 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 <stdlib.h>#include <stdio.h>#include <string.h>#include <gpac/list.h>#include <time.h>#define COPYRIGHT "/*\n * GPAC - Multimedia Framework C SDK\n *\n * Copyright (c) Jean Le Feuvre 2000-2005\n * All rights reserved\n *\n * This file is part of GPAC / X3D Scene Graph sub-project\n *\n * GPAC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2, or (at your option)\n * any later version.\n *\n * GPAC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details. \n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; see the file COPYING. If not, write to\n * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"static char *CurrentLine;void PrintUsage(){ printf("X3DGen [skip_file]\n" "\nGPAC X3D Scene Graph generator\n" "\n" "\nskip_file: txt file with list of nodes to leave unimplemented" "Generated Files are directly updated in the GPAC distribution - do NOT try to change this\n\n" "Written by Jean Le Feuvre - (c) 2000-2005\n" );}//a node fieldtypedef struct{ char type[50]; //SFxxx, MFxxx char familly[50]; //name char name[1000]; //default value char def[100]; //bounds u32 hasBounds; char b_min[20]; char b_max[20];} X3DField;//NDTs//a BIFS nodetypedef struct{ char name[1000]; //NDT info. NDT are created in alphabetical order GF_List *NDT; GF_List *Fields; u8 hasDefault; char Child_NDT_Name[1000]; u8 skip_impl;} X3DNode;void skip_sep(char *sep){ //skip separaors while (*CurrentLine && strchr(sep, *CurrentLine)) { CurrentLine = CurrentLine + 1; //end of line - no token if (*CurrentLine == '\n') return; }}//note that we increment the line no matter whatu32 GetNextToken(char *token, char *sep){ u32 i , j = 0; strcpy(token, ""); //skip separaors while (*CurrentLine && strchr(sep, *CurrentLine)) { CurrentLine = CurrentLine + 1; j ++; //end of line - no token if (*CurrentLine == '\n') return 0; } //copy token untill next blank i=0; while (1) { //bad line if (! *CurrentLine) { token[i] = 0; return 0; } //end of token or end of line if (strchr(sep, *CurrentLine) || (*CurrentLine == '\n') ) { token[i] = 0; CurrentLine = CurrentLine + 1; return i; } else { token[i] = *CurrentLine; } CurrentLine = CurrentLine + 1; i++; j++; } return 1;}X3DField *BlankField(){ X3DField *n = malloc(sizeof(X3DField)); memset(n, 0, sizeof(X3DField)); return n;}X3DNode *BlankNode(){ X3DNode *n = malloc(sizeof(X3DNode)); memset(n, 0, sizeof(X3DNode)); n->NDT = gf_list_new(); n->Fields = gf_list_new(); return n;}u8 IsNDT(GF_List *NDTs, char *famName){ u32 i; char *ndtName; for (i=0; i<gf_list_count(NDTs); i++) { ndtName = gf_list_get(NDTs, i); //remove SF / MF as we don't need that if (!strcmp(ndtName+2, famName+2)) return 1; } return 0;}void CheckInTable(char *token, GF_List *NDTs){ u32 i; char *p; for (i=0; i<gf_list_count(NDTs); i++) { p = gf_list_get(NDTs, i); if (!strcmp(p, token)) return; } p = malloc(strlen(token)+1); strcpy(p, token); gf_list_add(NDTs, p);}/*type: 0: header, 1: source*/FILE *BeginFile(u32 type){ FILE *f; char sPath[GF_MAX_PATH]; if (!type) { sprintf(sPath, "..%c..%c..%cinclude%cgpac%cnodes_x3d.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR); } else { sprintf(sPath, "..%c..%c..%csrc%cscenegraph%cx3d_nodes.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR); } f = fopen(sPath, "wt"); fprintf(f, "%s\n", COPYRIGHT); { time_t rawtime; time(&rawtime); fprintf(f, "\n/*\n\tDO NOT MOFIFY - File generated on GMT %s\n\tBY X3DGen for GPAC Version %s\n*/\n\n", asctime(gmtime(&rawtime)), GPAC_VERSION); } if (!type) { fprintf(f, "#ifndef _GF_X3D_NODES_H\n"); fprintf(f, "#define _GF_X3D_NODES_H\n\n"); fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"); } return f;}void EndFile(FILE *f, u32 type){ if (!type) { fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n"); fprintf(f, "\n\n#endif\t\t/*_GF_X3D_NODES_H*/\n\n"); } fclose(f);}void TranslateToken(char *token){ if (!strcmp(token, "+I") || !strcmp(token, "I")) { strcpy(token, "GF_MAX_FLOAT"); } else if (!strcmp(token, "-I")) { strcpy(token, "GF_MIN_FLOAT"); }}void WriteNodesFile(GF_List *BNodes, GF_List *NDTs){ FILE *f; u32 i, j; X3DNode *n; X3DField *bf; f = BeginFile(0); fprintf(f, "#include <gpac/scenegraph_vrml.h>\n\n"); //write all tags fprintf(f, "\n\nenum {\n"); for (i=0; i<gf_list_count(BNodes); i++) { n = gf_list_get(BNodes, i); if (i) fprintf(f, ",\n\tTAG_X3D_%s", n->name); else fprintf(f, "\tTAG_X3D_%s = GF_NODE_RANGE_FIRST_X3D", n->name); } fprintf(f, ",\n\tTAG_LastImplementedX3D\n};\n\n"); for (i=0; i<gf_list_count(BNodes); i++) { n = gf_list_get(BNodes, i); if (n->skip_impl) continue; fprintf(f, "typedef struct _tagX3D%s\n{\n", n->name); fprintf(f, "\tBASE_NODE\n"); /*write children field*/ for (j=0; j<gf_list_count(n->Fields); j++) { bf = gf_list_get(n->Fields, j); if (!stricmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue; if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) { fprintf(f, "\tVRML_CHILDREN\n"); break; } } for (j=0; j<gf_list_count(n->Fields); j++) { bf = gf_list_get(n->Fields, j); if (!strcmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue; if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) continue; if (strstr(bf->familly, "Node")) { //this is a POINTER to a node if (strstr(bf->familly, "SF")) { fprintf(f, "\tGF_Node *%s;\t/*%s*/\n", bf->name, bf->type); } else { //this is a POINTER to a chain fprintf(f, "\tGF_ChildNodeItem *%s;\t/*%s*/\n", bf->name, bf->type); } } else { fprintf(f, "\t%s %s;\t/*%s*/\n", bf->familly, bf->name, bf->type); } if (!strcmp(bf->type, "eventIn")) fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis);\t/*eventInHandler*/\n", bf->name); } fprintf(f, "} X_%s;\n\n\n", n->name); } EndFile(f, 0);}void WriteNodeFields(FILE *f, X3DNode *n){ u32 i; X3DField *bf; fprintf(f, "\nstatic u32 %s_get_field_count(GF_Node *node, u8 dummy)\n{\n\treturn %d;\n}\n\n", n->name, gf_list_count(n->Fields)); fprintf(f, "static GF_Err %s_get_field(GF_Node *node, GF_FieldInfo *info)\n{\n\tswitch (info->fieldIndex) {\n", n->name); for (i=0;i<gf_list_count(n->Fields); i++) { bf = gf_list_get(n->Fields, i); fprintf(f, "\tcase %d:\n", i); fprintf(f, "\t\tinfo->name = \"%s\";\n", bf->name); //skip all eventIn if (!strcmp(bf->type, "eventIn")) { fprintf(f, "\t\tinfo->eventType = GF_SG_EVENT_IN;\n"); fprintf(f, "\t\tinfo->on_event_in = ((X_%s *)node)->on_%s;\n", n->name, bf->name); } else if (!strcmp(bf->type, "eventOut")) { fprintf(f, "\t\tinfo->eventType = GF_SG_EVENT_OUT;\n"); } else if (!strcmp(bf->type, "field")) { fprintf(f, "\t\tinfo->eventType = GF_SG_EVENT_FIELD;\n"); } else { fprintf(f, "\t\tinfo->eventType = GF_SG_EVENT_EXPOSED_FIELD;\n"); } if (strstr(bf->familly, "Node")) { if (strstr(bf->familly, "MF")) { fprintf(f, "\t\tinfo->fieldType = GF_SG_VRML_MFNODE;\n"); } else { fprintf(f, "\t\tinfo->fieldType = GF_SG_VRML_SFNODE;\n"); } //always remove the SF or MF, as all NDTs are SFXXX fprintf(f, "\t\tinfo->NDTtype = NDT_SF%s;\n", bf->familly+2); fprintf(f, "\t\tinfo->far_ptr = & ((X_%s *)node)->%s;\n", n->name, bf->name); } else { char szName[20]; strcpy(szName, bf->familly); strupr(szName); //no ext type fprintf(f, "\t\tinfo->fieldType = GF_SG_VRML_%s;\n", szName); fprintf(f, "\t\tinfo->far_ptr = & ((X_%s *) node)->%s;\n", n->name, bf->name); } fprintf(f, "\t\treturn GF_OK;\n"); } fprintf(f, "\tdefault:\n\t\treturn GF_BAD_PARAM;\n\t}\n}\n\n"); fprintf(f, "\nstatic s32 %s_get_field_index_by_name(char *name)\n{\n", n->name); for (i=0;i<gf_list_count(n->Fields); i++) { bf = gf_list_get(n->Fields, i); fprintf(f, "\tif (!strcmp(\"%s\", name)) return %d;\n", bf->name, i); } fprintf(f, "\treturn -1;\n\t}\n");}void WriteNodeCode(GF_List *BNodes, FILE *vrml_code){ char token[20], tok[20]; char *store; u32 i, j, k, go; X3DField *bf; X3DNode *n; fprintf(vrml_code, "\n#include <gpac/nodes_x3d.h>\n"); fprintf(vrml_code, "\n#include <gpac/internal/scenegraph_dev.h>\n"); fprintf(vrml_code, "\n/*for NDT tag definitions*/\n#include <gpac/nodes_mpeg4.h>\n"); for (k=0; k<gf_list_count(BNodes); k++) { n = gf_list_get(BNodes, k); if (n->skip_impl) continue; fprintf(vrml_code, "\n/*\n\t%s Node deletion\n*/\n\n", n->name); fprintf(vrml_code, "static void %s_Del(GF_Node *node)\n{\n\tX_%s *p = (X_%s *) node;\n", n->name, n->name, n->name); for (i=0; i<gf_list_count(n->Fields); i++) { bf = gf_list_get(n->Fields, i); //nothing on child events if (!strcmp(bf->name, "addChildren")) continue; if (!strcmp(bf->name, "removeChildren")) continue; //delete all children node if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) { fprintf(vrml_code, "\tgf_sg_vrml_parent_destroy(node);\t\n"); continue; } //delete ALL fields that must be deleted: this includes eventIn and out since //all fields are defined in the node if (!strcmp(bf->familly, "MFInt") || !strcmp(bf->familly, "MFFloat") || !strcmp(bf->familly, "MFDouble") || !strcmp(bf->familly, "MFBool") || !strcmp(bf->familly, "MFInt32") || !strcmp(bf->familly, "MFColor") || !strcmp(bf->familly, "MFRotation") || !strcmp(bf->familly, "MFString") || !strcmp(bf->familly, "MFTime") || !strcmp(bf->familly, "MFVec2f") || !strcmp(bf->familly, "MFVec3f") || !strcmp(bf->familly, "MFVec4f") || !strcmp(bf->familly, "MFVec2d") || !strcmp(bf->familly, "MFVec3d") || !strcmp(bf->familly, "MFURL") || !strcmp(bf->familly, "MFScript") || !strcmp(bf->familly, "SFString") || !strcmp(bf->familly, "SFURL") || !strcmp(bf->familly, "SFImage") ) { char szName[500]; strcpy(szName, bf->familly); strlwr(szName); fprintf(vrml_code, "\tgf_sg_%s_del(p->%s);\n", szName, bf->name); } else if (strstr(bf->familly, "Node")) { //this is a POINTER to a node if (strstr(bf->familly, "SF")) { fprintf(vrml_code, "\tgf_node_unregister((GF_Node *) p->%s, node);\t\n", bf->name); } else { //this is a POINTER to a chain fprintf(vrml_code, "\tgf_node_unregister_children(node, p->%s);\t\n", bf->name); } } } /*avoids gcc warnings in case no field to delete*/ fprintf(vrml_code, "\tgf_node_free((GF_Node *)p);\n}\n\n"); //node fields WriteNodeFields(vrml_code, n); // // Constructor // fprintf(vrml_code, "\n\nstatic GF_Node *%s_Create()\n{\n\tX_%s *p;\n\tGF_SAFEALLOC(p, X_%s);\n", n->name, n->name, n->name); fprintf(vrml_code, "\tif(!p) return NULL;\n"); fprintf(vrml_code, "\tgf_node_setup((GF_Node *)p, TAG_X3D_%s);\n", n->name); for (i=0; i<gf_list_count(n->Fields); i++) { bf = gf_list_get(n->Fields, i); //setup all children node if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) { fprintf(vrml_code, "\tgf_sg_vrml_parent_setup((GF_Node *) p);\n"); break; } else if ( strstr(bf->familly, "Node") && strncmp(bf->type, "event", 5) ) { //this is a POINTER to a node if (strstr(bf->familly, "MF")) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -