From b2d34e0367a1a1ce6a5156a5c9e48da6a7ea1aa4 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Wed, 4 Jul 2012 14:28:32 -0500 Subject: [PATCH] support versioning the project template and triggering regeneration of the user project --- radiant/mainframe.cpp | 14 +++++++++++--- radiant/qe3.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++ radiant/qe3.h | 2 ++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 17fcedf7..c4e46151 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -3638,6 +3638,7 @@ void MainFrame::CreateQEChildren(){ char buf[PATH_MAX]; const char *r; bool bTriedTemplate = false; + int templateVersion = 0; if ( g_PrefsDlg.m_nLastProjectVer != 0 && g_PrefsDlg.m_nLastProjectVer != PROJECT_VERSION ) { // we need to regenerate from template @@ -3645,9 +3646,17 @@ void MainFrame::CreateQEChildren(){ g_PrefsDlg.m_strLastProject = ""; } + + // check to see if the project template is versioned + strcpy( buf, g_pGameDescription->mEnginePath.GetBuffer() ); + strcat( buf, g_pGameDescription->mBaseGame.GetBuffer() ); + strcat( buf, "/scripts/" ); + strcat( buf, PROJECT_TEMPLATE_NAME ); + templateVersion = QE_GetTemplateVersionForProject( buf ); + r = g_PrefsDlg.m_strLastProject.GetBuffer(); - while ( r == NULL || *r == '\0' || access( r, R_OK ) != 0 || !QE_LoadProject( r ) ) + while ( r == NULL || *r == '\0' || access( r, R_OK ) != 0 || !QE_LoadProject( r ) || templateVersion != IntForKey( g_qeglobals.d_project_entity, "template_version" ) ) { if ( !bTriedTemplate ) { // try default project location @@ -3666,8 +3675,7 @@ void MainFrame::CreateQEChildren(){ filename = file_dialog( m_pWidget, TRUE, _( "Choose Project File" ), buf, "project" ); if ( filename != NULL ) { r = filename; - } - else{ + } else { Error( "Cannot continue without loading a project..." ); } } diff --git a/radiant/qe3.cpp b/radiant/qe3.cpp index 16025d05..42497dbd 100644 --- a/radiant/qe3.cpp +++ b/radiant/qe3.cpp @@ -472,6 +472,50 @@ void ReplaceTemplates( char* w, const char* r ){ *w = '\0'; } +/* +Load up a project file to get the current version + */ +int QE_GetTemplateVersionForProject( const char * projectfile ) { + xmlDocPtr doc; + xmlNodePtr node, project; + int ret; + + Sys_Printf( "Scanning template version in %s\n", projectfile ); + doc = ParseXMLFile( projectfile, true ); + if ( doc == NULL ) { + Sys_FPrintf( SYS_ERR, "ERROR: XML parse failed %s\n", projectfile ); + return 0; + } + node = doc->children; + while ( node != NULL && node->type != XML_DTD_NODE ) { + node = node->next; + } + if ( node == NULL || strcmp( (char*)node->name, "project" ) != 0 ) { + Sys_FPrintf( SYS_ERR, "ERROR: invalid file type %s\n", projectfile ); + xmlFree( doc ); + return 0; + } + while ( node->type != XML_ELEMENT_NODE ) { + node = node->next; + } + // + project = node; + + for ( node = project->children; node != NULL; node = node->next ) { + if ( node->type != XML_ELEMENT_NODE ) { + continue; + } + if ( strcmp( (char*)node->properties->children->content, "template_version" ) == 0 ) { + ret = atoi( (char*)node->properties->next->children->content ); + xmlFreeDoc( doc ); + return ret; + } + } + Sys_FPrintf( SYS_WRN, "Version key not found in %s\n", projectfile ); + xmlFreeDoc( doc ); + return 0; +} + /* =========== QE_LoadProject diff --git a/radiant/qe3.h b/radiant/qe3.h index abdd39ce..7dc45262 100644 --- a/radiant/qe3.h +++ b/radiant/qe3.h @@ -337,6 +337,8 @@ qboolean QE_KeyDown( int key, int nFlags = 0 ); // does some sanity checks on the project entity, such as removing ending filename seperators from paths // (this usually gets propagated to the actual project file since most of the time we save right after calling the check) void QE_CheckProjectEntity(); +// peek in a project file to retrieve the version key +int QE_GetTemplateVersionForProject( const char * projectfile ); // this will load a new project entity in memory, and potentially process it from a template // NOTE TTimo calling QE_LoadProject won't take care of the various initialisation that are performed depending on the project settings // you should then call QE_Init for that