refactoring for wchar strings

This commit is contained in:
Jack Andersen 2015-06-09 16:40:03 -10:00
parent c8b7f5a3c8
commit 5d2d2b010d
46 changed files with 1015 additions and 864 deletions

6
hecl/.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "extern/Athena"] [submodule "extern/Athena"]
path = extern/Athena path = extern/Athena
url = https://github.com/Antidote/Athena.git url = https://github.com/Antidote/Athena.git
[submodule "extern/RetroCommon"]
path = extern/RetroCommon
url = https://github.com/RetroView/RetroCommon.git
[submodule "extern/libSquish"]
path = extern/libSquish
url = https://github.com/jackoalan/libSquish.git

View File

@ -1,16 +1,10 @@
#include "HECLDatabase.hpp" #include "HECLDatabase.hpp"
#include "DUMB.hpp"
#include "HMDL.hpp"
#include "MATR.hpp"
#include "STRG.hpp"
#include "TXTR.hpp"
const std::pair<std::string, std::string> DATA_SPECS[] = const std::pair<std::string, std::string> DATA_SPECS[] =
{ {
{"hecl-little", "Targets little-endian pc apps using the HECL runtime"}, {"hecl-little", "Targets little-endian pc apps using the HECL runtime"},
{"hecl-big", "Targets big-endian pc apps using the HECL runtime"}, {"hecl-big", "Targets big-endian pc apps using the HECL runtime"},
{"hecl-revolution", "Targets Wii apps using the HECL runtime"}, {"hecl-revolution", "Targets Wii apps using the HECL runtime"},
{"hecl-cafe", "Targets Wii U apps using the HECL runtime"}, {"hecl-cafe", "Targets Wii U apps using the HECL runtime"},
{"mp1", ""}
}; };

View File

@ -9,15 +9,19 @@ unix:LIBS += -std=c++11
clang:QMAKE_CXXFLAGS += -stdlib=libc++ clang:QMAKE_CXXFLAGS += -stdlib=libc++
clang:LIBS += -stdlib=libc++ -lc++abi clang:LIBS += -stdlib=libc++ -lc++abi
INCLUDEPATH += $$PWD ../include ../extern ../extern/Athena/include INCLUDEPATH += $$PWD ../include ../extern \
../extern/Athena/include
../extern/RetroCommon/include
include(../extern/RetroCommon/RetroCommon.pri)
include(hecl/hecl.pri)
include(mp1/mp1.pri)
include(mp2/mp2.pri)
include(mp3/mp3.pri)
HEADERS += \ HEADERS += \
helpers.hpp \ helpers.hpp
DUMB.hpp \
HMDL.hpp \
MATR.hpp \
STRG.hpp \
TXTR.hpp
SOURCES += \ SOURCES += \
helpers.cpp \ helpers.cpp \

View File

