Fix resource manager not properly accounting for overrides
This commit is contained in:
@@ -118,6 +118,7 @@
|
||||
<ClCompile Include="..\..\tools\menu_accel.win.cpp" />
|
||||
<ClCompile Include="..\..\tools\porting.cpp" />
|
||||
<ClCompile Include="..\..\tools\prefs.win.cpp" />
|
||||
<ClCompile Include="..\..\tools\resmgr\restypes.cpp" />
|
||||
<ClCompile Include="..\..\tools\soundtool.cpp" />
|
||||
<ClCompile Include="..\..\tools\specials_parse.cpp" />
|
||||
<ClCompile Include="..\..\tools\tarball.cpp" />
|
||||
|
@@ -333,6 +333,9 @@
|
||||
<ClCompile Include="..\..\tools\porting.cpp">
|
||||
<Filter>Tools\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tools\resmgr\restypes.cpp">
|
||||
<Filter>Tools\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tools\soundtool.cpp">
|
||||
<Filter>Tools\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@@ -137,6 +137,7 @@
|
||||
91870F84190C90980081C150 /* scenedit.xib in Resources */ = {isa = PBXBuildFile; fileRef = 914CA49F190C4E9200B6ADD1 /* scenedit.xib */; };
|
||||
919145FC18E3AB1B005CF3A4 /* boe.appleevents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 919145FB18E3A32F005CF3A4 /* boe.appleevents.mm */; };
|
||||
9192C12018F2745C0088A580 /* game.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9192C11E18F271920088A580 /* game.xib */; };
|
||||
91960ED41BB6157A008AF8F4 /* restypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91960ED31BB613E5008AF8F4 /* restypes.cpp */; };
|
||||
919CC2481B3772F300273FDA /* creatlist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC620A0FA2853700EEAE67 /* creatlist.cpp */; };
|
||||
919CC2491B3772FB00273FDA /* creature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914698FE1A747C4500F20F5E /* creature.cpp */; };
|
||||
919CC24B1B37730300273FDA /* item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279D3D0F9D1D6A007B0D52 /* item.cpp */; };
|
||||
@@ -657,6 +658,7 @@
|
||||
9191460018E63D8E005CF3A4 /* scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scrollbar.cpp; sourceTree = "<group>"; };
|
||||
9191460118E6591F005CF3A4 /* boe.menus.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = boe.menus.hpp; sourceTree = "<group>"; };
|
||||
9192C11E18F271920088A580 /* game.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = game.xib; path = ../rsrc/menus/game.xib; sourceTree = "<group>"; };
|
||||
91960ED31BB613E5008AF8F4 /* restypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = restypes.cpp; sourceTree = "<group>"; };
|
||||
919DDBFA19006CC9003E7FED /* libboost_filesystem.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libboost_filesystem.dylib; path = /usr/local/lib/libboost_filesystem.dylib; sourceTree = "<absolute>"; };
|
||||
919DDBFB19006CC9003E7FED /* libboost_system.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libboost_system.dylib; path = /usr/local/lib/libboost_system.dylib; sourceTree = "<absolute>"; };
|
||||
919DDC091900750D003E7FED /* freetype.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = freetype.framework; path = ../../../../../../Library/Frameworks/freetype.framework; sourceTree = "<group>"; };
|
||||
@@ -999,6 +1001,7 @@
|
||||
children = (
|
||||
912DFE8918E24B4C00B00D75 /* resmgr.hpp */,
|
||||
912DFE8A18E24B4C00B00D75 /* restypes.hpp */,
|
||||
91960ED31BB613E5008AF8F4 /* restypes.cpp */,
|
||||
);
|
||||
path = resmgr;
|
||||
sourceTree = "<group>";
|
||||
@@ -1788,6 +1791,7 @@
|
||||
919CC27D1B37743700273FDA /* tarball.cpp in Sources */,
|
||||
919CC27E1B37743B00273FDA /* undo.cpp in Sources */,
|
||||
919CC27F1B37744000273FDA /* winutil.mac.mm in Sources */,
|
||||
91960ED41BB6157A008AF8F4 /* restypes.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@@ -23,7 +23,9 @@
|
||||
/// Resources include sounds, images, fonts, and cursors.
|
||||
///
|
||||
/// To implement a new resource type, all you have to do is specialize
|
||||
/// @a ResMgr::resLoader::operator() for the desired resource type.
|
||||
/// @a ResMgr::resLoader::operator() and declare @a ResMgr::resLoader::file_ext
|
||||
/// for the desired resource type. The operator() receives the
|
||||
/// full file path with the extension already applied.
|
||||
namespace ResMgr {
|
||||
namespace fs = boost::filesystem;
|
||||
/// The signature of an ID map function.
|
||||
@@ -56,12 +58,13 @@ namespace ResMgr {
|
||||
/// Convert a relative path to an absolute path by checking the current search path stack.
|
||||
/// @param path The path to resolve.
|
||||
/// @return The resolved absolute path, or the relative path unchanged if resolution failed.
|
||||
static fs::path rel2abs(fs::path path) {
|
||||
static fs::path find(std::string name, std::string ext) {
|
||||
fs::path path = name + "." + ext;
|
||||
std::stack<fs::path> tmpPaths = resPaths();
|
||||
while(!tmpPaths.empty()) {
|
||||
fs::path thisPath = tmpPaths.top()/path;
|
||||
if(fs::exists(thisPath)) {
|
||||
pathFound()[path] = tmpPaths.top();
|
||||
pathFound()[name] = thisPath;
|
||||
return thisPath;
|
||||
}
|
||||
tmpPaths.pop();
|
||||
@@ -78,10 +81,12 @@ namespace ResMgr {
|
||||
/// @tparam type The type of resource.
|
||||
template<typename type> struct resLoader {
|
||||
/// Load a resource of this type from the given file.
|
||||
/// @param fname The path to the resource; this will be an absolute path unless resolution failed.
|
||||
/// @param fpath The path to the resource; this will be an absolute path unless resolution failed.
|
||||
/// @return A pointer to the loaded resource. The resource manager takes responsibility for freeing it,
|
||||
/// so it must be a pointer allocated with `new` rather than `new[]`.
|
||||
type* operator() (std::string fname);
|
||||
type* operator() (fs::path path);
|
||||
/// The standard file extension for this resource type;
|
||||
static const std::string file_ext;
|
||||
};
|
||||
|
||||
/// Thrown if an error occurs while loading a resource.
|
||||
@@ -131,19 +136,19 @@ namespace ResMgr {
|
||||
template<typename type> std::shared_ptr<type> get(std::string name) {
|
||||
if(resPool<type>::resources().find(name) != resPool<type>::resources().end()) {
|
||||
if(resPool<type>::pathFound().find(name) != resPool<type>::pathFound().end()) {
|
||||
resLoader<type> load;
|
||||
std::string curPath = resPool<type>::pathFound()[name].string();
|
||||
std::string checkPath = resPool<type>::rel2abs(name).string();
|
||||
checkPath = checkPath.substr(0,curPath.length());
|
||||
std::string checkPath = resPool<type>::find(name, load.file_ext).string();
|
||||
if(checkPath != curPath) {
|
||||
free<type>(name);
|
||||
return get<type>(name);
|
||||
type* tmp = load(checkPath);
|
||||
return resPool<type>::resources()[name] = std::shared_ptr<type>(tmp);
|
||||
}
|
||||
}
|
||||
return resPool<type>::resources()[name];
|
||||
} else {
|
||||
type* tmp;
|
||||
resLoader<type> load;
|
||||
tmp = load(name);
|
||||
type* tmp = load(resPool<type>::find(name, load.file_ext));
|
||||
return resPool<type>::resources()[name] = std::shared_ptr<type>(tmp);
|
||||
}
|
||||
}
|
||||
|
17
src/tools/resmgr/restypes.cpp
Normal file
17
src/tools/resmgr/restypes.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// restypes.cpp
|
||||
// BoE
|
||||
//
|
||||
// Created by Celtic Minstrel on 15-09-25.
|
||||
//
|
||||
//
|
||||
|
||||
#include "restypes.hpp"
|
||||
|
||||
namespace ResMgr {
|
||||
template<> const std::string resLoader<ImageRsrc>::file_ext = "png";
|
||||
template<> const std::string resLoader<CursorRsrc>::file_ext = "gif";
|
||||
template<> const std::string resLoader<FontRsrc>::file_ext = "ttf";
|
||||
template<> const std::string resLoader<StringRsrc>::file_ext = "txt";
|
||||
template<> const std::string resLoader<SoundRsrc>::file_ext = "wav";
|
||||
}
|
@@ -33,8 +33,7 @@ extern std::ostream& std_fmterr(std::ostream& out);
|
||||
|
||||
namespace ResMgr {
|
||||
/// Load an image from a PNG file.
|
||||
template<> inline ImageRsrc* resLoader<ImageRsrc>::operator() (std::string fname) {
|
||||
fs::path fpath = resPool<ImageRsrc>::rel2abs(fname + ".png");
|
||||
template<> inline ImageRsrc* resLoader<ImageRsrc>::operator() (fs::path fpath) {
|
||||
ImageRsrc* img = new ImageRsrc();
|
||||
if(img->loadFromFile(fpath.string())) return img;
|
||||
delete img;
|
||||
@@ -44,10 +43,9 @@ namespace ResMgr {
|
||||
/// Load a cursor from a GIF file.
|
||||
/// The cursor's hotspot location is stored in a GIF comment, with the following syntax (case-sensitive):
|
||||
/// "Hotspot(x,y)"
|
||||
template<> inline CursorRsrc* resLoader<CursorRsrc>::operator() (std::string fname) {
|
||||
fs::path fpath = resPool<CursorRsrc>::rel2abs(fname + ".gif");
|
||||
template<> inline CursorRsrc* resLoader<CursorRsrc>::operator() (fs::path fpath) {
|
||||
if(!fs::exists(fpath))
|
||||
throw xResMgrErr("Failed to load GIF cursor: " + fname);
|
||||
throw xResMgrErr("Failed to load GIF cursor: " + fpath.string());
|
||||
int x = 0, y = 0, f_sz;
|
||||
std::ifstream fin(fpath.c_str(), std::ios::binary);
|
||||
fin.seekg(0, std::ios::end);
|
||||
@@ -83,19 +81,16 @@ namespace ResMgr {
|
||||
}
|
||||
}
|
||||
if(!found_hotspot)
|
||||
std::cerr << "Cursor hotspot missing: " << fname << std::endl;
|
||||
std::cerr << "Cursor hotspot missing: " << fpath.string() << std::endl;
|
||||
// TODO: Handle errors?
|
||||
CursorRsrc* cur = new Cursor(fpath.string(),x,y);
|
||||
return cur;
|
||||
}
|
||||
|
||||
/// Load a font from a TTF file.
|
||||
template<> inline FontRsrc* resLoader<FontRsrc>::operator() (std::string fname) {
|
||||
fs::path fpath = resPool<FontRsrc>::rel2abs(fname + ".ttf");
|
||||
template<> inline FontRsrc* resLoader<FontRsrc>::operator() (fs::path fpath) {
|
||||
FontRsrc* theFont = new FontRsrc;
|
||||
if(theFont->loadFromFile(fpath.string())) return theFont;
|
||||
fpath = resPool<FontRsrc>::rel2abs(fname + ".otf");
|
||||
if(theFont->loadFromFile(fpath.string())) return theFont;
|
||||
delete theFont;
|
||||
throw xResMgrErr("Failed to find font: " + fpath.string());
|
||||
}
|
||||
@@ -103,8 +98,7 @@ namespace ResMgr {
|
||||
/// Load a list of strings from a TXT file.
|
||||
/// Each line in the file becomes one string in the resulting list.
|
||||
/// (Empty lines are included too.)
|
||||
template<> inline StringRsrc* resLoader<StringRsrc>::operator() (std::string fname) {
|
||||
fs::path fpath = resPool<StringRsrc>::rel2abs(fname + ".txt");
|
||||
template<> inline StringRsrc* resLoader<StringRsrc>::operator() (fs::path fpath) {
|
||||
std::ifstream fin(fpath.c_str());
|
||||
if(fin.fail()) {
|
||||
std::cerr << std_fmterr << ": Error opening file";
|
||||
@@ -120,8 +114,7 @@ namespace ResMgr {
|
||||
}
|
||||
|
||||
/// Load a sound from a WAV file.
|
||||
template<> inline SoundRsrc* resLoader<SoundRsrc>::operator() (std::string fname) {
|
||||
fs::path fpath = resPool<SoundRsrc>::rel2abs(fname + ".wav");
|
||||
template<> inline SoundRsrc* resLoader<SoundRsrc>::operator() (fs::path fpath) {
|
||||
SoundRsrc* snd = new SoundRsrc;
|
||||
if(snd->loadFromFile(fpath.string())) return snd;
|
||||
delete snd;
|
||||
|
Reference in New Issue
Block a user