1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Merge pull request #180 from Zyx-2000/FileInfo

Refactored CFileInfo & ResourceID
This commit is contained in:
ArseniyShestakov 2016-02-08 04:55:39 +03:00
commit 890ae43f55
29 changed files with 336 additions and 468 deletions

View File

@ -1,7 +1,6 @@
#include "StdInc.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/filesystem/CFileInfo.h"
#include "SDL.h"
#include "SDL_image.h"
#include "CBitmapHandler.h"

View File

@ -2,7 +2,6 @@
#include "CPreGame.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/filesystem/CFileInfo.h"
#include "../lib/filesystem/CCompressedStream.h"
#include "../lib/CStopWatch.h"

View File

@ -2,7 +2,7 @@
#include "../lib/NetPacks.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/filesystem/CFileInfo.h"
#include "../lib/filesystem/FileInfo.h"
#include "../CCallback.h"
#include "Client.h"
#include "CPlayerInterface.h"
@ -636,8 +636,8 @@ void BattleSetActiveStack::applyCl( CClient *cl )
PlayerColor playerToCall; //player that will move activated stack
if( activated->hasBonusOfType(Bonus::HYPNOTIZED) )
{
playerToCall = ( GS(cl)->curB->sides[0].color == activated->owner
? GS(cl)->curB->sides[1].color
playerToCall = ( GS(cl)->curB->sides[0].color == activated->owner
? GS(cl)->curB->sides[1].color
: GS(cl)->curB->sides[0].color );
}
else
@ -803,12 +803,12 @@ void YourTurn::applyCl( CClient *cl )
void SaveGame::applyCl(CClient *cl)
{
CFileInfo info(fname);
CResourceHandler::get("local")->createResource(info.getStem() + ".vcgm1");
const auto stem = FileInfo::GetPathStem(fname);
CResourceHandler::get("local")->createResource(stem.to_string() + ".vcgm1");
try
{
CSaveFile save(*CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::CLIENT_SAVEGAME)));
CSaveFile save(*CResourceHandler::get()->getResourceName(ResourceID(stem.to_string(), EResType::CLIENT_SAVEGAME)));
cl->saveCommonState(save);
save << *cl;
}

View File

@ -70,12 +70,11 @@
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-overloaded-virtual" />
<Add option="-fpermissive" />
<Add option="-isystem $(#boost.include)" />
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add option="-DBOOST_SYSTEM_NO_DEPRECATED" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add option="-D_WIN32" />
<Add directory="$(#boost.include)" />
<Add directory="../include" />
<Add directory="../client" />
<Add directory="$(#ffmpeg.include)" />
<Add directory="$(#sdl2.include)" />

View File