@ -1,11 +1,12 @@
#ifndef DUMB_HPP #ifndef DUMB_HPP
#define DUMB_HPP #define DUMB_HPP
#include "HECLDatabase.hpp"
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
class CDUMBProject : public HECLDatabase::ProjectObjectBase class CDUMBProject : public HECL::Database::ObjectBase
{ {
using HECLDatabase::ProjectObjectBase::ProjectObjectBase; using HECL::Database::ObjectBase::ObjectBase;
bool _cookObject(FDataAppender dataAppender, bool _cookObject(FDataAppender dataAppender,
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
@ -20,9 +21,9 @@ class CDUMBProject : public HECLDatabase::ProjectObjectBase
}; };
class CDUMBRuntime : public HECLRuntime::RuntimeObjectBase class CDUMBRuntime : public HECL::Runtime::ObjectBase
{ {
using HECLRuntime::RuntimeObjectBase::RuntimeObjectBase; using HECL::Runtime::ObjectBase::ObjectBase;
bool _objectFinishedLoading(const void* data, size_t len) bool _objectFinishedLoading(const void* data, size_t len)
{ {

View File

@ -4,9 +4,9 @@
#include "HECLDatabase.hpp" #include "HECLDatabase.hpp"
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
class CHMDLProject : public HECLDatabase::ProjectObjectBase class CHMDLProject : public HECL::Database::ObjectBase
{ {
using HECLDatabase::ProjectObjectBase::ProjectObjectBase; using HECL::Database::ObjectBase::ObjectBase;
bool _cookObject(FDataAppender dataAppender, bool _cookObject(FDataAppender dataAppender,
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
@ -20,9 +20,9 @@ class CHMDLProject : public HECLDatabase::ProjectObjectBase
} }
}; };
class CHMDLRuntime : public HECLRuntime::RuntimeObjectBase class CHMDLRuntime : public HECL::Runtime::ObjectBase
{ {
using HECLRuntime::RuntimeObjectBase::RuntimeObjectBase; using HECL::Runtime::ObjectBase::ObjectBase;
bool _objectFinishedLoading(const void* data, size_t len) bool _objectFinishedLoading(const void* data, size_t len)
{ {

View File

@ -4,9 +4,9 @@
#include "HECLDatabase.hpp" #include "HECLDatabase.hpp"
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
class CMATRProject : public HECLDatabase::ProjectObjectBase class CMATRProject : public HECL::Database::ObjectBase
{ {
using HECLDatabase::ProjectObjectBase::ProjectObjectBase; using HECL::Database::ObjectBase::ObjectBase;
bool _cookObject(FDataAppender dataAppender, bool _cookObject(FDataAppender dataAppender,
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
@ -20,9 +20,9 @@ class CMATRProject : public HECLDatabase::ProjectObjectBase
} }
}; };
class CMATRRuntime : public HECLRuntime::RuntimeObjectBase class CMATRRuntime : public HECL::Runtime::ObjectBase
{ {
using HECLRuntime::RuntimeObjectBase::RuntimeObjectBase; using HECL::Runtime::ObjectBase::ObjectBase;
bool _objectFinishedLoading(const void* data, size_t len) bool _objectFinishedLoading(const void* data, size_t len)
{ {

View File

@ -4,9 +4,9 @@
#include "HECLDatabase.hpp" #include "HECLDatabase.hpp"
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
class CSTRGProject : public HECLDatabase::ProjectObjectBase class CSTRGProject : public HECL::Database::ObjectBase
{ {
using HECLDatabase::ProjectObjectBase::ProjectObjectBase; using HECL::Database::ObjectBase::ObjectBase;
bool _cookObject(FDataAppender dataAppender, bool _cookObject(FDataAppender dataAppender,
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
@ -20,9 +20,9 @@ class CSTRGProject : public HECLDatabase::ProjectObjectBase
} }
}; };
class CSTRGRuntime : public HECLRuntime::RuntimeObjectBase class CSTRGRuntime : public HECL::Runtime::ObjectBase
{ {
using HECLRuntime::RuntimeObjectBase::RuntimeObjectBase; using HECL::Runtime::ObjectBase::ObjectBase;
bool _objectFinishedLoading(const void* data, size_t len) bool _objectFinishedLoading(const void* data, size_t len)
{ {

View File

@ -5,9 +5,9 @@
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
#include "helpers.hpp" #include "helpers.hpp"
class CTXTRProject : public HECLDatabase::ProjectObjectBase class CTXTRProject : public HECL::Database::ObjectBase
{ {
using HECLDatabase::ProjectObjectBase::ProjectObjectBase; using HECL::Database::ObjectBase::ObjectBase;
bool _cookObject(FDataAppender dataAppender, bool _cookObject(FDataAppender dataAppender,
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
@ -31,9 +31,9 @@ public:
} }
}; };
class CTXTRRuntime : public HECLRuntime::RuntimeObjectBase class CTXTRRuntime : public HECL::Runtime::ObjectBase
{ {
using HECLRuntime::RuntimeObjectBase::RuntimeObjectBase; using HECL::Runtime::ObjectBase::ObjectBase;
bool _objectFinishedLoading(const void* data, size_t len) bool _objectFinishedLoading(const void* data, size_t len)
{ {

View File

View File

View File

@ -0,0 +1,2 @@
SOURCES += \
$$PWD/mp1.cpp

View File

View File

@ -0,0 +1,2 @@
SOURCES += \
$$PWD/mp2.cpp

View File

View File

@ -0,0 +1,2 @@
SOURCES += \
$$PWD/mp3.cpp

View File

@ -1,64 +0,0 @@
#ifndef CTOOL_ADD
#define CTOOL_ADD
#include "CToolBase.hpp"
#include <stdio.h>
class CToolAdd final : public CToolBase
{
public:
CToolAdd(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolAdd()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-add - Add working files to the HECL index\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl add [<pathspec>...]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command stages a file or glob-pattern of files within the project database "
"for inclusion in the ");
help.wrapBold("hecl cook");
help.wrap(" process.\n\n"
"Files added in this manner automatically become 'explicit' database "
"objects. 'Explicit objects' will not be removed in housekeeping tasks automatically "
"performed by HECL's library functions, unless the user (re)moves the file "
"using the filesystem.\n\n"
"For details on explicit vs. implicit objects, view the ");
help.wrapBold("hecl cook");
help.wrap(" documentation.\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<pathspec>...", "input file(s)");
help.beginWrap();
help.wrap("Working file(s) containing production data to be cooked by HECL. "
"Glob-strings may be specified (e.g. ");
help.wrapBold("*.blend");
help.wrap(") to automatically add all matching files to the database.\n");
help.endWrap();
}
std::string toolName() const {return "add";}
int run()
{
return 0;
}
};
#endif // CTOOL_ADD

View File

@ -1,70 +0,0 @@
#ifndef CTOOL_CLEAN
#define CTOOL_CLEAN
#include "CToolBase.hpp"
#include <stdio.h>
class CToolClean final : public CToolBase
{
public:
CToolClean(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolClean()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-clean - Delete cached cooked objects referenced via working files\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl clean [-ri] [<pathspec>...]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command performs an immediate deletion of cooked objects cached "
"within the project database. It may operate on a subset of objects or the "
"entire project.\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<pathspec>...", "clean path(s)");
help.beginWrap();
help.wrap("When one or more paths are specified in the command, the clean process will "
"restrict object deletion to only the working file(s) specified. If ");
help.wrapBold("-r");
help.wrap(" is also specifed, directories may be provided as well. If no path(s) specified, "
"the entire project is cleaned.\n");
help.endWrap();
help.optionHead("-r", "recursion");
help.beginWrap();
help.wrap("Enables recursive file-matching for cleaning entire directories of working files.\n");
help.endWrap();
help.optionHead("-i", "follow implicit links");
help.beginWrap();
help.wrap("Enables implicit object traversal and cleaning. This is only useful if one or more paths "
"are specified. For objects supporting implicit-gathering, this will query those "
"objects for their current implicit links and ensure the linked-objects are cleaned "
"as well.\n");
help.endWrap();
}
std::string toolName() const {return "clean";}
int run()
{
return 0;
}
};
#endif // CTOOL_CLEAN

View File

@ -1,81 +0,0 @@
#ifndef CTOOL_COOK
#define CTOOL_COOK
#include "CToolBase.hpp"
#include <stdio.h>
class CToolCook final : public CToolBase
{
public:
CToolCook(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolCook()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-cook - Cook objects within the project database\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl cook [-r] [<pathspec>...]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command initiates a cooking pass on the project database. Cooking "
"is analogous to compiling in software development. The resulting object buffers "
"are cached within the project database. HECL performs the following "
"tasks for each object during the cook process:\n\n");
help.wrapBold("- Object Gather: ");
help.wrap("Files added with ");
help.wrapBold("hecl add");
help.wrap(" are queried for their dependent files (e.g. ");
help.wrapBold(".blend");
help.wrap(" files return any linked ");
help.wrapBold(".png");
help.wrap(" images). If the dependent files are unable to be found, the cook process aborts.\n\n");
help.wrapBold("- Modtime Comparison: ");
help.wrap("Files that have previously finished a cook pass are inspected for their time of "
"last modification. If the file hasn't changed since its previous cook-pass, the "
"process is skipped. If the file has been moved or deleted, the object is automatically "
"removed from the project database.\n\n");
help.wrapBold("- Cook: ");
help.wrap("A type-specific procedure compiles the file's contents into an efficient format "
"for use by the runtime. A data-buffer is provided to HECL.\n\n");
help.wrapBold("- Hash and Compress: ");
help.wrap("The data-buffer is hashed and compressed before being cached in the object database.\n\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<pathspec>...", "input file(s)");
help.beginWrap();
help.wrap("Specifies working file(s) containing production data to be cooked by HECL. "
"Glob-strings may be specified (e.g. ");
help.wrapBold("*.blend");
help.wrap(") to automatically cook all matching current-directory files in the project database. "
"If no path specified, all files in the project database are cooked.\n");
help.endWrap();
help.optionHead("-r", "recursion");
help.beginWrap();
help.wrap("Enables recursive file-matching for cooking entire directories of working files.\n");
help.endWrap();
}
std::string toolName() const {return "cook";}
int run()
{
return 0;
}
};
#endif // CTOOL_COOK

View File

@ -1,67 +0,0 @@
#ifndef CTOOL_GROUP
#define CTOOL_GROUP
#include "CToolBase.hpp"
#include <stdio.h>
class CToolGroup final : public CToolBase
{
public:
CToolGroup(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolGroup()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-group - Fork a project directory as an explicit group\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl group [-D] <dir>\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command turns a nested subdirectory of the project into a HECL group. "
"Groups play an important role in the resulting structure of the packaged "
"database. All objects in HECL belong to a group of some sort since the runtime "
"only provides loading functions for groups. Ungrouped "
"objects in the project root are individually added to 'loose groups'.\n\n With ");
help.wrapBold("hecl group");
help.wrap(", explicit groups may be defined (e.g. a stage, level, area, loadable segment). ");
help.wrap("Groups are defined by filesystem directories relative to the project root "
"and may be loaded within the runtime using the relative path as a lookup-string. "
"Sub-directories that aren't explicitly made into a group inherit the group-status "
"of the parent directory.\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<dir>", "group directory path");
help.beginWrap();
help.wrap("Directory to fork as an explicit group\n");
help.endWrap();
help.optionHead("-D", "delete group");
help.beginWrap();
help.wrap("Remove's directory's status as an explicit group; restoring its inheritance "
"from the parent directory.\n");
help.endWrap();
}
std::string toolName() const {return "group";}
int run()
{
return 0;
}
};
#endif // CTOOL_GROUP

View File

@ -1,96 +0,0 @@
#ifndef CTOOL_HELP
#define CTOOL_HELP
#include "CToolBase.hpp"
#include <stdio.h>
#include <stdexcept>
#include <functional>
class CToolHelp final : public CToolBase
{
public:
CToolHelp(const SToolPassInfo& info)
: CToolBase(info)
{
if (m_info.args.empty())
throw std::invalid_argument("help requires a tool name argument");
}
~CToolHelp()
{
}
static void Help(CHelpOutput& help)
{
help.printBold("................................___________ \n"
"...........................,.-'\"...........``~., \n"
"........................,.-\".......................\"-., \n"
"....................,/..................................\":, \n"
"..................,?........................................, \n"
"................/...........................................,}\n"
"............../........................................,:`^`..}\n"
"............./.......................................,:\"...../\n"
"............?.....__..................................:`...../\n"
".........../__.(...\"~-,_...........................,:`....../\n"
"........../(_....\"~,_....\"~,_.....................,:`...._/ \n"
"..........{.._$;_....\"=,_.....\"-,_......,.-~-,},.~\";/....} \n"
"...........((...*~_......\"=-._...\";,,./`........../\"..../ \n"
"...,,,___.`~,......\"~.,....................`......}....../ \n"
"............(....`=-,,...`.........................(...;_,,-\" \n"
"............/.`~,......`-.................................../ \n"
".............`~.*-,.....................................|,./...,__ \n"
",,_..........}.>-._...................................|.......`=~-, \n"
".....`=~-,__......`,................................. \n"
"...................`=~-,,.,........................... \n"
".........................`:,,..........................`\n"
"...........................`=-,...............,%%`>--==`` \n"
".................................._.........._,-%%...` \n"
"...................................,\n");
}
static void ToolHelp(const std::string& toolName)
{
/* Select tool's help-text streamer */
CHelpOutput::THelpFunc helpFunc = NULL;
if (toolName == "init")
helpFunc = CToolInit::Help;
else if (toolName == "spec")
helpFunc = CToolSpec::Help;
else if (toolName == "add")
helpFunc = CToolAdd::Help;
else if (toolName == "remove" || toolName == "rm")
helpFunc = CToolRemove::Help;
else if (toolName == "group")
helpFunc = CToolGroup::Help;
else if (toolName == "cook")
helpFunc = CToolCook::Help;
else if (toolName == "clean")
helpFunc = CToolClean::Help;
else if (toolName == "package" || toolName == "pack")
helpFunc = CToolPackage::Help;
else if (toolName == "help")
helpFunc = CToolHelp::Help;
else
{
throw std::invalid_argument("unrecognized tool '" + toolName + "' - can't help");
return;
}
CHelpOutput ho(helpFunc);
ho.go();
}
std::string toolName() const {return "help";}
int run()
{
ToolHelp(m_info.args[0]);
return 0;
}
};
#endif // CTOOL_HELP

View File

@ -1,60 +0,0 @@
#ifndef CTOOL_INIT
#define CTOOL_INIT
#include "CToolBase.hpp"
#include <stdio.h>
class CToolInit final : public CToolBase
{
const std::string* m_dir = NULL;
public:
CToolInit(const SToolPassInfo& info)
: CToolBase(info)
{
if (info.args.size())
{
}
m_dir = &info.args[0];
}
~CToolInit()
{
}
int run()
{
return 0;
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-init - Initialize a brand-new project database\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl init [<dir>]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("Creates a ");
help.wrapBold(".hecl");
help.wrap(" directory within the selected directory with an initialized database index. "
"This constitutes an empty HECL project, ready for making stuff!!\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<dir>", "group directory path");
help.beginWrap();
help.wrap("Directory to create new project database in. If not specified, current directory is used.\n");
help.endWrap();
}
std::string toolName() const {return "init";}
};
#endif // CTOOL_INIT

View File

@ -1,70 +0,0 @@
#ifndef CTOOL_PACKAGE
#define CTOOL_PACKAGE
#include <vector>
#include <string>
#include "CToolBase.hpp"
#include <stdio.h>
class CToolPackage final : public CToolBase
{
public:
CToolPackage(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolPackage()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-pack\n"
"hecl-package - Package objects within the project database\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl package [-a] [-o <package-out>] [<input-dir>]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command initiates a packaging pass on the project database. Packaging "
"is analogous to linking in software development. All objects necessary to "
"generate a complete package are gathered, grouped, and indexed within an .hlpk file.\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<dir>", "input directory");
help.beginWrap();
help.wrap("Specifies a project subdirectory to root the resulting package from. "
"If any dependent-files fall outside this subdirectory, they will implicitly "
"be gathered and packaged.\n");
help.endWrap();
help.optionHead("-o <package-out>", "output package file");
help.beginWrap();
help.wrap("Specifies a target path to write the package. If not specified, the package "
"is written into <project-root>/out/<relative-input-dirs>/<input-dir>.hlpk\n");
help.endWrap();
help.optionHead("-a", "auto cook");
help.beginWrap();
help.wrap("Any referenced objects that haven't already been cooked are automatically cooked as "
"part of the packaging process. If this flag is omitted, the packaging process will abort.\n");
help.endWrap();
}
std::string toolName() const {return "package";}
int run()
{
return 0;
}
};
#endif // CTOOL_PACKAGE

View File

@ -1,62 +0,0 @@
#ifndef CTOOL_REMOVE
#define CTOOL_REMOVE
#include "CToolBase.hpp"
#include <stdio.h>
class CToolRemove final : public CToolBase
{
public:
CToolRemove(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolRemove()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-rm\n");
help.wrap("hecl-remove - Remove working files from the HECL index\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl remove [-r] [<pathspec>...]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command removes a file, directory, or glob-pattern of files from the project database. "
"Once a file is removed, any cooked cache objects are deleted automatically. ");
help.wrapBold("The working file itself is not deleted from the filesystem.\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<pathspec>...", "input file(s)");
help.beginWrap();
help.wrap("Working file(s) to be removed from the project database. "
"Glob-strings may be specified (e.g. ");
help.wrapBold("*.blend");
help.wrap(") to automatically remove all matching files from the database.\n");
help.endWrap();
help.optionHead("-r", "recursion");
help.beginWrap();
help.wrap("Enables recursive file-matching for removing entire directories of working files.\n");
help.endWrap();
}
std::string toolName() const {return "remove";}
int run()
{
return 0;
}
};
#endif // CTOOL_REMOVE

View File

@ -1,53 +0,0 @@
#ifndef CTOOL_SPEC
#define CTOOL_SPEC
#include "CToolBase.hpp"
#include <stdio.h>
class CToolSpec final : public CToolBase
{
public:
CToolSpec(const SToolPassInfo& info)
: CToolBase(info)
{
}
~CToolSpec()
{
}
static void Help(CHelpOutput& help)
{
help.secHead("NAME");
help.beginWrap();
help.wrap("hecl-spec - Configure target data options\n");
help.endWrap();
help.secHead("SYNOPSIS");
help.beginWrap();
help.wrap("hecl spec [enable|disable] [<specname>...]\n");
help.endWrap();
help.secHead("DESCRIPTION");
help.beginWrap();
help.wrap("This command configures the HECL project with the user's preferred target DataSpecs.\n\n"
"Providing enable/disable argument will bulk-set the enable status of the provided spec(s)"
"list. If enable/disable is not provided, a list of supported DataSpecs is printed.\n\n");
help.endWrap();
help.secHead("OPTIONS");
help.optionHead("<specname>...", "DataSpec name(s)");
help.beginWrap();
help.wrap("Specifies platform-names to enable/disable");
help.endWrap();
}
std::string toolName() const {return "spec";}
int run()
{
return 0;
}
};
#endif // CTOOL_SPEC

64
hecl/driver/ToolAdd.hpp Normal file
View File

@ -0,0 +1,64 @@
#ifndef CTOOL_ADD
#define CTOOL_ADD
#include "ToolBase.hpp"
#include <stdio.h>
class ToolAdd final : public ToolBase
{
public:
ToolAdd(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolAdd()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-add - Add working files to the HECL index\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl add [<pathspec>...]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command stages a file or glob-pattern of files within the project database "
"for inclusion in the "));
help.wrapBold(_S("hecl cook"));
help.wrap(_S(" process.\n\n"
"Files added in this manner automatically become 'explicit' database "
"objects. 'Explicit objects' will not be removed in housekeeping tasks automatically "
"performed by HECL's library functions, unless the user (re)moves the file "
"using the filesystem.\n\n"
"For details on explicit vs. implicit objects, view the "));
help.wrapBold(_S("hecl cook"));
help.wrap(_S(" documentation.\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<pathspec>..."), _S("input file(s)"));
help.beginWrap();
help.wrap(_S("Working file(s) containing production data to be cooked by HECL. "
"Glob-strings may be specified (e.g. "));
help.wrapBold(_S("*.blend"));
help.wrap(_S(") to automatically add all matching files to the database.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("add");}
int run()
{
return 0;
}
};
#endif // CTOOL_ADD

View File

@ -9,25 +9,25 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
struct SToolPassInfo struct ToolPassInfo
{ {
std::string pname; HECL::SystemString pname;
std::string cwd; HECL::SystemString cwd;
std::vector<std::string> args; std::vector<HECL::SystemString> args;
std::string output; HECL::SystemString output;
unsigned verbosityLevel = 0; unsigned verbosityLevel = 0;
bool force = false; bool force = false;
}; };
class CToolBase class ToolBase
{ {
protected: protected:
const SToolPassInfo& m_info; const ToolPassInfo& m_info;
public: public:
CToolBase(const SToolPassInfo& info) ToolBase(const ToolPassInfo& info)
: m_info(info) {} : m_info(info) {}
virtual ~CToolBase() {} virtual ~ToolBase() {}
virtual std::string toolName() const=0; virtual HECL::SystemString toolName() const=0;
virtual int run()=0; virtual int run()=0;
}; };
@ -41,51 +41,51 @@ public:
extern bool XTERM_COLOR; extern bool XTERM_COLOR;
class CHelpOutput class HelpOutput
{ {
public: public:
typedef void(*THelpFunc)(CHelpOutput&); typedef void(*HelpFunc)(HelpOutput&);
private: private:
FILE* m_sout; FILE* m_sout;
THelpFunc m_helpFunc; HelpFunc m_helpFunc;
int m_lineWidth; int m_lineWidth;
std::string m_wrapBuffer; HECL::SystemString m_wrapBuffer;
void _wrapBuf(std::string& string) void _wrapBuf(HECL::SystemString& string)
{ {
int counter; int counter;
std::string::iterator it = string.begin(); HECL::SystemString::iterator it = string.begin();
while (it != string.end()) while (it != string.end())
{ {
std::string::iterator v=it; HECL::SystemString::iterator v=it;
/* copy string until the end of the line is reached */ /* copy string until the end of the line is reached */
for (counter=WRAP_INDENT ; counter < m_lineWidth ; ++counter) for (counter=WRAP_INDENT ; counter < m_lineWidth ; ++counter)
{ {
if (*it == '\n') if (*it == _S('\n'))
{ {
counter = WRAP_INDENT; counter = WRAP_INDENT;
++it; ++it;
} }
if (counter == WRAP_INDENT) if (counter == WRAP_INDENT)
it = string.insert(it, WRAP_INDENT, ' ') + WRAP_INDENT; it = string.insert(it, WRAP_INDENT, _S(' ')) + WRAP_INDENT;
if (it >= string.end()) if (it >= string.end())
return; return;
if (*it != '\n') if (*it != _S('\n'))
++it; ++it;
} }
/* check for whitespace */ /* check for whitespace */
if (isspace(*it)) if (isspace(*it))
{ {
*it = '\n'; *it = _S('\n');
counter = WRAP_INDENT; counter = WRAP_INDENT;
++it; ++it;
} }
else else
{ {
/* check for nearest whitespace back in string */ /* check for nearest whitespace back in string */
for (std::string::iterator k=it ; k!=string.begin() ; --k) for (HECL::SystemString::iterator k=it ; k!=string.begin() ; --k)
{ {
if (isspace(*k)) if (isspace(*k))
{ {
@ -93,10 +93,10 @@ private:
if (k < v) if (k < v)
{ {
k = it; k = it;
string.insert(k, '\n'); string.insert(k, _S('\n'));
} }
else else
*k = '\n'; *k = _S('\n');
it = k + 1; it = k + 1;
break; break;
} }
@ -107,19 +107,29 @@ private:
public: public:
CHelpOutput(THelpFunc helpFunc) HelpOutput(HelpFunc helpFunc)
: m_sout(NULL), m_helpFunc(helpFunc) : m_sout(NULL), m_helpFunc(helpFunc)
{ {
#if _WIN32
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
m_lineWidth = info.dwSize.X;
#else
struct winsize w; struct winsize w;
m_lineWidth = 80; m_lineWidth = 80;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1)
m_lineWidth = w.ws_col; m_lineWidth = w.ws_col;
#endif
if (m_lineWidth < 10) if (m_lineWidth < 10)
m_lineWidth = 10; m_lineWidth = 10;
} }
void go() void go()
{ {
#if _WIN32
m_sout = stdout;
m_helpFunc(*this);
#else
m_sout = popen("less -R", "w"); m_sout = popen("less -R", "w");
if (m_sout) if (m_sout)
{ {
@ -131,35 +141,36 @@ public:
m_sout = stdout; m_sout = stdout;
m_helpFunc(*this); m_helpFunc(*this);
} }
#endif
} }
void print(const char* str) void print(const HECL::SystemChar* str)
{ {
fputs(str, m_sout); HECL::FPrintf(m_sout, _S("%s"), str);
} }
void printBold(const char* str) void printBold(const HECL::SystemChar* str)
{ {
if (XTERM_COLOR) if (XTERM_COLOR)
fprintf(m_sout, BOLD "%s" NORMAL, str); HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL ""), str);
else else
fputs(str, m_sout); HECL::FPrintf(m_sout, _S("%s"), str);
} }
void secHead(const char* headName) void secHead(const HECL::SystemChar* headName)
{ {
if (XTERM_COLOR) if (XTERM_COLOR)
fprintf(m_sout, BOLD "%s" NORMAL "\n", headName); HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL "\n"), headName);
else else
fprintf(m_sout, "%s\n", headName); HECL::FPrintf(m_sout, _S("%s\n"), headName);
} }
void optionHead(const char* flag, const char* synopsis) void optionHead(const HECL::SystemChar* flag, const HECL::SystemChar* synopsis)
{ {
if (XTERM_COLOR) if (XTERM_COLOR)
fprintf(m_sout, BOLD "%s" NORMAL " (%s)\n", flag, synopsis); HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL " (%s)\n"), flag, synopsis);
else else
fprintf(m_sout, "%s (%s)\n", flag, synopsis); HECL::FPrintf(m_sout, _S("%s (%s)\n"), flag, synopsis);
} }
void beginWrap() void beginWrap()
@ -167,23 +178,25 @@ public:
m_wrapBuffer.clear(); m_wrapBuffer.clear();
} }
void wrap(const char* str) void wrap(const HECL::SystemChar* str)
{ {
m_wrapBuffer += str; m_wrapBuffer += str;
} }
void wrapBold(const char* str) void wrapBold(const HECL::SystemChar* str)
{ {
m_wrapBuffer += BOLD; if (XTERM_COLOR)
m_wrapBuffer += _S("" BOLD "");
m_wrapBuffer += str; m_wrapBuffer += str;
m_wrapBuffer += NORMAL; if (XTERM_COLOR)
m_wrapBuffer += _S("" NORMAL "");
} }
void endWrap() void endWrap()
{ {
_wrapBuf(m_wrapBuffer); _wrapBuf(m_wrapBuffer);
m_wrapBuffer += '\n'; m_wrapBuffer += _S('\n');
fputs(m_wrapBuffer.c_str(), m_sout); HECL::FPrintf(m_sout, _S("%s"), m_wrapBuffer.c_str());
m_wrapBuffer.clear(); m_wrapBuffer.clear();
} }
}; };

70
hecl/driver/ToolClean.hpp Normal file
View File

@ -0,0 +1,70 @@
#ifndef CTOOL_CLEAN
#define CTOOL_CLEAN
#include "ToolBase.hpp"
#include <stdio.h>
class ToolClean final : public ToolBase
{
public:
ToolClean(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolClean()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-clean - Delete cached cooked objects referenced via working files\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl clean [-ri] [<pathspec>...]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command performs an immediate deletion of cooked objects cached "
"within the project database. It may operate on a subset of objects or the "
"entire project.\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<pathspec>..."), _S("clean path(s)"));
help.beginWrap();
help.wrap(_S("When one or more paths are specified in the command, the clean process will "
"restrict object deletion to only the working file(s) specified. If "));
help.wrapBold(_S("-r"));
help.wrap(_S(" is also specifed, directories may be provided as well. If no path(s) specified, "
"the entire project is cleaned.\n"));
help.endWrap();
help.optionHead(_S("-r"), _S("recursion"));
help.beginWrap();
help.wrap(_S("Enables recursive file-matching for cleaning entire directories of working files.\n"));
help.endWrap();
help.optionHead(_S("-i"), _S("follow implicit links"));
help.beginWrap();
help.wrap(_S("Enables implicit object traversal and cleaning. This is only useful if one or more paths "
"are specified. For objects supporting implicit-gathering, this will query those "
"objects for their current implicit links and ensure the linked-objects are cleaned "
"as well.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("clean");}
int run()
{
return 0;
}
};
#endif // CTOOL_CLEAN

81
hecl/driver/ToolCook.hpp Normal file
View File

@ -0,0 +1,81 @@
#ifndef CTOOL_COOK
#define CTOOL_COOK
#include "ToolBase.hpp"
#include <stdio.h>
class ToolCook final : public ToolBase
{
public:
ToolCook(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolCook()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-cook - Cook objects within the project database\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl cook [-r] [<pathspec>...]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command initiates a cooking pass on the project database. Cooking "
"is analogous to compiling in software development. The resulting object buffers "
"are cached within the project database. HECL performs the following "
"tasks for each object during the cook process:\n\n"));
help.wrapBold(_S("- Object Gather: "));
help.wrap(_S("Files added with "));
help.wrapBold(_S("hecl add"));
help.wrap(_S(" are queried for their dependent files (e.g. "));
help.wrapBold(_S(".blend"));
help.wrap(_S(" files return any linked "));
help.wrapBold(_S(".png"));
help.wrap(_S(" images). If the dependent files are unable to be found, the cook process aborts.\n\n"));
help.wrapBold(_S("- Modtime Comparison: "));
help.wrap(_S("Files that have previously finished a cook pass are inspected for their time of "
"last modification. If the file hasn't changed since its previous cook-pass, the "
"process is skipped. If the file has been moved or deleted, the object is automatically "
"removed from the project database.\n\n"));
help.wrapBold(_S("- Cook: "));
help.wrap(_S("A type-specific procedure compiles the file's contents into an efficient format "
"for use by the runtime. A data-buffer is provided to HECL.\n\n"));
help.wrapBold(_S("- Hash and Compress: "));
help.wrap(_S("The data-buffer is hashed and compressed before being cached in the object database.\n\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<pathspec>..."), _S("input file(s)"));
help.beginWrap();
help.wrap(_S("Specifies working file(s) containing production data to be cooked by HECL. "
"Glob-strings may be specified (e.g. "));
help.wrapBold(_S("*.blend"));
help.wrap(_S(") to automatically cook all matching current-directory files in the project database. "
"If no path specified, all files in the project database are cooked.\n"));
help.endWrap();
help.optionHead(_S("-r"), _S("recursion"));
help.beginWrap();
help.wrap(_S("Enables recursive file-matching for cooking entire directories of working files.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("cook");}
int run()
{
return 0;
}
};
#endif // CTOOL_COOK

67
hecl/driver/ToolGroup.hpp Normal file
View File

@ -0,0 +1,67 @@
#ifndef CTOOL_GROUP
#define CTOOL_GROUP
#include "ToolBase.hpp"
#include <stdio.h>
class ToolGroup final : public ToolBase
{
public:
ToolGroup(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolGroup()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-group - Fork a project directory as an explicit group\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl group [-D] <dir>\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command turns a nested subdirectory of the project into a HECL group. "
"Groups play an important role in the resulting structure of the packaged "
"database. All objects in HECL belong to a group of some sort since the runtime "
"only provides loading functions for groups. Ungrouped "
"objects in the project root are individually added to 'loose groups'.\n\n With "));
help.wrapBold(_S("hecl group"));
help.wrap(_S(", explicit groups may be defined (e.g. a stage, level, area, loadable segment). "));
help.wrap(_S("Groups are defined by filesystem directories relative to the project root "
"and may be loaded within the runtime using the relative path as a lookup-string. "
"Sub-directories that aren't explicitly made into a group inherit the group-status "
"of the parent directory.\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<dir>"), _S("group directory path"));
help.beginWrap();
help.wrap(_S("Directory to fork as an explicit group\n"));
help.endWrap();
help.optionHead(_S("-D"), _S("delete group"));
help.beginWrap();
help.wrap(_S("Remove's directory's status as an explicit group; restoring its inheritance "
"from the parent directory.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("group");}
int run()
{
return 0;
}
};
#endif // CTOOL_GROUP

96
hecl/driver/ToolHelp.hpp Normal file
View File

@ -0,0 +1,96 @@
#ifndef CTOOL_HELP
#define CTOOL_HELP
#include "ToolBase.hpp"
#include <stdio.h>
#include <stdexcept>
#include <functional>
class ToolHelp final : public ToolBase
{
public:
ToolHelp(const ToolPassInfo& info)
: ToolBase(info)
{
if (m_info.args.empty())
throw HECL::Exception(_S("help requires a tool name argument"));
}
~ToolHelp()
{
}
static void Help(HelpOutput& help)
{
help.printBold(_S("................................___________ \n"
"...........................,.-'\"...........``~., \n"
"........................,.-\".......................\"-., \n"
"....................,/..................................\":, \n"
"..................,?........................................, \n"
"................/...........................................,}\n"
"............../........................................,:`^`..}\n"
"............./.......................................,:\"...../\n"
"............?.....__..................................:`...../\n"
".........../__.(...\"~-,_...........................,:`....../\n"
"........../(_....\"~,_....\"~,_.....................,:`...._/ \n"
"..........{.._$;_....\"=,_.....\"-,_......,.-~-,},.~\";/....} \n"
"...........((...*~_......\"=-._...\";,,./`........../\"..../ \n"
"...,,,___.`~,......\"~.,....................`......}....../ \n"
"............(....`=-,,...`.........................(...;_,,-\" \n"
"............/.`~,......`-.................................../ \n"
".............`~.*-,.....................................|,./...,__ \n"
",,_..........}.>-._...................................|.......`=~-, \n"
".....`=~-,__......`,................................. \n"
"...................`=~-,,.,........................... \n"
".........................`:,,..........................`\n"
"...........................`=-,...............,%%`>--==`` \n"
".................................._.........._,-%%...` \n"
"...................................,\n"));
}
static void ShowHelp(const HECL::SystemString& toolName)
{
/* Select tool's help-text streamer */
HelpOutput::HelpFunc helpFunc = NULL;
if (toolName == _S("init"))
helpFunc = ToolInit::Help;
else if (toolName == _S("spec"))
helpFunc = ToolSpec::Help;
else if (toolName == _S("add"))
helpFunc = ToolAdd::Help;
else if (toolName == _S("remove") || toolName == _S("rm"))
helpFunc = ToolRemove::Help;
else if (toolName == _S("group"))
helpFunc = ToolGroup::Help;
else if (toolName == _S("cook"))
helpFunc = ToolCook::Help;
else if (toolName == _S("clean"))
helpFunc = ToolClean::Help;
else if (toolName == _S("package") || toolName == _S("pack"))
helpFunc = ToolPackage::Help;
else if (toolName == _S("help"))
helpFunc = ToolHelp::Help;
else
{
throw HECL::Exception(_S("unrecognized tool '") + toolName + _S("' - can't help"));
return;
}
HelpOutput ho(helpFunc);
ho.go();
}
HECL::SystemString toolName() const {return _S("help");}
int run()
{
ShowHelp(m_info.args[0]);
return 0;
}
};
#endif // CTOOL_HELP

60
hecl/driver/ToolInit.hpp Normal file
View File

@ -0,0 +1,60 @@
#ifndef CTOOL_INIT
#define CTOOL_INIT
#include "ToolBase.hpp"
#include <stdio.h>
class ToolInit final : public ToolBase
{
const HECL::SystemString* m_dir = NULL;
public:
ToolInit(const ToolPassInfo& info)
: ToolBase(info)
{
if (info.args.size())
{
}
m_dir = &info.args[0];
}
~ToolInit()
{
}
int run()
{
return 0;
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-init - Initialize a brand-new project database\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl init [<dir>]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("Creates a "));
help.wrapBold(_S(".hecl"));
help.wrap(_S(" directory within the selected directory with an initialized database index. "
"This constitutes an empty HECL project, ready for making stuff!!\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<dir>"), _S("group directory path"));
help.beginWrap();
help.wrap(_S("Directory to create new project database in. If not specified, current directory is used.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("init");}
};
#endif // CTOOL_INIT

View File

@ -0,0 +1,70 @@
#ifndef CTOOL_PACKAGE
#define CTOOL_PACKAGE
#include <vector>
#include <string>
#include "ToolBase.hpp"
#include <stdio.h>
class ToolPackage final : public ToolBase
{
public:
ToolPackage(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolPackage()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-pack\n"
"hecl-package - Package objects within the project database\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl package [-a] [-o <package-out>] [<input-dir>]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command initiates a packaging pass on the project database. Packaging "
"is analogous to linking in software development. All objects necessary to "
"generate a complete package are gathered, grouped, and indexed within an .hlpk file.\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<dir>"), _S("input directory"));
help.beginWrap();
help.wrap(_S("Specifies a project subdirectory to root the resulting package from. "
"If any dependent-files fall outside this subdirectory, they will implicitly "
"be gathered and packaged.\n"));
help.endWrap();
help.optionHead(_S("-o <package-out>"), _S("output package file"));
help.beginWrap();
help.wrap(_S("Specifies a target path to write the package. If not specified, the package "
"is written into <project-root>/out/<relative-input-dirs>/<input-dir>.hlpk\n"));
help.endWrap();
help.optionHead(_S("-a"), _S("auto cook"));
help.beginWrap();
help.wrap(_S("Any referenced objects that haven't already been cooked are automatically cooked as "
"part of the packaging process. If this flag is omitted, the packaging process will abort.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("package");}
int run()
{
return 0;
}
};
#endif // CTOOL_PACKAGE

View File

@ -0,0 +1,62 @@
#ifndef CTOOL_REMOVE
#define CTOOL_REMOVE
#include "ToolBase.hpp"
#include <stdio.h>
class ToolRemove final : public ToolBase
{
public:
ToolRemove(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolRemove()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-rm\n"));
help.wrap(_S("hecl-remove - Remove working files from the HECL index\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl remove [-r] [<pathspec>...]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command removes a file, directory, or glob-pattern of files from the project database. "
"Once a file is removed, any cooked cache objects are deleted automatically. "));
help.wrapBold(_S("The working file itself is not deleted from the filesystem.\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<pathspec>..."), _S("input file(s)"));
help.beginWrap();
help.wrap(_S("Working file(s) to be removed from the project database. "
"Glob-strings may be specified (e.g. "));
help.wrapBold(_S("*.blend"));
help.wrap(_S(") to automatically remove all matching files from the database.\n"));
help.endWrap();
help.optionHead(_S("-r"), _S("recursion"));
help.beginWrap();
help.wrap(_S("Enables recursive file-matching for removing entire directories of working files.\n"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("remove");}
int run()
{
return 0;
}
};
#endif // CTOOL_REMOVE

53
hecl/driver/ToolSpec.hpp Normal file
View File

@ -0,0 +1,53 @@
#ifndef CTOOL_SPEC
#define CTOOL_SPEC
#include "ToolBase.hpp"
#include <stdio.h>
class ToolSpec final : public ToolBase
{
public:
ToolSpec(const ToolPassInfo& info)
: ToolBase(info)
{
}
~ToolSpec()
{
}
static void Help(HelpOutput& help)
{
help.secHead(_S("NAME"));
help.beginWrap();
help.wrap(_S("hecl-spec - Configure target data options\n"));
help.endWrap();
help.secHead(_S("SYNOPSIS"));
help.beginWrap();
help.wrap(_S("hecl spec [enable|disable] [<specname>...]\n"));
help.endWrap();
help.secHead(_S("DESCRIPTION"));
help.beginWrap();
help.wrap(_S("This command configures the HECL project with the user's preferred target DataSpecs.\n\n"
"Providing enable/disable argument will bulk-set the enable status of the provided spec(s)"
"list. If enable/disable is not provided, a list of supported DataSpecs is printed.\n\n"));
help.endWrap();
help.secHead(_S("OPTIONS"));
help.optionHead(_S("<specname>..."), _S("DataSpec name(s)"));
help.beginWrap();
help.wrap(_S("Specifies platform-names to enable/disable"));
help.endWrap();
}
HECL::SystemString toolName() const {return _S("spec");}
int run()
{
return 0;
}
};
#endif // CTOOL_SPEC

View File

@ -24,14 +24,14 @@ SOURCES += \
$$PWD/main.cpp $$PWD/main.cpp
HEADERS += \ HEADERS += \
CToolBase.hpp \ ToolBase.hpp \
CToolPackage.hpp \ ToolPackage.hpp \
CToolInit.hpp \ ToolInit.hpp \
CToolHelp.hpp \ ToolHelp.hpp \
CToolGroup.hpp \ ToolGroup.hpp \
CToolCook.hpp \ ToolCook.hpp \
CToolClean.hpp \ ToolClean.hpp \
CToolAdd.hpp \ ToolAdd.hpp \
CToolRemove.hpp \ ToolRemove.hpp \
CToolSpec.hpp ToolSpec.hpp

View File

@ -7,46 +7,52 @@
#include <list> #include <list>
#include <HECLDatabase.hpp> #include <HECLDatabase.hpp>
#include "CToolBase.hpp" #include "ToolBase.hpp"
#include "CToolInit.hpp" #include "ToolInit.hpp"
#include "CToolSpec.hpp" #include "ToolSpec.hpp"
#include "CToolAdd.hpp" #include "ToolAdd.hpp"
#include "CToolRemove.hpp" #include "ToolRemove.hpp"
#include "CToolGroup.hpp" #include "ToolGroup.hpp"
#include "CToolCook.hpp" #include "ToolCook.hpp"
#include "CToolClean.hpp" #include "ToolClean.hpp"
#include "CToolPackage.hpp" #include "ToolPackage.hpp"
#include "CToolHelp.hpp" #include "ToolHelp.hpp"
bool XTERM_COLOR = false; bool XTERM_COLOR = false;
#define HECL_GIT 1234567
#define HECL_GIT_S "1234567"
#define HECL_BRANCH master
#define HECL_BRANCH_S "master"
/* Main usage message */ /* Main usage message */
static void printHelp(const char* pname) static void printHelp(const HECL::SystemChar* pname)
{ {
if (XTERM_COLOR) if (XTERM_COLOR)
printf(BOLD "HECL" NORMAL); HECL::Printf(_S("" BOLD "HECL" NORMAL ""));
else else
printf("HECL"); HECL::Printf(_S("HECL"));
#if HECL_GIT #if HECL_GIT
printf(" Commit " #HECL_GIT " (" #HECL_BRANCH ")\n" HECL::Printf(_S(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname);
"Usage: %s init|add|remove|group|cook|clean|package|help\n", pname);
#elif HECL_VER #elif HECL_VER
printf(" Version " #HECL_VER "\n" HECL::Printf(_S(" Version " HECL_VER_S "\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname);
"Usage: %s init|add|remove|group|cook|clean|package|help\n", pname);
#else #else
printf("\n" HECL::Printf(_S("\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname);
"Usage: %s init|add|remove|group|cook|clean|package|help\n", pname);
#endif #endif
} }
/* Regex patterns */ /* Regex patterns */
static const std::regex regOPEN("-o([^\"]*|\\S*))", std::regex::ECMAScript|std::regex::optimize); static const HECL::SystemRegex regOPEN(_S("-o([^\"]*|\\S*))"), std::regex::ECMAScript|std::regex::optimize);
static const std::regex regVERBOSE("-v(v*)", std::regex::ECMAScript|std::regex::optimize); static const HECL::SystemRegex regVERBOSE(_S("-v(v*)"), std::regex::ECMAScript|std::regex::optimize);
static const std::regex regFORCE("-f", std::regex::ECMAScript|std::regex::optimize); static const HECL::SystemRegex regFORCE(_S("-f"), std::regex::ECMAScript|std::regex::optimize);
#include "../blender/CBlenderConnection.hpp" #include "../blender/CBlenderConnection.hpp"
#if HECL_UCS2
int wmain(int argc, const wchar_t** argv)
#else
int main(int argc, const char** argv) int main(int argc, const char** argv)
#endif
{ {
/* Xterm check */ /* Xterm check */
const char* term = getenv("TERM"); const char* term = getenv("TERM");
@ -64,32 +70,32 @@ int main(int argc, const char** argv)
} }
else if (argc == 0) else if (argc == 0)
{ {
printHelp("hecl"); printHelp(_S("hecl"));
return 0; return 0;
} }
/* Assemble common tool pass info */ /* Assemble common tool pass info */
SToolPassInfo info; ToolPassInfo info;
info.pname = argv[0]; info.pname = argv[0];
char cwdbuf[MAXPATHLEN]; HECL::SystemChar cwdbuf[MAXPATHLEN];
if (getcwd(cwdbuf, MAXPATHLEN)) if (HECL::Getcwd(cwdbuf, MAXPATHLEN))
info.cwd = cwdbuf; info.cwd = cwdbuf;
/* Concatenate args */ /* Concatenate args */
std::list<std::string> args; std::list<HECL::SystemString> args;
for (int i=2 ; i<argc ; ++i) for (int i=2 ; i<argc ; ++i)
args.push_back(std::string(argv[i])); args.push_back(HECL::SystemString(argv[i]));
if (!args.empty()) if (!args.empty())
{ {
/* Extract output argument */ /* Extract output argument */
for (std::list<std::string>::const_iterator it = args.begin() ; it != args.end() ;) for (std::list<HECL::SystemString>::const_iterator it = args.begin() ; it != args.end() ;)
{ {
const std::string& arg = *it; const HECL::SystemString& arg = *it;
std::smatch oMatch; HECL::SystemRegexMatch oMatch;
if (std::regex_search(arg, oMatch, regOPEN)) if (std::regex_search(arg, oMatch, regOPEN))
{ {
const std::string& token = oMatch[1].str(); const HECL::SystemString& token = oMatch[1].str();
if (token.size()) if (token.size())
{ {
if (info.output.empty()) if (info.output.empty())
@ -111,10 +117,10 @@ int main(int argc, const char** argv)
} }
/* Count verbosity */ /* Count verbosity */
for (std::list<std::string>::const_iterator it = args.begin() ; it != args.end() ;) for (std::list<HECL::SystemString>::const_iterator it = args.begin() ; it != args.end() ;)
{ {
const std::string& arg = *it; const HECL::SystemString& arg = *it;
std::smatch vMatch; HECL::SystemRegexMatch vMatch;
if (std::regex_search(arg, vMatch, regVERBOSE)) if (std::regex_search(arg, vMatch, regVERBOSE))
{ {
++info.verbosityLevel; ++info.verbosityLevel;
@ -126,9 +132,9 @@ int main(int argc, const char** argv)
} }
/* Check force argument */ /* Check force argument */
for (std::list<std::string>::const_iterator it = args.begin() ; it != args.end() ;) for (std::list<HECL::SystemString>::const_iterator it = args.begin() ; it != args.end() ;)
{ {
const std::string& arg = *it; const HECL::SystemString& arg = *it;
if (std::regex_search(arg, regFORCE)) if (std::regex_search(arg, regFORCE))
{ {
info.force = true; info.force = true;
@ -139,46 +145,52 @@ int main(int argc, const char** argv)
} }
/* Gather remaining args */ /* Gather remaining args */
for (const std::string& arg : args) for (const HECL::SystemString& arg : args)
info.args.push_back(arg); info.args.push_back(arg);
} }
/* Construct selected tool */ /* Construct selected tool */
std::string toolName(argv[1]); HECL::SystemString toolName(argv[1]);
#if HECL_UCS2
std::transform(toolName.begin(), toolName.end(), toolName.begin(), towlower);
#else
std::transform(toolName.begin(), toolName.end(), toolName.begin(), tolower); std::transform(toolName.begin(), toolName.end(), toolName.begin(), tolower);
CToolBase* tool = NULL; #endif
ToolBase* tool = NULL;
try try
{ {
if (toolName == "init") if (toolName == _S("init"))
tool = new CToolInit(info); tool = new ToolInit(info);
else if (toolName == "platform") else if (toolName == _S("spec"))
tool = new CToolPlatform(info); tool = new ToolSpec(info);
else if (toolName == "add") else if (toolName == _S("add"))
tool = new CToolAdd(info); tool = new ToolAdd(info);
else if (toolName == "remove" || toolName == "rm") else if (toolName == _S("remove") || toolName == _S("rm"))
tool = new CToolRemove(info); tool = new ToolRemove(info);
else if (toolName == "group") else if (toolName == _S("group"))
tool = new CToolGroup(info); tool = new ToolGroup(info);
else if (toolName == "cook") else if (toolName == _S("cook"))
tool = new CToolCook(info); tool = new ToolCook(info);
else if (toolName == "clean") else if (toolName == _S("clean"))
tool = new CToolClean(info); tool = new ToolClean(info);
else if (toolName == "package" || toolName == "pack") else if (toolName == _S("package") || toolName == _S("pack"))
tool = new CToolPackage(info); tool = new ToolPackage(info);
else if (toolName == "help") else if (toolName == _S("help"))
tool = new CToolHelp(info); tool = new ToolHelp(info);
else else
throw std::invalid_argument("unrecognized tool '" + toolName + "'"); throw HECL::Exception(_S("unrecognized tool '") + toolName + _S("'"));
} }
catch (std::exception& ex) catch (HECL::Exception& ex)
{ {
fprintf(stderr, "Unable to construct HECL tool '%s':\n%s\n", toolName.c_str(), ex.what()); HECL::FPrintf(stderr,
_S("Unable to construct HECL tool '%s':\n%s\n"),
toolName.c_str(), ex.swhat());
delete tool; delete tool;
return -1; return -1;
} }
if (info.verbosityLevel) if (info.verbosityLevel)
printf("Constructed tool '%s' %d\n", tool->toolName().c_str(), info.verbosityLevel); HECL::Printf(_S("Constructed tool '%s' %d\n"), tool->toolName().c_str(), info.verbosityLevel);
/* Run tool */ /* Run tool */
int retval; int retval;
@ -186,9 +198,9 @@ int main(int argc, const char** argv)
{ {
retval = tool->run(); retval = tool->run();
} }
catch (std::exception& ex) catch (HECL::Exception& ex)
{ {
fprintf(stderr, "Error running HECL tool '%s':\n%s\n", toolName.c_str(), ex.what()); HECL::FPrintf(stderr, _S("Error running HECL tool '%s':\n%s\n"), toolName.c_str(), ex.swhat());
delete tool; delete tool;
return -1; return -1;
} }

1
hecl/extern/RetroCommon vendored Submodule

@ -0,0 +1 @@
Subproject commit de29d08623c8807c85e996f81b71e9339466067c

1
hecl/extern/libSquish vendored Submodule

@ -0,0 +1 @@
Subproject commit 7c67895430d88d4971e3197f9a4eeba3ba0f6d35

View File

@ -20,7 +20,6 @@ HEADERS += \
SUBDIRS += \ SUBDIRS += \
extern/blowfish \ extern/blowfish \
extern/libpng \ extern/libpng \
extern/Athena \
blender \ blender \
lib \ lib \
dataspec \ dataspec \

View File

@ -10,6 +10,7 @@ char* win_realpath(const char* name, char* restrict resolved);
#include <dirent.h> #include <dirent.h>
#endif #endif
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <functional> #include <functional>
#include <stdexcept> #include <stdexcept>
@ -20,27 +21,31 @@ char* win_realpath(const char* name, char* restrict resolved);
namespace HECL namespace HECL
{ {
#if _WIN32 && UNICODE
#define HECL_UCS2 1
#endif
std::string WideToUTF8(const std::wstring& src); std::string WideToUTF8(const std::wstring& src);
std::wstring UTF8ToWide(const std::string& src); std::wstring UTF8ToWide(const std::string& src);
#if _WIN32 && UNICODE #if HECL_UCS2
typedef wchar_t SystemChar; typedef wchar_t SystemChar;
typedef std::wstring SystemString; typedef std::wstring SystemString;
class CSystemUTF8View class SystemUTF8View
{ {
std::string m_utf8; std::string m_utf8;
public: public:
CSystemUTF8View(const SystemString& str) SystemUTF8View(const SystemString& str)
: m_utf8(WideToUTF8(str)) {} : m_utf8(WideToUTF8(str)) {}
inline const std::string& utf8_str() {return m_utf8;} inline const std::string& utf8_str() {return m_utf8;}
}; };
class CSystemStringView class SystemStringView
{ {
std::wstring m_sys; std::wstring m_sys;
public: public:
CSystemStringView(const std::string& str) SystemStringView(const std::string& str)
: m_sys(UTF8ToWide(str)) {} : m_sys(UTF8ToWide(str)) {}
inline const std::string& sys_str() {return m_sys;} inline const std::wstring& sys_str() {return m_sys;}
}; };
#ifndef _S #ifndef _S
#define _S(val) L ## val #define _S(val) L ## val
@ -48,19 +53,19 @@ public:
#else #else
typedef char SystemChar; typedef char SystemChar;
typedef std::string SystemString; typedef std::string SystemString;
class CSystemUTF8View class SystemUTF8View
{ {
const std::string& m_utf8; const std::string& m_utf8;
public: public:
CSystemUTF8View(const SystemString& str) SystemUTF8View(const SystemString& str)
: m_utf8(str) {} : m_utf8(str) {}
inline const std::string& utf8_str() {return m_utf8;} inline const std::string& utf8_str() {return m_utf8;}
}; };
class CSystemStringView class SystemStringView
{ {
const std::string& m_sys; const std::string& m_sys;
public: public:
CSystemStringView(const std::string& str) SystemStringView(const std::string& str)
: m_sys(str) {} : m_sys(str) {}
inline const std::string& sys_str() {return m_sys;} inline const std::string& sys_str() {return m_sys;}
}; };
@ -69,6 +74,31 @@ public:
#endif #endif
#endif #endif
class Exception : public std::exception
{
SystemString m_what;
#if HECL_UCS2
std::string m_utf8what;
#endif
public:
Exception(const SystemString& what) noexcept
: m_what(what)
{
#if HECL_UCS2
m_utf8what = WideToUTF8(what);
#endif
}
const char* what() const noexcept
{
#if HECL_UCS2
return m_utf8what.c_str();
#else
return m_what.c_str();
#endif
}
inline const SystemChar* swhat() const noexcept {return m_what.c_str();}
};
static inline void MakeDir(const SystemString& dir) static inline void MakeDir(const SystemString& dir)
{ {
#if _WIN32 #if _WIN32
@ -83,9 +113,18 @@ static inline void MakeDir(const SystemString& dir)
#endif #endif
} }
static inline SystemChar* Getcwd(SystemChar* buf, int maxlen)
{
#if HECL_UCS2
return wgetcwd(buf, maxlen);
#else
return getcwd(buf, maxlen);
#endif
}
static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode) static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode)
{ {
#if _WIN32 && UNICODE #if HECL_UCS2
FILE* fp = wfopen(path, mode); FILE* fp = wfopen(path, mode);
#else #else
FILE* fp = fopen(path, mode); FILE* fp = fopen(path, mode);
@ -96,6 +135,39 @@ static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode)
return fp; return fp;
} }
static inline int Stat(const SystemChar* path, struct stat* statOut)
{
#if HECL_UCS2
return wstat(path, statOut);
#else
return stat(path, statOut);
#endif
}
static inline void Printf(const SystemChar* format, ...)
{
va_list va;
va_start(va, format);
#if HECL_UCS2
vwprintf(format, va);
#else
vprintf(format, va);
#endif
va_end(va);
}
static inline void FPrintf(FILE* fp, const SystemChar* format, ...)
{
va_list va;
va_start(va, format);
#if HECL_UCS2
vfwprintf(fp, format, va);
#else
vfprintf(fp, format, va);
#endif
va_end(va);
}
typedef std::basic_regex<SystemChar> SystemRegex; typedef std::basic_regex<SystemChar> SystemRegex;
typedef std::regex_token_iterator<SystemString::const_iterator> SystemRegexTokenIterator; typedef std::regex_token_iterator<SystemString::const_iterator> SystemRegexTokenIterator;
typedef std::match_results<SystemString::const_iterator> SystemRegexMatch; typedef std::match_results<SystemString::const_iterator> SystemRegexMatch;
@ -115,7 +187,7 @@ enum LogType
/** /**
* @brief Logger callback type * @brief Logger callback type
*/ */
typedef std::function<void(LogType, std::string&)> TLogger; typedef std::function<void(LogType, std::string&)> FLogger;
/** /**
* @brief FourCC representation used within HECL's database * @brief FourCC representation used within HECL's database
@ -183,6 +255,10 @@ class ProjectPath
protected: protected:
SystemString m_absPath; SystemString m_absPath;
const SystemChar* m_relPath = NULL; const SystemChar* m_relPath = NULL;
#if HECL_UCS2
std::string m_utf8AbsPath;
const char* m_utf8RelPath;
#endif
ProjectPath() {} ProjectPath() {}
bool _canonAbsPath(const SystemString& path); bool _canonAbsPath(const SystemString& path);
public: public:
@ -197,25 +273,47 @@ public:
* @brief Determine if ProjectPath represents project root directory * @brief Determine if ProjectPath represents project root directory
* @return true if project root directory * @return true if project root directory
*/ */
inline bool isRoot() {return (m_relPath == NULL);} inline bool isRoot() const {return (m_relPath == NULL);}
/** /**
* @brief Access fully-canonicalized absolute path * @brief Access fully-canonicalized absolute path
* @return Absolute path reference * @return Absolute path reference
*/ */
inline const SystemString& getAbsolutePath() {return m_absPath;} inline const SystemString& getAbsolutePath() const {return m_absPath;}
/** /**
* @brief Access fully-canonicalized project-relative path * @brief Access fully-canonicalized project-relative path
* @return Relative pointer to within absolute-path or "." for project root-directory (use isRoot to detect) * @return Relative pointer to within absolute-path or "." for project root-directory (use isRoot to detect)
*/ */
inline const SystemChar* getRelativePath() inline const SystemChar* getRelativePath() const
{ {
if (m_relPath) if (m_relPath)
return m_relPath; return m_relPath;
return _S("."); return _S(".");
} }
/**
* @brief Access fully-canonicalized absolute path in UTF-8
* @return Absolute path reference
*/
inline const std::string& getAbsolutePathUTF8() const
{
#if HECL_UCS2
return m_utf8AbsPath;
#else
return m_absPath;
#endif
}
inline const char* getRelativePathUTF8() const
{
#if HECL_UCS2
return m_utf8RelPath;
#else
return m_relPath;
#endif
}
/** /**
* @brief Type of path * @brief Type of path
*/ */
@ -231,13 +329,13 @@ public:
* @brief Get type of path based on syntax and filesystem queries * @brief Get type of path based on syntax and filesystem queries
* @return Type of path * @return Type of path
*/ */
PathType getPathType(); PathType getPathType() const;
/** /**
* @brief Insert glob matches into existing vector * @brief Insert glob matches into existing vector
* @param outPaths Vector to add matches to (will not erase existing contents) * @param outPaths Vector to add matches to (will not erase existing contents)
*/ */
void getGlobResults(std::vector<SystemString>& outPaths); void getGlobResults(std::vector<SystemString>& outPaths) const;
}; };
/** /**

View File

@ -13,7 +13,9 @@
#include "HECL.hpp" #include "HECL.hpp"
namespace HECLDatabase namespace HECL
{
namespace Database
{ {
/** /**
@ -25,9 +27,9 @@ namespace HECLDatabase
* *
* DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!! * DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!!
*/ */
class ProjectObjectBase class ObjectBase
{ {
friend class CProject; friend class Project;
std::string m_path; std::string m_path;
protected: protected:
@ -69,7 +71,7 @@ protected:
DataEndianness endianness, DataPlatform platform) DataEndianness endianness, DataPlatform platform)
{(void)dataAppender;(void)endianness;(void)platform;return true;} {(void)dataAppender;(void)endianness;(void)platform;return true;}
typedef std::function<void(ProjectObjectBase*)> FDepAdder; typedef std::function<void(ObjectBase*)> FDepAdder;
/** /**
* @brief Optional private method implemented by CProjectObject subclasses to resolve dependencies * @brief Optional private method implemented by CProjectObject subclasses to resolve dependencies
@ -83,7 +85,7 @@ protected:
{(void)depAdder;} {(void)depAdder;}
public: public:
ProjectObjectBase(const std::string& path) ObjectBase(const std::string& path)
: m_path(path) {} : m_path(path) {}
inline const std::string& getPath() const {return m_path;} inline const std::string& getPath() const {return m_path;}
@ -106,17 +108,17 @@ public:
*/ */
class Project class Project
{ {
HECL::SystemString m_rootPath; ProjectRootPath m_rootPath;
public: public:
Project(const std::string& rootPath); Project(const HECL::ProjectRootPath& rootPath);
class ConfigFile class ConfigFile
{ {
const Project& m_project; const Project& m_project;
const HECL::SystemString& m_name; const SystemString& m_name;
HECL::SystemString m_filepath; SystemString m_filepath;
public: public:
ConfigFile(const Project& project, const HECL::SystemString& name); ConfigFile(const Project& project, const SystemString& name);
std::vector<std::string> readLines(); std::vector<std::string> readLines();
void addLine(const std::string& line); void addLine(const std::string& line);
void removeLine(const std::string& refLine); void removeLine(const std::string& refLine);
@ -152,7 +154,7 @@ public:
* *
* If this method is never called, all project operations will run silently. * If this method is never called, all project operations will run silently.
*/ */
virtual void registerLogger(HECL::TLogger logger); virtual void registerLogger(HECL::FLogger logger);
/** /**
* @brief Get the path of the project's root-directory * @brief Get the path of the project's root-directory
@ -161,7 +163,7 @@ public:
* *
* Self explanatory * Self explanatory
*/ */
virtual const HECL::ProjectRootPath& getProjectRootPath(bool absolute=false) const; virtual const ProjectRootPath& getProjectRootPath(bool absolute=false) const;
/** /**
* @brief Add given file(s) to the database * @brief Add given file(s) to the database
@ -170,7 +172,7 @@ public:
* *
* This method blocks while object hashing takes place * This method blocks while object hashing takes place
*/ */
virtual bool addPaths(const std::vector<HECL::ProjectPath>& paths); virtual bool addPaths(const std::vector<ProjectPath>& paths);
/** /**
* @brief Remove a given file or file-pattern from the database * @brief Remove a given file or file-pattern from the database
@ -181,7 +183,7 @@ public:
* This method will not delete actual working files from the project * This method will not delete actual working files from the project
* directory. It will delete associated cooked objects though. * directory. It will delete associated cooked objects though.
*/ */
virtual bool removePaths(const std::vector<HECL::ProjectPath>& paths, bool recursive=false); virtual bool removePaths(const std::vector<ProjectPath>& paths, bool recursive=false);
/** /**
* @brief Register a working sub-directory as a Dependency Group * @brief Register a working sub-directory as a Dependency Group
@ -197,14 +199,14 @@ public:
* This contiguous storage makes for optimal loading from slow block-devices * This contiguous storage makes for optimal loading from slow block-devices
* like optical drives. * like optical drives.
*/ */
virtual bool addGroup(const HECL::ProjectPath& path); virtual bool addGroup(const ProjectPath& path);
/** /**
* @brief Unregister a working sub-directory as a dependency group * @brief Unregister a working sub-directory as a dependency group
* @param path directory to unregister as Dependency Group * @param path directory to unregister as Dependency Group
* @return true on success * @return true on success
*/ */
virtual bool removeGroup(const HECL::ProjectPath& path); virtual bool removeGroup(const ProjectPath& path);
/** /**
* @brief Return map populated with dataspecs targetable by this project interface * @brief Return map populated with dataspecs targetable by this project interface
@ -237,7 +239,7 @@ public:
* This method blocks execution during the procedure, with periodic * This method blocks execution during the procedure, with periodic
* feedback delivered via feedbackCb. * feedback delivered via feedbackCb.
*/ */
virtual bool cookPath(const HECL::SystemString& path, virtual bool cookPath(const ProjectPath& path,
std::function<void(std::string&, Cost, unsigned)> feedbackCb, std::function<void(std::string&, Cost, unsigned)> feedbackCb,
bool recursive=false); bool recursive=false);
@ -262,7 +264,7 @@ public:
* Developers understand how useful 'clean' is. While ideally not required, * Developers understand how useful 'clean' is. While ideally not required,
* it's useful for verifying that a rebuild from ground-up is doable. * it's useful for verifying that a rebuild from ground-up is doable.
*/ */
virtual bool cleanPath(const HECL::SystemString& path, bool recursive=false); virtual bool cleanPath(const ProjectPath& path, bool recursive=false);
/** /**
* @brief Nodegraph class for gathering dependency-resolved objects for packaging * @brief Nodegraph class for gathering dependency-resolved objects for packaging
@ -278,7 +280,7 @@ public:
NODE_GROUP NODE_GROUP
} type; } type;
std::string path; std::string path;
ProjectObjectBase* projectObj; ObjectBase* projectObj;
Node* sub; Node* sub;
Node* next; Node* next;
}; };
@ -294,7 +296,7 @@ public:
* @param path Subpath of project to root depsgraph at * @param path Subpath of project to root depsgraph at
* @return Populated depsgraph ready to traverse * @return Populated depsgraph ready to traverse
*/ */
virtual PackageDepsgraph buildPackageDepsgraph(const HECL::ProjectPath& path); virtual PackageDepsgraph buildPackageDepsgraph(const ProjectPath& path);
}; };
@ -308,10 +310,10 @@ public:
class IDataSpec class IDataSpec
{ {
public: public:
virtual Project::PackageDepsgraph packageData(); virtual Project::PackageDepsgraph packageData();
}; };
}
} }
#endif // HECLDATABASE_HPP #endif // HECLDATABASE_HPP

View File

@ -7,14 +7,15 @@
#include "HECL.hpp" #include "HECL.hpp"
namespace HECL
namespace HECLRuntime {
namespace Runtime
{ {
class RuntimeEntity class Entity
{ {
public: public:
enum ERuntimeEntityType enum Type
{ {
ENTITY_NONE, ENTITY_NONE,
ENTITY_OBJECT, ENTITY_OBJECT,
@ -22,13 +23,13 @@ public:
}; };
private: private:
ERuntimeEntityType m_type; Type m_type;
const std::string& m_path; const std::string& m_path;
bool m_loaded = false; bool m_loaded = false;
friend class RuntimeGroup; friend class Group;
friend class RuntimeObjectBase; friend class ObjectBase;
RuntimeEntity(ERuntimeEntityType type, const std::string& path) Entity(Type type, const std::string& path)
: m_type(type), m_path(path) {} : m_type(type), m_path(path) {}
public: public:
@ -36,7 +37,7 @@ public:
* @brief Get type of runtime object * @brief Get type of runtime object
* @return Type enum * @return Type enum
*/ */
inline ERuntimeEntityType getType() const {return m_type;} inline Type getType() const {return m_type;}
/** /**
* @brief Get database entity path * @brief Get database entity path
@ -64,15 +65,15 @@ public:
* *
* DO NOT CONSTRUCT THIS DIRECTLY!! * DO NOT CONSTRUCT THIS DIRECTLY!!
*/ */
class RuntimeGroup : public RuntimeEntity class Group : public Entity
{ {
public: public:
typedef std::vector<std::weak_ptr<const class RuntimeObjectBase>> GroupObjectsVector; typedef std::vector<std::weak_ptr<const class RuntimeObjectBase>> GroupObjectsVector;
private: private:
friend class HECLRuntime; friend class HECLRuntime;
GroupObjectsVector m_objects; GroupObjectsVector m_objects;
RuntimeGroup(const std::string& path) Group(const std::string& path)
: RuntimeEntity(ENTITY_GROUP, path) {} : Entity(ENTITY_GROUP, path) {}
public: public:
inline const GroupObjectsVector& getObjects() const {return m_objects;} inline const GroupObjectsVector& getObjects() const {return m_objects;}
}; };
@ -86,9 +87,9 @@ public:
* *
* DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!! * DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!!
*/ */
class RuntimeObjectBase : public RuntimeEntity class ObjectBase : public Entity
{ {
std::shared_ptr<const RuntimeGroup> m_parent; std::shared_ptr<const Group> m_parent;
protected: protected:
/** /**
@ -106,14 +107,14 @@ protected:
virtual void _objectWillUnload() {} virtual void _objectWillUnload() {}
public: public:
RuntimeObjectBase(const RuntimeGroup* group, const std::string& path) ObjectBase(const Group* group, const std::string& path)
: RuntimeEntity(ENTITY_OBJECT, path), m_parent(group) {} : Entity(ENTITY_OBJECT, path), m_parent(group) {}
/** /**
* @brief Get parent group of object * @brief Get parent group of object
* @return Borrowed pointer of parent RuntimeGroup * @return Borrowed pointer of parent RuntimeGroup
*/ */
inline const RuntimeGroup* getParentGroup() {return m_parent.get();} inline const Group* getParentGroup() {return m_parent.get();}
}; };
/** /**
@ -124,15 +125,15 @@ public:
* implementation automatically constructs RuntimeObjectBase and * implementation automatically constructs RuntimeObjectBase and
* RuntimeGroup instances as needed. * RuntimeGroup instances as needed.
*/ */
class HECLRuntime class Runtime
{ {
public: public:
/** /**
* @brief Constructs the HECL runtime root * @brief Constructs the HECL runtime root
* @param hlpkDirectory directory to search for .hlpk files * @param hlpkDirectory directory to search for .hlpk files
*/ */
HECLRuntime(const HECL::SystemString& hlpkDirectory); Runtime(const SystemString& hlpkDirectory);
~HECLRuntime(); ~Runtime();
/** /**
* @brief Structure indicating the load status of an object group * @brief Structure indicating the load status of an object group
@ -152,7 +153,7 @@ public:
* This method blocks until the entire containing-group is loaded. * This method blocks until the entire containing-group is loaded.
* Paths to groups or individual objects are accepted. * Paths to groups or individual objects are accepted.
*/ */
std::shared_ptr<RuntimeEntity> loadSync(const HECL::Hash& pathHash); std::shared_ptr<Entity> loadSync(const Hash& pathHash);
/** /**
* @brief Begin an asynchronous group-load transaction * @brief Begin an asynchronous group-load transaction
@ -163,11 +164,12 @@ public:
* This method returns once all group entity stubs are constructed. * This method returns once all group entity stubs are constructed.
* Paths to groups or individual objects are accepted. * Paths to groups or individual objects are accepted.
*/ */
std::shared_ptr<RuntimeEntity> loadAsync(const HECL::Hash& pathHash, std::shared_ptr<Entity> loadAsync(const Hash& pathHash,
SGroupLoadStatus* statusOut=NULL); SGroupLoadStatus* statusOut=NULL);
}; };
}
} }
#endif // HECLRUNTIME_HPP #endif // HECLRUNTIME_HPP

View File

@ -22,7 +22,7 @@ bool ProjectPath::_canonAbsPath(const SystemString& path)
SystemChar resolvedPath[PATH_MAX]; SystemChar resolvedPath[PATH_MAX];
if (!realpath(path.c_str(), resolvedPath)) if (!realpath(path.c_str(), resolvedPath))
{ {
throw std::invalid_argument("Unable to resolve '" + CSystemUTF8View(path).utf8_str() + throw std::invalid_argument("Unable to resolve '" + SystemUTF8View(path).utf8_str() +
"' as a canonicalized path"); "' as a canonicalized path");
return false; return false;
} }
@ -38,8 +38,8 @@ ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& pa
m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(), m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(),
((ProjectPath&)rootPath).m_absPath)) ((ProjectPath&)rootPath).m_absPath))
{ {
throw std::invalid_argument("'" + CSystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" + throw std::invalid_argument("'" + SystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" +
CSystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'"); SystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'");
return; return;
} }
if (m_absPath.size() == ((ProjectPath&)rootPath).m_absPath.size()) if (m_absPath.size() == ((ProjectPath&)rootPath).m_absPath.size())
@ -52,9 +52,14 @@ ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& pa
++m_relPath; ++m_relPath;
if (m_relPath[0] == _S('\0')) if (m_relPath[0] == _S('\0'))
m_relPath = NULL; m_relPath = NULL;
#if HECL_UCS2
m_utf8AbsPath = WideToUTF8(m_absPath);
m_utf8RelPath = m_utf8AbsPath.c_str() + ((ProjectPath&)rootPath).m_utf8AbsPath.size();
#endif
} }
ProjectPath::PathType ProjectPath::getPathType() ProjectPath::PathType ProjectPath::getPathType() const
{ {
if (std::regex_search(m_absPath, regGLOB)) if (std::regex_search(m_absPath, regGLOB))
return PT_GLOB; return PT_GLOB;
@ -123,7 +128,7 @@ static void _recursiveGlob(std::vector<SystemString>& outPaths,
#endif #endif
} }
void ProjectPath::getGlobResults(std::vector<SystemString>& outPaths) void ProjectPath::getGlobResults(std::vector<SystemString>& outPaths) const
{ {
#if _WIN32 #if _WIN32
TSystemPath itStr; TSystemPath itStr;

View File

@ -6,7 +6,9 @@
#include "HECLDatabase.hpp" #include "HECLDatabase.hpp"
namespace HECLDatabase namespace HECL
{
namespace Database
{ {
/********************************************** /**********************************************
@ -31,10 +33,10 @@ static inline bool CheckNewLineAdvance(std::string::const_iterator& it)
return false; return false;
} }
Project::ConfigFile::ConfigFile(const Project& project, const HECL::SystemString& name) Project::ConfigFile::ConfigFile(const Project& project, const SystemString& name)
: m_project(project), m_name(name) : m_project(project), m_name(name)
{ {
m_filepath = project.m_rootPath + _S("/.hecl/config/") + name; m_filepath = project.m_rootPath.getAbsolutePath() + _S("/.hecl/config/") + name;
} }
std::vector<std::string> Project::ConfigFile::readLines() std::vector<std::string> Project::ConfigFile::readLines()
@ -118,38 +120,39 @@ bool Project::ConfigFile::checkForLine(const std::string& refLine)
* Project * Project
**********************************************/ **********************************************/
Project::Project(const std::string& rootPath) Project::Project(const ProjectRootPath& rootPath)
: m_rootPath(rootPath) : m_rootPath(rootPath)
{ {
/* Stat for existing project directory (must already exist) */ /* Stat for existing project directory (must already exist) */
struct stat myStat; struct stat myStat;
if (stat(m_rootPath.c_str(), &myStat)) if (HECL::Stat(m_rootPath.getAbsolutePath().c_str(), &myStat))
throw std::error_code(errno, std::system_category()); throw std::error_code(errno, std::system_category());
if (!S_ISDIR(myStat.st_mode)) if (!S_ISDIR(myStat.st_mode))
throw std::invalid_argument("provided path must be a directory; '" + m_rootPath + "' isn't"); throw std::invalid_argument("provided path must be a directory; '" +
m_rootPath.getAbsolutePathUTF8() + "' isn't");
/* Create project directory structure */ /* Create project directory structure */
HECL::MakeDir(m_rootPath + "/.hecl"); HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl"));
HECL::MakeDir(m_rootPath + "/.hecl/cooked"); HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/cooked"));
HECL::MakeDir(m_rootPath + "/.hecl/config"); HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/config"));
/* Create or open databases */ /* Create or open databases */
} }
void Project::registerLogger(HECL::TLogger logger) void Project::registerLogger(FLogger logger)
{ {
} }
const HECL::ProjectRootPath& Project::getProjectRootPath(bool absolute) const const ProjectRootPath& Project::getProjectRootPath(bool absolute) const
{ {
} }
bool Project::addPaths(const std::vector<HECL::ProjectPath>& paths) bool Project::addPaths(const std::vector<ProjectPath>& paths)
{ {
} }
bool Project::removePaths(const std::vector<HECL::ProjectPath>& paths, bool recursive) bool Project::removePaths(const std::vector<ProjectPath>& paths, bool recursive)
{ {
} }
@ -157,7 +160,7 @@ bool Project::addGroup(const HECL::ProjectPath& path)
{ {
} }
bool Project::removeGroup(const HECL::ProjectPath& path) bool Project::removeGroup(const ProjectPath& path)
{ {
} }
@ -173,7 +176,7 @@ bool Project::disableDataSpecs(const std::vector<std::string>& specs)
{ {
} }
bool Project::cookPath(const std::string& path, bool Project::cookPath(const ProjectPath& path,
std::function<void(std::string&, Cost, unsigned)> feedbackCb, std::function<void(std::string&, Cost, unsigned)> feedbackCb,
bool recursive) bool recursive)
{ {
@ -183,12 +186,13 @@ void Project::interruptCook()
{ {
} }
bool Project::cleanPath(const std::string& path, bool recursive) bool Project::cleanPath(const ProjectPath& path, bool recursive)
{ {
} }
Project::PackageDepsgraph Project::buildPackageDepsgraph(const HECL::ProjectPath& path) Project::PackageDepsgraph Project::buildPackageDepsgraph(const ProjectPath& path)
{ {
} }
} }
}

View File

@ -1,4 +1,4 @@
HEADERS += HEADERS +=
SOURCES += \ SOURCES += \
$$PWD/CProject.cpp $$PWD/Project.cpp

View File

@ -1,23 +1,26 @@
#include "HECLRuntime.hpp" #include "HECLRuntime.hpp"
namespace HECLRuntime namespace HECL
{
namespace Runtime
{ {
HECLRuntime::HECLRuntime(const HECL::SystemString& hlpkDirectory) Runtime::Runtime(const HECL::SystemString& hlpkDirectory)
{ {
} }
HECLRuntime::~HECLRuntime() Runtime::~Runtime()
{ {
} }
std::shared_ptr<RuntimeEntity> HECLRuntime::loadSync(const HECL::Hash& pathHash) std::shared_ptr<Entity> Runtime::loadSync(const Hash& pathHash)
{ {
} }
std::shared_ptr<RuntimeEntity> HECLRuntime::loadAsync(const HECL::Hash& pathHash, std::shared_ptr<Entity> Runtime::loadAsync(const Hash& pathHash,
SGroupLoadStatus* statusOut) SGroupLoadStatus* statusOut)
{ {
} }
} }
}