Status ReloadChangedFile(const VfsPath& path) { // Ignore files that aren't in the right path if (!boost::algorithm::starts_with(path.string(), L"art/skeletons/")) return INFO::OK; if (path.Extension() != L".xml") return INFO::OK; m_skeletonHashInvalidated = true; // If the file doesn't exist (e.g. it was deleted), don't bother reloading // or 'unloading' since that isn't possible if (!VfsFileExists(path)) return INFO::OK; if (!dll.IsLoaded() && !TryLoadDLL()) return ERR::FAIL; LOGMESSAGE("Hotloading skeleton definitions from '%s'", path.string8()); // Set the filename for the logger to report set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&path))); CVFSFile skeletonFile; if (skeletonFile.Load(m_VFS, path) != PSRETURN_OK) { LOGERROR("Failed to read skeleton defintions from '%s'", path.string8()); return ERR::FAIL; } int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); if (ok < 0) { LOGERROR("Failed to load skeleton definitions from '%s'", path.string8()); return ERR::FAIL; } return INFO::OK; }
bool LoadSkeletonDefinitions() { VfsPaths pathnames; if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L"*.xml", pathnames) < 0) { LOGERROR("No skeleton definition files present"); return false; } bool loaded = false; for (const VfsPath& path : pathnames) { LOGMESSAGE("Loading skeleton definitions from '%s'", path.string8()); // Set the filename for the logger to report set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&path))); CVFSFile skeletonFile; if (skeletonFile.Load(m_VFS, path) != PSRETURN_OK) { LOGERROR("Failed to read skeleton defintions from '%s'", path.string8()); continue; } int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); if (ok < 0) { LOGERROR("Failed to load skeleton definitions from '%s'", path.string8()); continue; } loaded = true; } if (!loaded) LOGERROR("Failed to load any skeleton definitions"); return loaded; }
bool Convert(const VfsPath& daeFilename, const VfsPath& pmdFilename, CColladaManager::FileType type) { // To avoid always loading the DLL when it's usually not going to be // used (and to do the same on Linux where delay-loading won't help), // and to avoid compile-time dependencies (because it's a minor pain // to get all the right libraries to build the COLLADA DLL), we load // it dynamically when it is required, instead of using the exported // functions and binding at link-time. if (! dll.IsLoaded()) { if (! dll.LoadDLL()) { LOGERROR(L"Failed to load COLLADA conversion DLL"); return false; } try { dll.LoadSymbol("set_logger", set_logger); dll.LoadSymbol("set_skeleton_definitions", set_skeleton_definitions); dll.LoadSymbol("convert_dae_to_pmd", convert_dae_to_pmd); dll.LoadSymbol("convert_dae_to_psa", convert_dae_to_psa); } catch (PSERROR_DllLoader&) { LOGERROR(L"Failed to load symbols from COLLADA conversion DLL"); dll.Unload(); return false; } VfsPath skeletonPath("art/skeletons/skeletons.xml"); // Set the filename for the logger to report set_logger(ColladaLog, static_cast<void*>(&skeletonPath)); CVFSFile skeletonFile; if (skeletonFile.Load(g_VFS, skeletonPath) != PSRETURN_OK) { LOGERROR(L"Failed to read skeleton definitions"); dll.Unload(); return false; } int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); if (ok < 0) { LOGERROR(L"Failed to load skeleton definitions"); dll.Unload(); return false; } // TODO: the cached PMD/PSA files should probably be invalidated when // the skeleton definition file is changed, else people will get confused // as to why it's not picking up their changes } // Set the filename for the logger to report set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&daeFilename))); // We need to null-terminate the buffer, so do it (possibly inefficiently) // by converting to a CStr CStr daeData; { CVFSFile daeFile; if (daeFile.Load(g_VFS, daeFilename) != PSRETURN_OK) return false; daeData = daeFile.GetAsString(); } // Do the conversion into a memory buffer WriteBuffer writeBuffer; switch (type) { case CColladaManager::PMD: convert_dae_to_pmd(daeData.c_str(), ColladaOutput, &writeBuffer); break; case CColladaManager::PSA: convert_dae_to_psa(daeData.c_str(), ColladaOutput, &writeBuffer); break; } // don't create zero-length files (as happens in test_invalid_dae when // we deliberately pass invalid XML data) because the VFS caching // logic warns when asked to load such. if (writeBuffer.Size()) { Status ret = g_VFS->CreateFile(pmdFilename, writeBuffer.Data(), writeBuffer.Size()); ENSURE(ret == INFO::OK); } return true; }