@ -51,11 +51,11 @@ class CompImageLoader
ui8 *position;
ui8 *entry;
ui32 currentLine;
inline ui8 typeOf(ui8 color);
inline void NewEntry(ui8 color, size_t size);
inline void NewEntry(const ui8 * &data, size_t size);
public:
//load size raw pixels from data
inline void Load(size_t size, const ui8 * data);
@ -75,29 +75,26 @@ class CFileCache
static const int cacheSize = 50; //Max number of cached files
struct FileData
{
ResourceID name;
size_t size;
ui8 * data;
ResourceID name;
size_t size;
std::unique_ptr<ui8[]> data;
ui8 * getCopy()
std::unique_ptr<ui8[]> getCopy()
{
auto ret = new ui8[size];
std::copy(data, data + size, ret);
auto ret = std::unique_ptr<ui8[]>(new ui8[size]);
std::copy(data.get(), data.get() + size, ret.get());
return ret;
}
FileData():
size(0),
data(nullptr)
FileData(ResourceID name_, size_t size_, std::unique_ptr<ui8[]> data_):
name{std::move(name_)},
size{size_},
data{std::move(data_)}
{}
~FileData()
{
delete [] data;
}
};
std::list<FileData> cache;
std::deque<FileData> cache;
public:
ui8 * getCachedFile(ResourceID && rid)
std::unique_ptr<ui8[]> getCachedFile(ResourceID rid)
{
for(auto & file : cache)
{
@ -107,12 +104,10 @@ public:
// Still here? Cache miss
if (cache.size() > cacheSize)
cache.pop_front();
cache.push_back(FileData());
auto data = CResourceHandler::get()->load(rid)->readAll();
cache.back().name = ResourceID(rid);
cache.back().size = data.second;
cache.back().data = data.first.release();
cache.emplace_back(std::move(rid), data.second, std::move(data.first));
return cache.back().getCopy();
}
@ -142,15 +137,15 @@ CDefFile::CDefFile(std::string Name):
};
data = animationCache.getCachedFile(ResourceID(std::string("SPRITES/") + Name, EResType::ANIMATION));
palette = new SDL_Color[256];
palette = std::unique_ptr<SDL_Color[]>(new SDL_Color[256]);
int it = 0;
ui32 type = read_le_u32(data + it);
ui32 type = read_le_u32(data.get() + it);
it+=4;
//int width = read_le_u32(data + it); it+=4;//not used
//int height = read_le_u32(data + it); it+=4;
it+=8;
ui32 totalBlocks = read_le_u32(data + it);
ui32 totalBlocks = read_le_u32(data.get() + it);
it+=4;
for (ui32 i= 0; i<256; i++)
@ -161,15 +156,15 @@ CDefFile::CDefFile(std::string Name):
palette[i].a = SDL_ALPHA_OPAQUE;
}
if (type == 71 || type == 64)//Buttons/buildings don't have shadows\semi-transparency
memset(palette, 0, sizeof(SDL_Color)*2);
memset(palette.get(), 0, sizeof(SDL_Color)*2);
else
memcpy(palette, H3Palette, sizeof(SDL_Color)*8);//initialize shadow\selection colors
memcpy(palette.get(), H3Palette, sizeof(SDL_Color)*8);//initialize shadow\selection colors
for (ui32 i=0; i<totalBlocks; i++)
{
size_t blockID = read_le_u32(data + it);
size_t blockID = read_le_u32(data.get() + it);
it+=4;
size_t totalEntries = read_le_u32(data + it);
size_t totalEntries = read_le_u32(data.get() + it);
it+=12;
//8 unknown bytes - skipping
@ -178,7 +173,7 @@ CDefFile::CDefFile(std::string Name):
for (ui32 j=0; j<totalEntries; j++)
{
size_t currOffset = read_le_u32(data + it);
size_t currOffset = read_le_u32(data.get() + it);
offset[blockID].push_back(currOffset);
it += 4;
}
@ -192,7 +187,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
it = offset.find(group);
assert (it != offset.end());
const ui8 * FDef = data+it->second[frame];
const ui8 * FDef = data.get()+it->second[frame];
const SSpriteDef sd = * reinterpret_cast<const SSpriteDef *>(FDef);
SSpriteDef sprite;
@ -210,7 +205,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
loader.init(Point(sprite.width, sprite.height),
Point(sprite.leftMargin, sprite.topMargin),
Point(sprite.fullWidth, sprite.fullHeight), palette);
Point(sprite.fullWidth, sprite.fullHeight), palette.get());
switch (sprite.format)
{
@ -321,11 +316,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
}
};
CDefFile::~CDefFile()
{
delete[] data;
delete[] palette;
}
CDefFile::~CDefFile() = default;
const std::map<size_t, size_t > CDefFile::getEntries() const
{
@ -355,10 +346,10 @@ void SDLImageLoader::init(Point SpriteSize, Point Margins, Point FullSize, SDL_C
image->fullSize = FullSize;
//Prepare surface
SDL_Palette * p = SDL_AllocPalette(256);
SDL_Palette * p = SDL_AllocPalette(256);
SDL_SetPaletteColors(p, pal, 0, 256);
SDL_SetSurfacePalette(image->surf, p);
SDL_FreePalette(p);
SDL_FreePalette(p);
SDL_LockSurface(image->surf);
lineStart = position = (ui8*)image->surf->pixels;
@ -396,14 +387,14 @@ SDLImageLoader::~SDLImageLoader()
}
////////////////////////////////////////////////////////////////////////////////
CompImageLoader::CompImageLoader(CompImage * Img):
image(Img),
position(nullptr),
entry(nullptr),
currentLine(0)
{
}
void CompImageLoader::init(Point SpriteSize, Point Margins, Point FullSize, SDL_Color *pal)
@ -451,7 +442,7 @@ inline ui8 CompImageLoader::typeOf(ui8 color)
if (image->palette[color].a != 255)
return 1;
return 2;
}
@ -489,7 +480,7 @@ inline void CompImageLoader::Load(size_t size, const ui8 * data)
ui8 type = typeOf(color);
ui8 color2;
ui8 type2;
if (size > 1)
{
do
@ -632,7 +623,7 @@ SDLImage::SDLImage(std::string filename, bool compressed):
{
CSDL_Ext::setColorKey(temp,temp->format->palette->colors[0]);
}
SDL_SetSurfaceRLE(temp, SDL_RLEACCEL);
SDL_SetSurfaceRLE(temp, SDL_RLEACCEL);
// convert surface to enable RLE
surf = SDL_ConvertSurface(temp, temp->format, temp->flags);
@ -680,7 +671,7 @@ CompImage::CompImage(const CDefFile *data, size_t frame, size_t group):
surf(nullptr),
line(nullptr),
palette(nullptr)
{
CompImageLoader loader(this);
data->loadFrame(frame, group, loader);
@ -738,7 +729,7 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 alph
currX = 0;
ui8 bpp = where->format->BytesPerPixel;
//Calculate position for blitting: pixels + Y + X
ui8* blitPos = (ui8*) where->pixels;
if (rotation & 4)
@ -769,7 +760,7 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 alph
void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const
{
assert(bpp>1 && bpp<5);
if (rotated)
switch (bpp)
{
@ -817,7 +808,7 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
//Put row of RGBA data
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, palette[*(data++)]);
}
}
//RLE-d sequence
@ -831,7 +822,7 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
return;
}
switch (palette[type].a)
{
case 0:
@ -958,7 +949,7 @@ bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
else //load from separate file
{
std::string filename = source[group][frame].Struct().find("file")->second.String();
IImage * img = getFromExtraDef(filename);
if (!img)
img = new SDLImage(filename, compressed);
@ -1183,7 +1174,7 @@ void CAnimation::getAnimInfo()
logGlobal->errorStream()<<"Animation stats: Loaded "<<loadedAnims.size()<<" total";
for (auto anim : loadedAnims)
{
logGlobal->errorStream()<<"Name: "<<anim->name<<" Groups: "<<anim->images.size();
if (!anim->images.empty())
logGlobal->errorStream()<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
@ -1202,12 +1193,12 @@ void CFadeAnimation::update()
{
if (!fading)
return;
if (fadingMode == EMode::OUT)
fadingCounter -= delta;
else
fadingCounter += delta;
if (isFinished())
{
fading = false;
@ -1236,7 +1227,7 @@ CFadeAnimation::CFadeAnimation()
CFadeAnimation::~CFadeAnimation()
{
if (fadingSurface && shouldFreeSurface)
SDL_FreeSurface(fadingSurface);
SDL_FreeSurface(fadingSurface);
}
void CFadeAnimation::init(EMode mode, SDL_Surface * sourceSurface, bool freeSurfaceAtEnd /* = false */, float animDelta /* = DEFAULT_DELTA */)
@ -1247,17 +1238,17 @@ void CFadeAnimation::init(EMode mode, SDL_Surface * sourceSurface, bool freeSurf
// (alternatively, we could just return here to ignore the new fade request until this one finished (but we'd need to free the passed bitmap to avoid leaks))
logGlobal->warnStream() << "Tried to init fading animation that is already running.";
if (fadingSurface && shouldFreeSurface)
SDL_FreeSurface(fadingSurface);
}
SDL_FreeSurface(fadingSurface);
}
if (animDelta <= 0.0f)
{
logGlobal->warnStream() << "Fade anim: delta should be positive; " << animDelta << " given.";
animDelta = DEFAULT_DELTA;
}
if (sourceSurface)
fadingSurface = sourceSurface;
delta = animDelta;
fadingMode = mode;
fadingCounter = initialCounter();
@ -1266,13 +1257,13 @@ void CFadeAnimation::init(EMode mode, SDL_Surface * sourceSurface, bool freeSurf
}
void CFadeAnimation::draw(SDL_Surface * targetSurface, const SDL_Rect * sourceRect, SDL_Rect * destRect)
{
{
if (!fading || !fadingSurface || fadingMode == EMode::NONE)
{
fading = false;
return;
}
CSDL_Ext::setAlpha(fadingSurface, fadingCounter * 255);
SDL_BlitSurface(fadingSurface, const_cast<SDL_Rect *>(sourceRect), targetSurface, destRect); //FIXME
CSDL_Ext::setAlpha(fadingSurface, 255);

View File

@ -39,8 +39,8 @@ private:
//offset[group][frame] - offset of frame data in file
std::map<size_t, std::vector <size_t> > offset;
ui8 * data;
SDL_Color * palette;
std::unique_ptr<ui8[]> data;
std::unique_ptr<SDL_Color[]> palette;
public:
CDefFile(std::string Name);
@ -236,7 +236,7 @@ private:
bool fading;
float fadingCounter;
bool shouldFreeSurface;
float initialCounter() const;
bool isFinished() const;
public:

View File

@ -9,17 +9,18 @@
<Target title="Debug Win32">
<Option output="../VCMI_launcher" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output=".objs/debug" />
<Option object_output="../obj/Launcher/Debug" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-Og" />
</Compiler>
</Target>
<Target title="Release Win32">
<Option output="../VCMI_launcher" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output=".objs/release" />
<Option object_output="../obj/Launcher/Release" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
@ -36,11 +37,10 @@
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-std=gnu++11" />
<Add option="-isystem $(#boost.include)" />
<Add option="-DBOOST_SYSTEM_NO_DEPRECATED" />
<Add option="-D_WIN32" />
<Add directory="." />
<Add directory="../include" />
<Add directory="$(#boost.include)" />
<Add directory="$(#qt.include)" />
<Add directory="$(#qt.include)/QtGui" />
<Add directory="$(#qt.include)/QtCore" />

View File

@ -11,11 +11,11 @@ set(lib_SRCS
filesystem/CCompressedStream.cpp
filesystem/CFilesystemLoader.cpp
filesystem/CArchiveLoader.cpp
filesystem/CFileInfo.cpp
filesystem/CMemoryStream.cpp
filesystem/CBinaryReader.cpp
filesystem/CFileInputStream.cpp
filesystem/CZipLoader.cpp
filesystem/FileInfo.cpp
filesystem/Filesystem.cpp
filesystem/FileStream.cpp
filesystem/ResourceID.cpp

View File

@ -31,7 +31,7 @@ void IVCMIDirs::init()
#ifndef CSIDL_MYDOCUMENTS
#define CSIDL_MYDOCUMENTS CSIDL_PERSONAL
#endif
#endif
#endif // __MINGW32__
#include <windows.h>
@ -87,7 +87,7 @@ bool StartBatchCopyDataProgram(
"%5%" "\n"
"del \"%%~f0\"&exit" "\n" // Script deletes itself
;
const auto startGameString =
bfs::equivalent(currentPath, from) ?
(boost::format("start \"\" %1%") % (to / exeName)) : // Start game in new path.
@ -107,7 +107,7 @@ bool StartBatchCopyDataProgram(
return true;
}
class VCMIDirsWIN32 : public IVCMIDirs
class VCMIDirsWIN32 final : public IVCMIDirs
{
public:
boost::filesystem::path userDataPath() const override;
@ -166,7 +166,7 @@ void VCMIDirsWIN32::init()
{
const std::wstring& pathStr = path.native();
std::unique_ptr<wchar_t[]> result(new wchar_t[pathStr.length() + 2]);
size_t i = 0;
for (const wchar_t ch : pathStr)
result[i++] = ch;
@ -195,7 +195,7 @@ void VCMIDirsWIN32::init()
return false;
else if (!bfs::is_empty(from)) // TODO: Log warn. Some files not moved. User should try to move files.
return false;
if (bfs::current_path() == from)
bfs::current_path(to);
@ -203,7 +203,7 @@ void VCMIDirsWIN32::init()
bfs::remove(from);
return true;
};
// Retrieves the fully qualified path for the file that contains the specified module.
// The module must have been loaded by the current process.
// If this parameter is nullptr, retrieves the path of the executable file of the current process.
@ -247,7 +247,7 @@ void VCMIDirsWIN32::init()
// Start copying script and exit program.
if (StartBatchCopyDataProgram(from, to, executableName))
exit(ERROR_SUCCESS);
// Everything failed :C
return false;
};
@ -262,14 +262,14 @@ bfs::path VCMIDirsWIN32::userDataPath() const
if (SHGetSpecialFolderPathW(nullptr, profileDir, CSIDL_MYDOCUMENTS, FALSE) != FALSE)
return bfs::path(profileDir) / "My Games\\vcmi";
return ".";
}
bfs::path VCMIDirsWIN32::oldUserDataPath() const
{
wchar_t profileDir[MAX_PATH];
if (SHGetSpecialFolderPathW(nullptr, profileDir, CSIDL_PROFILE, FALSE) == FALSE) // WinAPI way failed
{
#if defined(_MSC_VER) && _MSC_VER >= 1700
@ -284,7 +284,7 @@ bfs::path VCMIDirsWIN32::oldUserDataPath() const
}
#else
const char* profileDirA;
if (profileDirA = std::getenv("userprofile")) // STL way succeed
if ((profileDirA = std::getenv("userprofile"))) // STL way succeed
return bfs::path(profileDirA) / "vcmi";
#endif
else
@ -365,7 +365,7 @@ std::string IVCMIDirsUNIX::genHelpString() const
}
#ifdef VCMI_APPLE
class VCMIDirsOSX : public IVCMIDirsUNIX
class VCMIDirsOSX final : public IVCMIDirsUNIX
{
public:
boost::filesystem::path userDataPath() const override;

View File

@ -19,7 +19,6 @@
<Compiler>
<Add option="-g" />
<Add option="-Og" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add option="-lws2_32" />
@ -33,9 +32,7 @@
<Add option="-lboost_date_time$(#boost.libsuffix)" />
<Add option="-liconv" />
<Add option="-ldbghelp" />
<Add directory="$(#sdl2.lib)" />
<Add directory="$(#boost.lib32)" />
<Add directory="$(#zlib.lib)" />
</Linker>
</Target>
<Target title="Release-win32">
@ -48,7 +45,6 @@
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add option="-s" />
@ -62,9 +58,7 @@
<Add option="-lboost_locale$(#boost.libsuffix)" />
<Add option="-lboost_date_time$(#boost.libsuffix)" />
<Add option="-liconv" />
<Add directory="$(#sdl2.lib)" />
<Add directory="$(#boost.lib32)" />
<Add directory="$(#zlib.lib)" />
</Linker>
</Target>
<Target title="Debug-win64">
@ -110,18 +104,20 @@
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-overloaded-virtual" />
<Add option="-Wno-unused-local-typedefs" />
<Add option="-isystem $(#boost.include)" />
<Add option="-DVCMI_DLL" />
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add option="-DBOOST_SYSTEM_NO_DEPRECATED" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add option="-D_WIN32" />
<Add directory="$(#boost.include)" />
<Add directory="../include" />
<Add directory="../lib" />
<Add directory="." />
<Add directory="$(#sdl2.include)" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add directory="../" />
<Add directory="$(#sdl2.lib)" />
<Add directory="$(#zlib.lib)" />
</Linker>
<Unit filename="AI_Base.h" />
<Unit filename="BattleAction.cpp" />
@ -217,8 +213,6 @@
<Unit filename="filesystem/CBinaryReader.h" />
<Unit filename="filesystem/CCompressedStream.cpp" />
<Unit filename="filesystem/CCompressedStream.h" />
<Unit filename="filesystem/CFileInfo.cpp" />
<Unit filename="filesystem/CFileInfo.h" />
<Unit filename="filesystem/CFileInputStream.cpp" />
<Unit filename="filesystem/CFileInputStream.h" />
<Unit filename="filesystem/CFilesystemLoader.cpp" />
@ -228,6 +222,8 @@
<Unit filename="filesystem/CMemoryStream.h" />
<Unit filename="filesystem/CZipLoader.cpp" />
<Unit filename="filesystem/CZipLoader.h" />
<Unit filename="filesystem/FileInfo.cpp" />
<Unit filename="filesystem/FileInfo.h" />
<Unit filename="filesystem/FileStream.cpp" />
<Unit filename="filesystem/FileStream.h" />
<Unit filename="filesystem/Filesystem.cpp" />

View File

@ -8,7 +8,8 @@ CMappedFileLoader::CMappedFileLoader(const std::string & mountPoint, const JsonN
{
for(auto entry : config.Struct())
{
fileList[ResourceID(mountPoint + entry.first)] = ResourceID(mountPoint + entry.second.String());
//fileList[ResourceID(mountPoint + entry.first)] = ResourceID(mountPoint + entry.second.String());
fileList.emplace(ResourceID(mountPoint + entry.first), ResourceID(mountPoint + entry.second.String()));
}
}

View File

@ -1,87 +1,86 @@
#pragma once
/*
* AdapterLoaders.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "ISimpleResourceLoader.h"
#include "ResourceID.h"
class CFileInfo;
class CInputStream;
class JsonNode;
/**
* Class that implements file mapping (aka *nix symbolic links)
* Uses json file as input, content is map:
* "fileA.txt" : "fileB.txt"
* Note that extension is necessary, but used only to determine type
*
* fileA - file which will be replaced
* fileB - file which will be used as replacement
*/
class DLL_LINKAGE CMappedFileLoader : public ISimpleResourceLoader
{
public:
/**
* Ctor.
*
* @param config Specifies filesystem configuration
*/
explicit CMappedFileLoader(const std::string &mountPoint, const JsonNode & config);
/// Interface implementation
/// @see ISimpleResourceLoader
std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override;
bool existsResource(const ResourceID & resourceName) const override;
std::string getMountPoint() const override;
boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override;
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
private:
/** A list of files in this map
* key = ResourceID for resource loader
* value = ResourceID to which file this request will be redirected
*/
std::unordered_map<ResourceID, ResourceID> fileList;
};
class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader
{
std::vector<std::unique_ptr<ISimpleResourceLoader> > loaders;
std::set<ISimpleResourceLoader *> writeableLoaders;
//FIXME: this is only compile fix, should be removed in the end
#pragma once
/*
* AdapterLoaders.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "ISimpleResourceLoader.h"
#include "ResourceID.h"
class CInputStream;
class JsonNode;
/**
* Class that implements file mapping (aka *nix symbolic links)
* Uses json file as input, content is map:
* "fileA.txt" : "fileB.txt"
* Note that extension is necessary, but used only to determine type
*
* fileA - file which will be replaced
* fileB - file which will be used as replacement
*/
class DLL_LINKAGE CMappedFileLoader : public ISimpleResourceLoader
{
public:
/**
* Ctor.
*
* @param config Specifies filesystem configuration
*/
explicit CMappedFileLoader(const std::string &mountPoint, const JsonNode & config);
/// Interface implementation
/// @see ISimpleResourceLoader
std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override;
bool existsResource(const ResourceID & resourceName) const override;
std::string getMountPoint() const override;
boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override;
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
private:
/** A list of files in this map
* key = ResourceID for resource loader
* value = ResourceID to which file this request will be redirected
*/
std::unordered_map<ResourceID, ResourceID> fileList;
};
class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader
{
std::vector<std::unique_ptr<ISimpleResourceLoader> > loaders;
std::set<ISimpleResourceLoader *> writeableLoaders;
//FIXME: this is only compile fix, should be removed in the end
CFilesystemList(CFilesystemList &) = delete;
CFilesystemList &operator=(CFilesystemList &) = delete;
public:
CFilesystemList();
~CFilesystemList();
/// Interface implementation
/// @see ISimpleResourceLoader
std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override;
bool existsResource(const ResourceID & resourceName) const override;
std::string getMountPoint() const override;
boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override;
public:
CFilesystemList();
~CFilesystemList();
/// Interface implementation
/// @see ISimpleResourceLoader
std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override;
bool existsResource(const ResourceID & resourceName) const override;
std::string getMountPoint() const override;
boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override;
std::set<boost::filesystem::path> getResourceNames(const ResourceID & resourceName) const override;
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
bool createResource(std::string filename, bool update = false) override;
std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override;
/**
* Adds a resource loader to the loaders list
* Passes loader ownership to this object
*
* @param loader The simple resource loader object to add
* @param writeable - resource shall be treated as writeable
*/
void addLoader(ISimpleResourceLoader * loader, bool writeable);
};
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
bool createResource(std::string filename, bool update = false) override;
std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override;
/**
* Adds a resource loader to the loaders list
* Passes loader ownership to this object
*
* @param loader The simple resource loader object to add
* @param writeable - resource shall be treated as writeable
*/
void addLoader(ISimpleResourceLoader * loader, bool writeable);
};

View File

@ -5,7 +5,6 @@
#include "CCompressedStream.h"
#include "CBinaryReader.h"
#include "CFileInfo.h"
ArchiveEntry::ArchiveEntry()
: offset(0), fullSize(0), compressedSize(0)
@ -140,13 +139,13 @@ std::unique_ptr<CInputStream> CArchiveLoader::load(const ResourceID & resourceNa
if (entry.compressedSize != 0) //compressed data
{
std::unique_ptr<CInputStream> fileStream(new CFileInputStream(archive, entry.offset, entry.compressedSize));
auto fileStream = make_unique<CFileInputStream>(archive, entry.offset, entry.compressedSize);
return std::unique_ptr<CInputStream>(new CCompressedStream(std::move(fileStream), false, entry.fullSize));
return make_unique<CCompressedStream>(std::move(fileStream), false, entry.fullSize);
}
else
{
return std::unique_ptr<CInputStream>(new CFileInputStream(archive, entry.offset, entry.fullSize));
return make_unique<CFileInputStream>(archive, entry.offset, entry.fullSize);
}
}

View File

@ -13,7 +13,6 @@
#include "ISimpleResourceLoader.h"
#include "ResourceID.h"
class CFileInfo;
class CFileInputStream;
/**

View File

@ -1,96 +0,0 @@
#include "StdInc.h"
#include "CFileInfo.h"
CFileInfo::CFileInfo() : name("")
{
}
CFileInfo::CFileInfo(std::string name)
: name(std::move(name))
{
}
bool CFileInfo::exists() const
{
return boost::filesystem::exists(name);
}
bool CFileInfo::isDirectory() const
{
return boost::filesystem::is_directory(name);
}
void CFileInfo::setName(const std::string & name)
{
this->name = name;
}
std::string CFileInfo::getName() const
{
return name;
}
std::string CFileInfo::getPath() const
{
size_t found = name.find_last_of("/\\");
return name.substr(0, found);
}
std::string CFileInfo::getExtension() const
{
// Get position of file extension dot
size_t dotPos = name.find_last_of('.');
if(dotPos != std::string::npos)
return name.substr(dotPos);
return "";
}
std::string CFileInfo::getFilename() const
{
const size_t found = name.find_last_of("/\\");
return name.substr(found + 1);
}
std::string CFileInfo::getStem() const
{
std::string rslt = name;
// Remove file extension
const size_t dotPos = name.find_last_of('.');
if(dotPos != std::string::npos)
rslt.erase(dotPos);
return rslt;
}
std::string CFileInfo::getBaseName() const
{
size_t begin = name.find_last_of("/\\");
size_t end = name.find_last_of(".");
if(begin == std::string::npos)
begin = 0;
else
++begin;
if (end < begin)
end = std::string::npos;
size_t len = (end == std::string::npos ? std::string::npos : end - begin);
return name.substr(begin, len);
}
EResType::Type CFileInfo::getType() const
{
return EResTypeHelper::getTypeFromExtension(getExtension());
}
std::time_t CFileInfo::getDate() const
{
return boost::filesystem::last_write_time(name);
}

View File

@ -1,113 +0,0 @@
#pragma once
/*
* CFileInfo.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "ResourceID.h"
/**
* A class which holds information about a file.
*/
class DLL_LINKAGE CFileInfo
{
public:
/**
* Default ctor.
*/
CFileInfo();
/**
* Ctor.
*
* @param name The path and name of the file.
*/
explicit CFileInfo(std::string name);
/**
* Checks if the file exists.
*
* @return true if the file exists, false if not.
*/
bool exists() const;
/**
* Checks if the file is a directory.
*
* @return true if the file is a directory, false if not.
*/
bool isDirectory() const;
/**
* Sets the name.
*
* @param name The name of the file
*/
void setName(const std::string & name);
/**
* Gets the name of the file.
*
* @return the path and name of the file. E.g. ./dir/file.ext
*/
std::string getName() const;
/**
* Gets the path to the file only.
*
* @return the path to the file only. E.g. ./dir/
*/
std::string getPath() const;
/**
* Gets the file extension.
*
* @return the file extension. E.g. .ext
*/
std::string getExtension() const;
/**
* Returns the name of the file.
*
* @return the name of the file. E.g. foo.txt
*/
std::string getFilename() const;
/**
* Gets the file name + path exclusive the extension of the file.
*
* @return the file name exclusive the extension of the file. E.g. ./dir/foo
*/
std::string getStem() const;
/**
* Gets the file name exclusive the extension of the file.
*
* @return the file name exclusive the extension and a path of the file. E.g. foo
*/
std::string getBaseName() const;
/**
* Gets the extension type as a EResType enumeration.
*
* @return the extension type as a EResType enumeration.
*/
EResType::Type getType() const;
/**
* Gets the timestamp of the file.
*
* @return the timestamp of the file, 0 if no timestamp was set
*/
std::time_t getDate() const;
private:
/** Contains the original URI(not modified) e.g. ./dir/foo.txt */
std::string name;
};

View File

@ -1,8 +1,6 @@
#include "StdInc.h"
#include "CFileInputStream.h"
#include "CFileInfo.h"
CFileInputStream::CFileInputStream(const boost::filesystem::path & file, si64 start, si64 size)
: dataStart{start},
dataSize{size},
@ -20,9 +18,6 @@ CFileInputStream::CFileInputStream(const boost::filesystem::path & file, si64 st
fileStream.seekg(dataStart, std::ios::beg);
}
CFileInputStream::CFileInputStream(const CFileInfo & file, si64 start, si64 size)
: CFileInputStream{file.getName(), start, size} {}
si64 CFileInputStream::read(ui8 * data, si64 size)
{
si64 origin = tell();

View File

@ -13,8 +13,6 @@
#include "CInputStream.h"
#include "FileStream.h"
class CFileInfo;
/**
* A class which provides method definitions for reading a file from the filesystem.
*/
@ -32,13 +30,6 @@ public:
*/
CFileInputStream(const boost::filesystem::path & file, si64 start = 0, si64 size = 0);
/**
* C-tor. Opens the specified file.
*
* @see CFileInputStream::CFileInputStream(const boost::filesystem::path &, si64, si64)
*/
CFileInputStream(const CFileInfo & file, si64 start=0, si64 size=0);
/**
* Reads n bytes from the stream into the data buffer.
*

View File

@ -1,7 +1,6 @@
#include "StdInc.h"
#include "CFilesystemLoader.h"
#include "CFileInfo.h"
#include "CFileInputStream.h"
#include "FileStream.h"
@ -19,8 +18,7 @@ std::unique_ptr<CInputStream> CFilesystemLoader::load(const ResourceID & resourc
{
assert(fileList.count(resourceName));
std::unique_ptr<CInputStream> stream(new CFileInputStream(baseDirectory / fileList.at(resourceName)));
return stream;
return make_unique<CFileInputStream>(baseDirectory / fileList.at(resourceName));
}
bool CFilesystemLoader::existsResource(const ResourceID & resourceName) const

View File

@ -13,7 +13,6 @@
#include "ISimpleResourceLoader.h"
#include "ResourceID.h"
class CFileInfo;
class CInputStream;
/**

View File

@ -86,7 +86,7 @@ std::unordered_map<ResourceID, unz64_file_pos> CZipLoader::listFiles(const std::
std::unique_ptr<CInputStream> CZipLoader::load(const ResourceID & resourceName) const
{
return std::unique_ptr<CInputStream>(new CZipStream(archiveName, files.at(resourceName)));
return make_unique<CZipStream>(archiveName, files.at(resourceName));
}
bool CZipLoader::existsResource(const ResourceID & resourceName) const

View File

@ -0,0 +1,56 @@
#include "StdInc.h"
#include "FileInfo.h"
namespace FileInfo
{
boost::string_ref GetFilename(boost::string_ref path)
{
const auto pos = path.find_last_of("/\\");
if (pos != boost::string_ref::npos)
return path.substr(pos + 1);
return path;
}
boost::string_ref GetExtension(boost::string_ref path)
{
const auto dotPos = path.find_last_of('.');
if(dotPos != boost::string_ref::npos)
return path.substr(dotPos);
return boost::string_ref{};
}
boost::string_ref GetStem(boost::string_ref path)
{
auto begin = path.find_last_of("/\\");
auto end = path.find_last_of('.');
if (begin == boost::string_ref::npos)
begin = 0;
else
begin += 1;
if (end < begin)
end = boost::string_ref::npos;
return path.substr(begin, end);
}
boost::string_ref GetParentPath(boost::string_ref path)
{
const auto pos = path.find_last_of("/\\");
return path.substr(0, pos);
}
boost::string_ref GetPathStem(boost::string_ref path)
{
const auto dotPos = path.find_last_of('.');
return path.substr(0, dotPos);
}
} // namespace FileInfo

53
lib/filesystem/FileInfo.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
/*
* FileInfo.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include <boost/utility/string_ref.hpp>
namespace FileInfo
{
/**
* Returns the name of the file.
*
* @return the name of the file. E.g. foo.txt
*/
boost::string_ref DLL_LINKAGE GetFilename(boost::string_ref path);
/**
* Gets the file extension.
*
* @return the file extension. E.g. .ext
*/
boost::string_ref DLL_LINKAGE GetExtension(boost::string_ref path);
/**
* Gets the file name exclusive the extension of the file.
*
* @return the file name exclusive the extension and the path of the file. E.g. foo
*/
boost::string_ref DLL_LINKAGE GetStem(boost::string_ref path);
/**
* Gets the path to the file only.
*
* @return the path to the file only. E.g. ./dir/
*/
boost::string_ref DLL_LINKAGE GetParentPath(boost::string_ref path);
/**
* Gets the file name + path exclusive the extension of the file.
*
* @return the file name exclusive the extension of the file. E.g. ./dir/foo
*/
boost::string_ref DLL_LINKAGE GetPathStem(boost::string_ref path);
} // namespace FileInfo

View File

@ -1,8 +1,6 @@
#include "StdInc.h"
#include "Filesystem.h"
#include "CFileInfo.h"
#include "CArchiveLoader.h"
#include "CFilesystemLoader.h"
#include "AdapterLoaders.h"

View File

@ -1,7 +1,6 @@
#include "StdInc.h"
#include "ResourceID.h"
#include "CFileInfo.h"
#include "FileInfo.h"
// trivial to_upper that completely ignores localization and only work with ASCII
// Technically not a problem since
@ -23,30 +22,47 @@ static inline void toUpper(std::string & string)
for (char & symbol : string)
toUpper(symbol);
}
#else
static inline void toUpper(std::string & string)
{
boost::to_upper(string);
}
#endif
static inline EResType::Type readType(const std::string& name)
{
return EResTypeHelper::getTypeFromExtension(FileInfo::GetExtension(name).to_string());
}
static inline std::string readName(std::string name)
{
const auto dotPos = name.find_last_of('.');
if (dotPos != std::string::npos)
name.resize(dotPos);
toUpper(name);
return name;
}
#if 0
ResourceID::ResourceID()
:type(EResType::OTHER)
{
}
#endif
ResourceID::ResourceID(std::string name)
:type(EResType::UNDEFINED)
{
CFileInfo info(std::move(name));
setType(info.getType());
setName(info.getStem());
}
ResourceID::ResourceID(std::string name, EResType::Type type)
:type(EResType::UNDEFINED)
{
setType(type);
setName(std::move(name));
}
ResourceID::ResourceID(std::string name_):
type{readType(name_)},
name{readName(std::move(name_))}
{}
ResourceID::ResourceID(std::string name_, EResType::Type type_):
type{type_},
name{readName(std::move(name_))}
{}
#if 0
std::string ResourceID::getName() const
{
return name;
@ -72,26 +88,17 @@ void ResourceID::setName(std::string name)
this->name.erase(dotPos);
}
#ifdef ENABLE_TRIVIAL_TOUPPER
toUpper(this->name);
#else
// strangely enough but this line takes 40-50% of filesystem loading time
boost::to_upper(this->name);
#endif
}
void ResourceID::setType(EResType::Type type)
{
this->type = type;
}
#endif
EResType::Type EResTypeHelper::getTypeFromExtension(std::string extension)
{
#ifdef ENABLE_TRIVIAL_TOUPPER
toUpper(extension);
#else
boost::to_upper(extension);
#endif
static const std::map<std::string, EResType::Type> stringToRes =
{

View File

@ -70,7 +70,7 @@ public:
/**
* Default c-tor.
*/
ResourceID();
//ResourceID();
/**
* Ctor. Can be used to create identifier for resource loading using one parameter
@ -98,20 +98,20 @@ public:
return name == other.name && type == other.type;
}
std::string getName() const;
EResType::Type getType() const;
void setName(std::string name);
void setType(EResType::Type type);
std::string getName() const {return name;}
EResType::Type getType() const {return type;}
//void setName(std::string name);
//void setType(EResType::Type type);
private:
/** Specifies the resource name. No extension so .pcx and .png can override each other, always in upper case. **/
std::string name;
/**
* Specifies the resource type. EResType::OTHER if not initialized.
* Required to prevent conflicts if files with different types (e.g. text and image) have the same name.
*/
EResType::Type type;
/** Specifies the resource name. No extension so .pcx and .png can override each other, always in upper case. **/
std::string name;
};
namespace std

View File

@ -1,7 +1,7 @@
#include "StdInc.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/filesystem/CFileInfo.h"
#include "../lib/filesystem/FileInfo.h"
#include "../lib/int3.h"
#include "../lib/mapping/CCampaignHandler.h"
#include "../lib/StartInfo.h"
@ -2413,13 +2413,13 @@ void CGameHandler::sendAndApply( NewStructures * info )
void CGameHandler::save(const std::string & filename )
{
logGlobal->infoStream() << "Saving to " << filename;
CFileInfo info(filename);
//CResourceHandler::get("local")->createResource(info.getStem() + ".vlgm1");
CResourceHandler::get("local")->createResource(info.getStem() + ".vsgm1");
const auto stem = FileInfo::GetPathStem(filename);
const auto savefname = stem.to_string() + ".vsgm1";
CResourceHandler::get("local")->createResource(savefname);
{
logGlobal->infoStream() << "Ordering clients to serialize...";
SaveGame sg(info.getStem() + ".vcgm1");
SaveGame sg(savefname);
sendToAllClients(&sg);
}
@ -2434,7 +2434,7 @@ void CGameHandler::save(const std::string & filename )
// }
{
CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourceID(info.getStem(), EResType::SERVER_SAVEGAME)));
CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourceID(stem.to_string(), EResType::SERVER_SAVEGAME)));
saveCommonState(save);
logGlobal->infoStream() << "Saving server state";
save << *this;

View File

@ -15,9 +15,8 @@
<Option compiler="gcc" />
<Option use_console_runner="0" />
<Compiler>
<Add option="-g" />
<Add option="-Og" />
<Add option="-ggdb" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add directory="$(#boost.lib32)" />
@ -34,7 +33,6 @@
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add option="-s" />
@ -69,13 +67,13 @@
<Add option="-Wno-sign-compare" />
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-overloaded-virtual" />
<Add option="-isystem $(#boost.include)" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add option="-DBOOST_SYSTEM_NO_DEPRECATED" />
<Add option="-D_WIN32" />
<Add directory="$(#boost.include)" />
<Add directory="../include" />
<Add directory="$(#sdl2.include)" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add option="-lole32" />

View File

@ -6,8 +6,8 @@
<Depends filename="lib/minizip/minizip.cbp" />
</Project>
<Project filename="client/VCMI_client.cbp">
<Depends filename="server/VCMI_server.cbp" />
<Depends filename="lib/VCMI_lib.cbp" />
<Depends filename="server/VCMI_server.cbp" />
</Project>
<Project filename="server/VCMI_server.cbp">
<Depends filename="lib/VCMI_lib.cbp" />
@ -27,13 +27,13 @@
<Depends filename="lib/VCMI_lib.cbp" />
</Project>
<Project filename="test/Test.cbp">
<Depends filename="server/VCMI_server.cbp" />
<Depends filename="AI/EmptyAI/EmptyAI.cbp" />
<Depends filename="AI/VCAI/VCAI.cbp" />
<Depends filename="AI/StupidAI/StupidAI.cbp" />
<Depends filename="AI/BattleAI/BattleAI.cbp" />
<Depends filename="lib/VCMI_lib.cbp" />
<Depends filename="client/VCMI_client.cbp" />
<Depends filename="server/VCMI_server.cbp" />
<Depends filename="AI/VCAI/VCAI.cbp" />
</Project>
<Project filename="scripting/erm/ERM.cbp">
<Depends filename="lib/VCMI_lib.cbp" />