X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Freferencecache.cpp;h=9ceeba1bc78fe0e0578d2d3ec97dca2459afa951;hb=8da2e32d53f927833ee0e74010c7165349096bdf;hp=ee3ab8061e17f4a16201458e6b66d641cfb4eef0;hpb=7fc621fc78d0e040dc2c12f38dc53dd9048215dc;p=xonotic%2Fnetradiant.git diff --git a/radiant/referencecache.cpp b/radiant/referencecache.cpp index ee3ab806..9ceeba1b 100644 --- a/radiant/referencecache.cpp +++ b/radiant/referencecache.cpp @@ -20,6 +20,7 @@ */ #include "referencecache.h" +#include "globaldefs.h" #include "debugging/debugging.h" @@ -27,9 +28,13 @@ #include "iselection.h" #include "iundo.h" #include "imap.h" + MapModules& ReferenceAPI_getMapModules(); + #include "imodel.h" + ModelModules& ReferenceAPI_getModelModules(); + #include "ifilesystem.h" #include "iarchive.h" #include "ifiletypes.h" @@ -54,6 +59,7 @@ ModelModules& ReferenceAPI_getModelModules(); #include "map.h" #include "filetypes.h" +extern bool g_writeMapComments; bool References_Saved(); @@ -105,7 +111,7 @@ bool MapResource_saveFile( const MapFormat& format, scene::Node& root, GraphTrav if ( !file.failed() ) { globalOutputStream() << "success\n"; ScopeDisableScreenUpdates disableScreenUpdates( path_get_filename_start( filename ), "Saving Map" ); - format.writeGraph( root, traverse, file ); + format.writeGraph( root, traverse, file, g_writeMapComments ); return true; } @@ -206,7 +212,7 @@ NodeSmartReference ModelResource_load( ModelLoader* loader, const char* name ){ inline hash_t path_hash( const char* path, hash_t previous = 0 ){ -#if defined( WIN32 ) +#if GDEF_OS_WINDOWS return string_hash_nocase( path, previous ); #else // UNIX return string_hash( path, previous ); @@ -223,6 +229,7 @@ struct PathEqual struct PathHash { typedef hash_t hash_type; + hash_type operator()( const CopiedString& path ) const { return path_hash( path.c_str() ); } @@ -240,6 +247,7 @@ struct ModelKeyEqual struct ModelKeyHash { typedef hash_t hash_type; + hash_type operator()( const ModelKey& key ) const { return hash_combine( path_hash( key.first.c_str() ), path_hash( key.second.c_str() ) ); } @@ -344,20 +352,24 @@ struct ModelResource : public Resource realise(); } } + ~ModelResource(){ if ( realised() ) { unrealise(); } ASSERT_MESSAGE( !realised(), "ModelResource::~ModelResource: resource reference still realised: " << makeQuoted( m_name.c_str() ) ); } + // NOT COPYABLE ModelResource( const ModelResource& ); + // NOT ASSIGNABLE ModelResource& operator=( const ModelResource& ); void setModel( const NodeSmartReference& model ){ m_model = model; } + void clearModel(){ m_model = g_nullModel; } @@ -396,6 +408,7 @@ struct ModelResource : public Resource return m_model != g_nullModel; } + bool save(){ if ( !mapSaved() ) { const char* moduleName = findModuleName( GetFileTypeRegistry(), MapFormat::Name(), m_type.c_str() ); @@ -409,11 +422,13 @@ struct ModelResource : public Resource } return false; } + void flush(){ if ( realised() ) { ModelCache_flush( m_path.c_str(), m_name.c_str() ); } } + scene::Node* getNode(){ //if(m_model != g_nullModel) { @@ -421,6 +436,7 @@ struct ModelResource : public Resource } //return 0; } + void setNode( scene::Node* node ){ ModelCache::iterator i = ModelCache_find( m_path.c_str(), m_name.c_str() ); if ( i != g_modelCache.end() ) { @@ -430,21 +446,25 @@ struct ModelResource : public Resource connectMap(); } + void attach( ModuleObserver& observer ){ if ( realised() ) { observer.realise(); } m_observers.attach( observer ); } + void detach( ModuleObserver& observer ){ if ( realised() ) { observer.unrealise(); } m_observers.detach( observer ); } + bool realised(){ return m_unrealised == 0; } + void realise(){ ASSERT_MESSAGE( m_unrealised != 0, "ModelResource::realise: already realised" ); if ( --m_unrealised == 0 ) { @@ -456,6 +476,7 @@ struct ModelResource : public Resource m_observers.realise(); } } + void unrealise(){ if ( ++m_unrealised == 1 ) { m_observers.unrealise(); @@ -464,20 +485,24 @@ struct ModelResource : public Resource clearModel(); } } + bool isMap() const { return Node_getMapFile( m_model ) != 0; } + void connectMap(){ MapFile* map = Node_getMapFile( m_model ); if ( map != 0 ) { - map->setChangedCallback( FreeCaller() ); + map->setChangedCallback( makeCallbackF(MapChanged) ); } } + std::time_t modified() const { StringOutputStream fullpath( 256 ); fullpath << m_path.c_str() << m_name.c_str(); return file_modified( fullpath.c_str() ); } + void mapSave(){ m_modified = modified(); MapFile* map = Node_getMapFile( m_model ); @@ -485,6 +510,7 @@ struct ModelResource : public Resource map->save(); } } + bool mapSaved() const { MapFile* map = Node_getMapFile( m_model ); if ( map != 0 ) { @@ -492,11 +518,13 @@ struct ModelResource : public Resource } return true; } + bool isModified() const { return ( ( !string_empty( m_path.c_str() ) // had or has an absolute path && m_modified != modified() ) // AND disk timestamp changed || !path_equal( rootPath( m_originalName.c_str() ), m_path.c_str() ) ); // OR absolute vfs-root changed } + void refresh(){ if ( isModified() ) { flush(); @@ -519,6 +547,7 @@ typedef std::list Iterators; Iterators m_iterators; public: typedef Iterators::iterator iterator; + ModelReferencesSnapshot( ModelReferences& references ) : m_references( references ){ for ( ModelReferences::iterator i = m_references.begin(); i != m_references.end(); ++i ) { @@ -526,15 +555,18 @@ ModelReferencesSnapshot( ModelReferences& references ) : m_references( reference m_iterators.push_back( i ); } } + ~ModelReferencesSnapshot(){ for ( Iterators::iterator i = m_iterators.begin(); i != m_iterators.end(); ++i ) { m_references.release( *i ); } } + iterator begin(){ return m_iterators.begin(); } + iterator end(){ return m_iterators.end(); } @@ -550,6 +582,7 @@ HashtableReferenceCache() : m_unrealised( 1 ){ iterator begin(){ return m_references.begin(); } + iterator end(){ return m_references.end(); } @@ -562,6 +595,7 @@ Resource* capture( const char* path ){ //globalOutputStream() << "capture: \"" << path << "\"\n"; return m_references.capture( CopiedString( path ) ).get(); } + void release( const char* path ){ m_references.release( CopiedString( path ) ); //globalOutputStream() << "release: \"" << path << "\"\n"; @@ -574,6 +608,7 @@ void setEntityCreator( EntityCreator& entityCreator ){ bool realised() const { return m_unrealised == 0; } + void realise(){ ASSERT_MESSAGE( m_unrealised != 0, "HashtableReferenceCache::realise: already realised" ); if ( --m_unrealised == 0 ) { @@ -591,6 +626,7 @@ void realise(){ } } } + void unrealise(){ if ( ++m_unrealised == 1 ) { g_realised = false; @@ -609,6 +645,7 @@ void unrealise(){ ModelCache_clear(); } } + void refresh(){ ModelReferencesSnapshot snapshot( m_references ); for ( ModelReferencesSnapshot::iterator i = snapshot.begin(); i != snapshot.end(); ++i ) @@ -691,9 +728,11 @@ ReferenceDependencies() : m_map_modules( GlobalRadiant().getRequiredGameDescriptionKeyValue( "maptypes" ) ) { } + ModelModules& getModelModules(){ return m_model_modules.get(); } + MapModules& getMapModules(){ return m_map_modules.get(); } @@ -704,6 +743,7 @@ class ReferenceAPI : public TypeSystemRef ReferenceCache* m_reference; public: typedef ReferenceCache Type; + STRING_CONSTANT( Name, "*" ); ReferenceAPI(){ @@ -713,11 +753,13 @@ ReferenceAPI(){ m_reference = &GetReferenceCache(); } + ~ReferenceAPI(){ GlobalFileSystem().detach( g_referenceCache ); g_nullModel = g_nullNode; } + ReferenceCache* getTable(){ return m_reference; } @@ -730,6 +772,7 @@ StaticRegisterModule staticRegisterReference( StaticReferenceModule::instance() ModelModules& ReferenceAPI_getModelModules(){ return StaticReferenceModule::instance().getDependencies().getModelModules(); } + MapModules& ReferenceAPI_getMapModules(){ return StaticReferenceModule::instance().getDependencies().getMapModules( ); }