- const char *rootPath(const char *name)
- {
- return GlobalFileSystem().findRoot(
- path_is_absolute(name)
- ? name
- : GlobalFileSystem().findFile(name)
- );
- }
-}
-
-struct ModelResource : public Resource {
- NodeSmartReference m_model;
- const CopiedString m_originalName;
- CopiedString m_path;
- CopiedString m_name;
- CopiedString m_type;
- ModelLoader *m_loader;
- ModuleObservers m_observers;
- std::time_t m_modified;
- std::size_t m_unrealised;
-
- ModelResource(const CopiedString &name) :
- m_model(g_nullModel),
- m_originalName(name),
- m_type(path_get_extension(name.c_str())),
- m_loader(0),
- m_modified(0),
- m_unrealised(1)
- {
- m_loader = ModelLoader_forType(m_type.c_str());
-
- if (g_realised) {
- 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;
- }
-
- void loadCached()
- {
- if (g_modelCache_enabled) {
- // cache lookup
- ModelCache::iterator i = ModelCache_find(m_path.c_str(), m_name.c_str());
- if (i == g_modelCache.end()) {
- i = ModelCache_insert(
- m_path.c_str(),
- m_name.c_str(),
- Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str())
- );
- }
-
- setModel((*i).value);
- } else {
- setModel(Model_load(m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str()));
- }
- }
-
- void loadModel()
- {
- loadCached();
- connectMap();
- mapSave();
- }
-
- bool load()
- {
- ASSERT_MESSAGE(realised(), "resource not realised");
- if (m_model == g_nullModel) {
- loadModel();
- }
-
- return m_model != g_nullModel;
- }
-
- bool save()
- {
- if (!mapSaved()) {
- const char *moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), m_type.c_str());
- if (string_not_empty(moduleName)) {
- const MapFormat *format = ReferenceAPI_getMapModules().findModule(moduleName);
- if (format != 0 && MapResource_save(*format, m_model.get(), m_path.c_str(), m_name.c_str())) {
- mapSave();
- return true;
- }
- }
- }
- return false;
- }
-
- void flush()
- {
- if (realised()) {
- ModelCache_flush(m_path.c_str(), m_name.c_str());
- }
- }
-
- scene::Node *getNode()
- {
- //if(m_model != g_nullModel)
- {
- return m_model.get_pointer();
- }
- //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()) {
- (*i).value = NodeSmartReference(*node);
- }
- setModel(NodeSmartReference(*node));
-
- 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) {
- m_path = rootPath(m_originalName.c_str());
- m_name = path_make_relative(m_originalName.c_str(), m_path.c_str());
-
- //globalOutputStream() << "ModelResource::realise: " << m_path.c_str() << m_name.c_str() << "\n";
-
- m_observers.realise();
- }
- }
-
- void unrealise()
- {
- if (++m_unrealised == 1) {
- m_observers.unrealise();
-
- //globalOutputStream() << "ModelResource::unrealise: " << m_path.c_str() << m_name.c_str() << "\n";
- clearModel();
- }
- }
-
- bool isMap() const
- {
- return Node_getMapFile(m_model) != 0;
- }
-
- void connectMap()
- {
- MapFile *map = Node_getMapFile(m_model);
- if (map != 0) {
- 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);
- if (map != 0) {
- map->save();
- }
- }
-
- bool mapSaved() const
- {
- MapFile *map = Node_getMapFile(m_model);
- if (map != 0) {
- return m_modified == modified() && map->saved();
- }
- 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();
- unrealise();
- realise();
- }
- }
+const char* rootPath( const char* name ){
+ return GlobalFileSystem().findRoot(
+ path_is_absolute( name )
+ ? name
+ : GlobalFileSystem().findFile( name )
+ );
+}
+}
+
+struct ModelResource : public Resource
+{
+ NodeSmartReference m_model;
+ const CopiedString m_originalName;
+ CopiedString m_path;
+ CopiedString m_name;
+ CopiedString m_type;
+ ModelLoader* m_loader;
+ ModuleObservers m_observers;
+ std::time_t m_modified;
+ std::size_t m_unrealised;
+
+ ModelResource( const CopiedString& name ) :
+ m_model( g_nullModel ),
+ m_originalName( name ),
+ m_type( path_get_extension( name.c_str() ) ),
+ m_loader( 0 ),
+ m_modified( 0 ),
+ m_unrealised( 1 ){
+ m_loader = ModelLoader_forType( m_type.c_str() );
+
+ if ( g_realised ) {
+ 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;
+ }
+
+ void loadCached(){
+ if ( g_modelCache_enabled ) {
+ // cache lookup
+ ModelCache::iterator i = ModelCache_find( m_path.c_str(), m_name.c_str() );
+ if ( i == g_modelCache.end() ) {
+ i = ModelCache_insert(
+ m_path.c_str(),
+ m_name.c_str(),
+ Model_load( m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str() )
+ );
+ }
+
+ setModel( ( *i ).value );
+ }
+ else
+ {
+ setModel( Model_load( m_loader, m_path.c_str(), m_name.c_str(), m_type.c_str() ) );
+ }
+ }
+
+ void loadModel(){
+ loadCached();
+ connectMap();
+ mapSave();
+ }
+
+ bool load(){
+ ASSERT_MESSAGE( realised(), "resource not realised" );
+ if ( m_model == g_nullModel ) {
+ loadModel();
+ }
+
+ return m_model != g_nullModel;
+ }
+
+ bool save(){
+ if ( !mapSaved() ) {
+ const char* moduleName = findModuleName( GetFileTypeRegistry(), MapFormat::Name(), m_type.c_str() );
+ if ( string_not_empty( moduleName ) ) {
+ const MapFormat* format = ReferenceAPI_getMapModules().findModule( moduleName );
+ if ( format != 0 && MapResource_save( *format, m_model.get(), m_path.c_str(), m_name.c_str() ) ) {
+ mapSave();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void flush(){
+ if ( realised() ) {
+ ModelCache_flush( m_path.c_str(), m_name.c_str() );
+ }
+ }
+
+ scene::Node* getNode(){
+ //if(m_model != g_nullModel)
+ {
+ return m_model.get_pointer();
+ }
+ //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() ) {
+ ( *i ).value = NodeSmartReference( *node );
+ }
+ setModel( NodeSmartReference( *node ) );
+
+ 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 ) {
+ m_path = rootPath( m_originalName.c_str() );
+ m_name = path_make_relative( m_originalName.c_str(), m_path.c_str() );
+
+ //globalOutputStream() << "ModelResource::realise: " << m_path.c_str() << m_name.c_str() << "\n";
+
+ m_observers.realise();
+ }
+ }
+
+ void unrealise(){
+ if ( ++m_unrealised == 1 ) {
+ m_observers.unrealise();
+
+ //globalOutputStream() << "ModelResource::unrealise: " << m_path.c_str() << m_name.c_str() << "\n";
+ clearModel();
+ }
+ }
+
+ bool isMap() const {
+ return Node_getMapFile( m_model ) != 0;
+ }
+
+ void connectMap(){
+ MapFile* map = Node_getMapFile( m_model );
+ if ( map != 0 ) {
+ 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 );
+ if ( map != 0 ) {
+ map->save();
+ }
+ }
+
+ bool mapSaved() const {
+ MapFile* map = Node_getMapFile( m_model );
+ if ( map != 0 ) {
+ return m_modified == modified() && map->saved();
+ }
+ 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();
+ unrealise();
+ realise();
+ }
+ }