From 5d2d2b010d2cef07f22f92c99da47a9ece30321f Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 9 Jun 2015 16:40:03 -1000 Subject: [PATCH] refactoring for wchar strings --- hecl/.gitmodules | 6 + hecl/dataspec/dataspec.cpp | 8 +- hecl/dataspec/dataspec.pro | 18 ++- hecl/dataspec/{ => hecl}/DUMB.hpp | 9 +- hecl/dataspec/{ => hecl}/HMDL.hpp | 8 +- hecl/dataspec/{ => hecl}/MATR.hpp | 8 +- hecl/dataspec/{ => hecl}/STRG.hpp | 8 +- hecl/dataspec/{ => hecl}/TXTR.hpp | 8 +- hecl/dataspec/hecl/hecl.cpp | 0 hecl/dataspec/mp1/mp1.cpp | 0 hecl/dataspec/mp1/mp1.pri | 2 + hecl/dataspec/mp2/mp2.cpp | 0 hecl/dataspec/mp2/mp2.pri | 2 + hecl/dataspec/mp3/mp3.cpp | 0 hecl/dataspec/mp3/mp3.pri | 2 + hecl/driver/CToolAdd.hpp | 64 -------- hecl/driver/CToolClean.hpp | 70 --------- hecl/driver/CToolCook.hpp | 81 ---------- hecl/driver/CToolGroup.hpp | 67 --------- hecl/driver/CToolHelp.hpp | 96 ------------ hecl/driver/CToolInit.hpp | 60 -------- hecl/driver/CToolPackage.hpp | 70 --------- hecl/driver/CToolRemove.hpp | 62 -------- hecl/driver/CToolSpec.hpp | 53 ------- hecl/driver/ToolAdd.hpp | 64 ++++++++ hecl/driver/{CToolBase.hpp => ToolBase.hpp} | 97 ++++++------ hecl/driver/ToolClean.hpp | 70 +++++++++ hecl/driver/ToolCook.hpp | 81 ++++++++++ hecl/driver/ToolGroup.hpp | 67 +++++++++ hecl/driver/ToolHelp.hpp | 96 ++++++++++++ hecl/driver/ToolInit.hpp | 60 ++++++++ hecl/driver/ToolPackage.hpp | 70 +++++++++ hecl/driver/ToolRemove.hpp | 62 ++++++++ hecl/driver/ToolSpec.hpp | 53 +++++++ hecl/driver/driver.pro | 20 +-- hecl/driver/main.cpp | 140 ++++++++++-------- hecl/extern/RetroCommon | 1 + hecl/extern/libSquish | 1 + hecl/hecl.pro | 1 - hecl/include/HECL.hpp | 132 ++++++++++++++--- hecl/include/HECLDatabase.hpp | 44 +++--- hecl/include/HECLRuntime.hpp | 48 +++--- hecl/lib/ProjectPath.cpp | 15 +- .../database/{CProject.cpp => Project.cpp} | 38 ++--- hecl/lib/database/database.pri | 2 +- hecl/lib/runtime/HECLRuntime.cpp | 15 +- 46 files changed, 1015 insertions(+), 864 deletions(-) rename hecl/dataspec/{ => hecl}/DUMB.hpp (64%) rename hecl/dataspec/{ => hecl}/HMDL.hpp (66%) rename hecl/dataspec/{ => hecl}/MATR.hpp (66%) rename hecl/dataspec/{ => hecl}/STRG.hpp (66%) rename hecl/dataspec/{ => hecl}/TXTR.hpp (76%) create mode 100644 hecl/dataspec/hecl/hecl.cpp create mode 100644 hecl/dataspec/mp1/mp1.cpp create mode 100644 hecl/dataspec/mp1/mp1.pri create mode 100644 hecl/dataspec/mp2/mp2.cpp create mode 100644 hecl/dataspec/mp2/mp2.pri create mode 100644 hecl/dataspec/mp3/mp3.cpp create mode 100644 hecl/dataspec/mp3/mp3.pri delete mode 100644 hecl/driver/CToolAdd.hpp delete mode 100644 hecl/driver/CToolClean.hpp delete mode 100644 hecl/driver/CToolCook.hpp delete mode 100644 hecl/driver/CToolGroup.hpp delete mode 100644 hecl/driver/CToolHelp.hpp delete mode 100644 hecl/driver/CToolInit.hpp delete mode 100644 hecl/driver/CToolPackage.hpp delete mode 100644 hecl/driver/CToolRemove.hpp delete mode 100644 hecl/driver/CToolSpec.hpp create mode 100644 hecl/driver/ToolAdd.hpp rename hecl/driver/{CToolBase.hpp => ToolBase.hpp} (54%) create mode 100644 hecl/driver/ToolClean.hpp create mode 100644 hecl/driver/ToolCook.hpp create mode 100644 hecl/driver/ToolGroup.hpp create mode 100644 hecl/driver/ToolHelp.hpp create mode 100644 hecl/driver/ToolInit.hpp create mode 100644 hecl/driver/ToolPackage.hpp create mode 100644 hecl/driver/ToolRemove.hpp create mode 100644 hecl/driver/ToolSpec.hpp create mode 160000 hecl/extern/RetroCommon create mode 160000 hecl/extern/libSquish rename hecl/lib/database/{CProject.cpp => Project.cpp} (75%) diff --git a/hecl/.gitmodules b/hecl/.gitmodules index 0b5c0b6e3..e63cf39c9 100644 --- a/hecl/.gitmodules +++ b/hecl/.gitmodules @@ -1,3 +1,9 @@ [submodule "extern/Athena"] path = extern/Athena 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 diff --git a/hecl/dataspec/dataspec.cpp b/hecl/dataspec/dataspec.cpp index 8d172327e..64b1bf9ed 100644 --- a/hecl/dataspec/dataspec.cpp +++ b/hecl/dataspec/dataspec.cpp @@ -1,16 +1,10 @@ #include "HECLDatabase.hpp" -#include "DUMB.hpp" -#include "HMDL.hpp" -#include "MATR.hpp" -#include "STRG.hpp" -#include "TXTR.hpp" - const std::pair DATA_SPECS[] = { {"hecl-little", "Targets little-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-cafe", "Targets Wii U apps using the HECL runtime"}, - + {"mp1", ""} }; diff --git a/hecl/dataspec/dataspec.pro b/hecl/dataspec/dataspec.pro index fa5268627..edff6bc6c 100644 --- a/hecl/dataspec/dataspec.pro +++ b/hecl/dataspec/dataspec.pro @@ -9,15 +9,19 @@ unix:LIBS += -std=c++11 clang:QMAKE_CXXFLAGS += -stdlib=libc++ 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 += \ - helpers.hpp \ - DUMB.hpp \ - HMDL.hpp \ - MATR.hpp \ - STRG.hpp \ - TXTR.hpp + helpers.hpp SOURCES += \ helpers.cpp \ diff --git a/hecl/dataspec/DUMB.hpp b/hecl/dataspec/hecl/DUMB.hpp similarity index 64% rename from hecl/dataspec/DUMB.hpp rename to hecl/dataspec/hecl/DUMB.hpp index b977177d0..457391070 100644 --- a/hecl/dataspec/DUMB.hpp +++ b/hecl/dataspec/hecl/DUMB.hpp @@ -1,11 +1,12 @@ #ifndef DUMB_HPP #define DUMB_HPP +#include "HECLDatabase.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, 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) { diff --git a/hecl/dataspec/HMDL.hpp b/hecl/dataspec/hecl/HMDL.hpp similarity index 66% rename from hecl/dataspec/HMDL.hpp rename to hecl/dataspec/hecl/HMDL.hpp index 439d1d4b0..9ca28086d 100644 --- a/hecl/dataspec/HMDL.hpp +++ b/hecl/dataspec/hecl/HMDL.hpp @@ -4,9 +4,9 @@ #include "HECLDatabase.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, 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) { diff --git a/hecl/dataspec/MATR.hpp b/hecl/dataspec/hecl/MATR.hpp similarity index 66% rename from hecl/dataspec/MATR.hpp rename to hecl/dataspec/hecl/MATR.hpp index 5e0d58ed1..7b682dc6c 100644 --- a/hecl/dataspec/MATR.hpp +++ b/hecl/dataspec/hecl/MATR.hpp @@ -4,9 +4,9 @@ #include "HECLDatabase.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, 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) { diff --git a/hecl/dataspec/STRG.hpp b/hecl/dataspec/hecl/STRG.hpp similarity index 66% rename from hecl/dataspec/STRG.hpp rename to hecl/dataspec/hecl/STRG.hpp index 7387d8c42..d90b8f610 100644 --- a/hecl/dataspec/STRG.hpp +++ b/hecl/dataspec/hecl/STRG.hpp @@ -4,9 +4,9 @@ #include "HECLDatabase.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, 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) { diff --git a/hecl/dataspec/TXTR.hpp b/hecl/dataspec/hecl/TXTR.hpp similarity index 76% rename from hecl/dataspec/TXTR.hpp rename to hecl/dataspec/hecl/TXTR.hpp index 16527a536..943cdf49d 100644 --- a/hecl/dataspec/TXTR.hpp +++ b/hecl/dataspec/hecl/TXTR.hpp @@ -5,9 +5,9 @@ #include "HECLRuntime.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, 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) { diff --git a/hecl/dataspec/hecl/hecl.cpp b/hecl/dataspec/hecl/hecl.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/hecl/dataspec/mp1/mp1.cpp b/hecl/dataspec/mp1/mp1.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/hecl/dataspec/mp1/mp1.pri b/hecl/dataspec/mp1/mp1.pri new file mode 100644 index 000000000..f30e8b372 --- /dev/null +++ b/hecl/dataspec/mp1/mp1.pri @@ -0,0 +1,2 @@ +SOURCES += \ + $$PWD/mp1.cpp diff --git a/hecl/dataspec/mp2/mp2.cpp b/hecl/dataspec/mp2/mp2.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/hecl/dataspec/mp2/mp2.pri b/hecl/dataspec/mp2/mp2.pri new file mode 100644 index 000000000..afaad83b0 --- /dev/null +++ b/hecl/dataspec/mp2/mp2.pri @@ -0,0 +1,2 @@ +SOURCES += \ + $$PWD/mp2.cpp diff --git a/hecl/dataspec/mp3/mp3.cpp b/hecl/dataspec/mp3/mp3.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/hecl/dataspec/mp3/mp3.pri b/hecl/dataspec/mp3/mp3.pri new file mode 100644 index 000000000..50b65534d --- /dev/null +++ b/hecl/dataspec/mp3/mp3.pri @@ -0,0 +1,2 @@ +SOURCES += \ + $$PWD/mp3.cpp diff --git a/hecl/driver/CToolAdd.hpp b/hecl/driver/CToolAdd.hpp deleted file mode 100644 index 104a18918..000000000 --- a/hecl/driver/CToolAdd.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef CTOOL_ADD -#define CTOOL_ADD - -#include "CToolBase.hpp" -#include - -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 [...]\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("...", "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 diff --git a/hecl/driver/CToolClean.hpp b/hecl/driver/CToolClean.hpp deleted file mode 100644 index de8b9df3b..000000000 --- a/hecl/driver/CToolClean.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CTOOL_CLEAN -#define CTOOL_CLEAN - -#include "CToolBase.hpp" -#include - -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] [...]\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("...", "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 diff --git a/hecl/driver/CToolCook.hpp b/hecl/driver/CToolCook.hpp deleted file mode 100644 index d8b3f2169..000000000 --- a/hecl/driver/CToolCook.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef CTOOL_COOK -#define CTOOL_COOK - -#include "CToolBase.hpp" -#include - -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] [...]\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("...", "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 diff --git a/hecl/driver/CToolGroup.hpp b/hecl/driver/CToolGroup.hpp deleted file mode 100644 index 4648f44e1..000000000 --- a/hecl/driver/CToolGroup.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef CTOOL_GROUP -#define CTOOL_GROUP - -#include "CToolBase.hpp" -#include - -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] \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("", "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 diff --git a/hecl/driver/CToolHelp.hpp b/hecl/driver/CToolHelp.hpp deleted file mode 100644 index 32aa0f8fe..000000000 --- a/hecl/driver/CToolHelp.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef CTOOL_HELP -#define CTOOL_HELP - -#include "CToolBase.hpp" -#include -#include -#include - -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 diff --git a/hecl/driver/CToolInit.hpp b/hecl/driver/CToolInit.hpp deleted file mode 100644 index e59e4efb1..000000000 --- a/hecl/driver/CToolInit.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef CTOOL_INIT -#define CTOOL_INIT - -#include "CToolBase.hpp" -#include - -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 []\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("", "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 diff --git a/hecl/driver/CToolPackage.hpp b/hecl/driver/CToolPackage.hpp deleted file mode 100644 index a6035a630..000000000 --- a/hecl/driver/CToolPackage.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CTOOL_PACKAGE -#define CTOOL_PACKAGE - -#include -#include -#include "CToolBase.hpp" -#include - -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 ] []\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("", "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 ", "output package file"); - help.beginWrap(); - help.wrap("Specifies a target path to write the package. If not specified, the package " - "is written into /out//.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 diff --git a/hecl/driver/CToolRemove.hpp b/hecl/driver/CToolRemove.hpp deleted file mode 100644 index 7e8c1428d..000000000 --- a/hecl/driver/CToolRemove.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef CTOOL_REMOVE -#define CTOOL_REMOVE - -#include "CToolBase.hpp" -#include - -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] [...]\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("...", "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 diff --git a/hecl/driver/CToolSpec.hpp b/hecl/driver/CToolSpec.hpp deleted file mode 100644 index 67e499dce..000000000 --- a/hecl/driver/CToolSpec.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef CTOOL_SPEC -#define CTOOL_SPEC - -#include "CToolBase.hpp" -#include - -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] [...]\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("...", "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 diff --git a/hecl/driver/ToolAdd.hpp b/hecl/driver/ToolAdd.hpp new file mode 100644 index 000000000..5844820e0 --- /dev/null +++ b/hecl/driver/ToolAdd.hpp @@ -0,0 +1,64 @@ +#ifndef CTOOL_ADD +#define CTOOL_ADD + +#include "ToolBase.hpp" +#include + +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 [...]\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("..."), _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 diff --git a/hecl/driver/CToolBase.hpp b/hecl/driver/ToolBase.hpp similarity index 54% rename from hecl/driver/CToolBase.hpp rename to hecl/driver/ToolBase.hpp index 51063ab15..ada95fe06 100644 --- a/hecl/driver/CToolBase.hpp +++ b/hecl/driver/ToolBase.hpp @@ -9,25 +9,25 @@ #include #include -struct SToolPassInfo +struct ToolPassInfo { - std::string pname; - std::string cwd; - std::vector args; - std::string output; + HECL::SystemString pname; + HECL::SystemString cwd; + std::vector args; + HECL::SystemString output; unsigned verbosityLevel = 0; bool force = false; }; -class CToolBase +class ToolBase { protected: - const SToolPassInfo& m_info; + const ToolPassInfo& m_info; public: - CToolBase(const SToolPassInfo& info) + ToolBase(const ToolPassInfo& info) : m_info(info) {} - virtual ~CToolBase() {} - virtual std::string toolName() const=0; + virtual ~ToolBase() {} + virtual HECL::SystemString toolName() const=0; virtual int run()=0; }; @@ -41,51 +41,51 @@ public: extern bool XTERM_COLOR; -class CHelpOutput +class HelpOutput { public: - typedef void(*THelpFunc)(CHelpOutput&); + typedef void(*HelpFunc)(HelpOutput&); private: FILE* m_sout; - THelpFunc m_helpFunc; + HelpFunc m_helpFunc; int m_lineWidth; - std::string m_wrapBuffer; + HECL::SystemString m_wrapBuffer; - void _wrapBuf(std::string& string) + void _wrapBuf(HECL::SystemString& string) { int counter; - std::string::iterator it = string.begin(); + HECL::SystemString::iterator it = string.begin(); while (it != string.end()) { - std::string::iterator v=it; + HECL::SystemString::iterator v=it; /* copy string until the end of the line is reached */ for (counter=WRAP_INDENT ; counter < m_lineWidth ; ++counter) { - if (*it == '\n') + if (*it == _S('\n')) { counter = WRAP_INDENT; ++it; } 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()) return; - if (*it != '\n') + if (*it != _S('\n')) ++it; } /* check for whitespace */ if (isspace(*it)) { - *it = '\n'; + *it = _S('\n'); counter = WRAP_INDENT; ++it; } else { /* 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)) { @@ -93,10 +93,10 @@ private: if (k < v) { k = it; - string.insert(k, '\n'); + string.insert(k, _S('\n')); } else - *k = '\n'; + *k = _S('\n'); it = k + 1; break; } @@ -107,19 +107,29 @@ private: public: - CHelpOutput(THelpFunc helpFunc) + HelpOutput(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; m_lineWidth = 80; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) m_lineWidth = w.ws_col; +#endif if (m_lineWidth < 10) m_lineWidth = 10; } void go() { +#if _WIN32 + m_sout = stdout; + m_helpFunc(*this); +#else m_sout = popen("less -R", "w"); if (m_sout) { @@ -131,35 +141,36 @@ public: m_sout = stdout; 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) - fprintf(m_sout, BOLD "%s" NORMAL, str); + HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL ""), str); 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) - fprintf(m_sout, BOLD "%s" NORMAL "\n", headName); + HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL "\n"), headName); 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) - fprintf(m_sout, BOLD "%s" NORMAL " (%s)\n", flag, synopsis); + HECL::FPrintf(m_sout, _S("" BOLD "%s" NORMAL " (%s)\n"), flag, synopsis); else - fprintf(m_sout, "%s (%s)\n", flag, synopsis); + HECL::FPrintf(m_sout, _S("%s (%s)\n"), flag, synopsis); } void beginWrap() @@ -167,23 +178,25 @@ public: m_wrapBuffer.clear(); } - void wrap(const char* str) + void wrap(const HECL::SystemChar* 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 += NORMAL; + if (XTERM_COLOR) + m_wrapBuffer += _S("" NORMAL ""); } void endWrap() { _wrapBuf(m_wrapBuffer); - m_wrapBuffer += '\n'; - fputs(m_wrapBuffer.c_str(), m_sout); + m_wrapBuffer += _S('\n'); + HECL::FPrintf(m_sout, _S("%s"), m_wrapBuffer.c_str()); m_wrapBuffer.clear(); } }; diff --git a/hecl/driver/ToolClean.hpp b/hecl/driver/ToolClean.hpp new file mode 100644 index 000000000..74c6265f9 --- /dev/null +++ b/hecl/driver/ToolClean.hpp @@ -0,0 +1,70 @@ +#ifndef CTOOL_CLEAN +#define CTOOL_CLEAN + +#include "ToolBase.hpp" +#include + +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] [...]\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("..."), _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 diff --git a/hecl/driver/ToolCook.hpp b/hecl/driver/ToolCook.hpp new file mode 100644 index 000000000..0ba637a68 --- /dev/null +++ b/hecl/driver/ToolCook.hpp @@ -0,0 +1,81 @@ +#ifndef CTOOL_COOK +#define CTOOL_COOK + +#include "ToolBase.hpp" +#include + +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] [...]\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("..."), _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 diff --git a/hecl/driver/ToolGroup.hpp b/hecl/driver/ToolGroup.hpp new file mode 100644 index 000000000..a1e71d247 --- /dev/null +++ b/hecl/driver/ToolGroup.hpp @@ -0,0 +1,67 @@ +#ifndef CTOOL_GROUP +#define CTOOL_GROUP + +#include "ToolBase.hpp" +#include + +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] \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(""), _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 diff --git a/hecl/driver/ToolHelp.hpp b/hecl/driver/ToolHelp.hpp new file mode 100644 index 000000000..78bf7513c --- /dev/null +++ b/hecl/driver/ToolHelp.hpp @@ -0,0 +1,96 @@ +#ifndef CTOOL_HELP +#define CTOOL_HELP + +#include "ToolBase.hpp" +#include +#include +#include + +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 diff --git a/hecl/driver/ToolInit.hpp b/hecl/driver/ToolInit.hpp new file mode 100644 index 000000000..e90a2d745 --- /dev/null +++ b/hecl/driver/ToolInit.hpp @@ -0,0 +1,60 @@ +#ifndef CTOOL_INIT +#define CTOOL_INIT + +#include "ToolBase.hpp" +#include + +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 []\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(""), _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 diff --git a/hecl/driver/ToolPackage.hpp b/hecl/driver/ToolPackage.hpp new file mode 100644 index 000000000..a793be930 --- /dev/null +++ b/hecl/driver/ToolPackage.hpp @@ -0,0 +1,70 @@ +#ifndef CTOOL_PACKAGE +#define CTOOL_PACKAGE + +#include +#include +#include "ToolBase.hpp" +#include + +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 ] []\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(""), _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 "), _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 /out//.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 diff --git a/hecl/driver/ToolRemove.hpp b/hecl/driver/ToolRemove.hpp new file mode 100644 index 000000000..80d9dd415 --- /dev/null +++ b/hecl/driver/ToolRemove.hpp @@ -0,0 +1,62 @@ +#ifndef CTOOL_REMOVE +#define CTOOL_REMOVE + +#include "ToolBase.hpp" +#include + +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] [...]\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("..."), _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 diff --git a/hecl/driver/ToolSpec.hpp b/hecl/driver/ToolSpec.hpp new file mode 100644 index 000000000..cc39f2290 --- /dev/null +++ b/hecl/driver/ToolSpec.hpp @@ -0,0 +1,53 @@ +#ifndef CTOOL_SPEC +#define CTOOL_SPEC + +#include "ToolBase.hpp" +#include + +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] [...]\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("..."), _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 diff --git a/hecl/driver/driver.pro b/hecl/driver/driver.pro index 6d4927072..42484a63e 100644 --- a/hecl/driver/driver.pro +++ b/hecl/driver/driver.pro @@ -24,14 +24,14 @@ SOURCES += \ $$PWD/main.cpp HEADERS += \ - CToolBase.hpp \ - CToolPackage.hpp \ - CToolInit.hpp \ - CToolHelp.hpp \ - CToolGroup.hpp \ - CToolCook.hpp \ - CToolClean.hpp \ - CToolAdd.hpp \ - CToolRemove.hpp \ - CToolSpec.hpp + ToolBase.hpp \ + ToolPackage.hpp \ + ToolInit.hpp \ + ToolHelp.hpp \ + ToolGroup.hpp \ + ToolCook.hpp \ + ToolClean.hpp \ + ToolAdd.hpp \ + ToolRemove.hpp \ + ToolSpec.hpp diff --git a/hecl/driver/main.cpp b/hecl/driver/main.cpp index bf1fbc3a0..490e4a604 100644 --- a/hecl/driver/main.cpp +++ b/hecl/driver/main.cpp @@ -7,46 +7,52 @@ #include #include -#include "CToolBase.hpp" -#include "CToolInit.hpp" -#include "CToolSpec.hpp" -#include "CToolAdd.hpp" -#include "CToolRemove.hpp" -#include "CToolGroup.hpp" -#include "CToolCook.hpp" -#include "CToolClean.hpp" -#include "CToolPackage.hpp" -#include "CToolHelp.hpp" +#include "ToolBase.hpp" +#include "ToolInit.hpp" +#include "ToolSpec.hpp" +#include "ToolAdd.hpp" +#include "ToolRemove.hpp" +#include "ToolGroup.hpp" +#include "ToolCook.hpp" +#include "ToolClean.hpp" +#include "ToolPackage.hpp" +#include "ToolHelp.hpp" 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 */ -static void printHelp(const char* pname) +static void printHelp(const HECL::SystemChar* pname) { if (XTERM_COLOR) - printf(BOLD "HECL" NORMAL); + HECL::Printf(_S("" BOLD "HECL" NORMAL "")); else - printf("HECL"); + HECL::Printf(_S("HECL")); #if HECL_GIT - printf(" Commit " #HECL_GIT " (" #HECL_BRANCH ")\n" - "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); + HECL::Printf(_S(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname); #elif HECL_VER - printf(" Version " #HECL_VER "\n" - "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); + HECL::Printf(_S(" Version " HECL_VER_S "\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname); #else - printf("\n" - "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); + HECL::Printf(_S("\nUsage: %s init|add|remove|group|cook|clean|package|help\n"), pname); #endif } /* Regex patterns */ -static const std::regex regOPEN("-o([^\"]*|\\S*))", std::regex::ECMAScript|std::regex::optimize); -static const std::regex regVERBOSE("-v(v*)", std::regex::ECMAScript|std::regex::optimize); -static const std::regex regFORCE("-f", std::regex::ECMAScript|std::regex::optimize); +static const HECL::SystemRegex regOPEN(_S("-o([^\"]*|\\S*))"), std::regex::ECMAScript|std::regex::optimize); +static const HECL::SystemRegex regVERBOSE(_S("-v(v*)"), std::regex::ECMAScript|std::regex::optimize); +static const HECL::SystemRegex regFORCE(_S("-f"), std::regex::ECMAScript|std::regex::optimize); #include "../blender/CBlenderConnection.hpp" +#if HECL_UCS2 +int wmain(int argc, const wchar_t** argv) +#else int main(int argc, const char** argv) +#endif { /* Xterm check */ const char* term = getenv("TERM"); @@ -64,32 +70,32 @@ int main(int argc, const char** argv) } else if (argc == 0) { - printHelp("hecl"); + printHelp(_S("hecl")); return 0; } /* Assemble common tool pass info */ - SToolPassInfo info; + ToolPassInfo info; info.pname = argv[0]; - char cwdbuf[MAXPATHLEN]; - if (getcwd(cwdbuf, MAXPATHLEN)) + HECL::SystemChar cwdbuf[MAXPATHLEN]; + if (HECL::Getcwd(cwdbuf, MAXPATHLEN)) info.cwd = cwdbuf; /* Concatenate args */ - std::list args; + std::list args; for (int i=2 ; i::const_iterator it = args.begin() ; it != args.end() ;) + for (std::list::const_iterator it = args.begin() ; it != args.end() ;) { - const std::string& arg = *it; - std::smatch oMatch; + const HECL::SystemString& arg = *it; + HECL::SystemRegexMatch oMatch; 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 (info.output.empty()) @@ -111,10 +117,10 @@ int main(int argc, const char** argv) } /* Count verbosity */ - for (std::list::const_iterator it = args.begin() ; it != args.end() ;) + for (std::list::const_iterator it = args.begin() ; it != args.end() ;) { - const std::string& arg = *it; - std::smatch vMatch; + const HECL::SystemString& arg = *it; + HECL::SystemRegexMatch vMatch; if (std::regex_search(arg, vMatch, regVERBOSE)) { ++info.verbosityLevel; @@ -126,9 +132,9 @@ int main(int argc, const char** argv) } /* Check force argument */ - for (std::list::const_iterator it = args.begin() ; it != args.end() ;) + for (std::list::const_iterator it = args.begin() ; it != args.end() ;) { - const std::string& arg = *it; + const HECL::SystemString& arg = *it; if (std::regex_search(arg, regFORCE)) { info.force = true; @@ -139,46 +145,52 @@ int main(int argc, const char** argv) } /* Gather remaining args */ - for (const std::string& arg : args) + for (const HECL::SystemString& arg : args) info.args.push_back(arg); } /* 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); - CToolBase* tool = NULL; +#endif + ToolBase* tool = NULL; try { - if (toolName == "init") - tool = new CToolInit(info); - else if (toolName == "platform") - tool = new CToolPlatform(info); - else if (toolName == "add") - tool = new CToolAdd(info); - else if (toolName == "remove" || toolName == "rm") - tool = new CToolRemove(info); - else if (toolName == "group") - tool = new CToolGroup(info); - else if (toolName == "cook") - tool = new CToolCook(info); - else if (toolName == "clean") - tool = new CToolClean(info); - else if (toolName == "package" || toolName == "pack") - tool = new CToolPackage(info); - else if (toolName == "help") - tool = new CToolHelp(info); + if (toolName == _S("init")) + tool = new ToolInit(info); + else if (toolName == _S("spec")) + tool = new ToolSpec(info); + else if (toolName == _S("add")) + tool = new ToolAdd(info); + else if (toolName == _S("remove") || toolName == _S("rm")) + tool = new ToolRemove(info); + else if (toolName == _S("group")) + tool = new ToolGroup(info); + else if (toolName == _S("cook")) + tool = new ToolCook(info); + else if (toolName == _S("clean")) + tool = new ToolClean(info); + else if (toolName == _S("package") || toolName == _S("pack")) + tool = new ToolPackage(info); + else if (toolName == _S("help")) + tool = new ToolHelp(info); 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; return -1; } 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 */ int retval; @@ -186,9 +198,9 @@ int main(int argc, const char** argv) { 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; return -1; } diff --git a/hecl/extern/RetroCommon b/hecl/extern/RetroCommon new file mode 160000 index 000000000..de29d0862 --- /dev/null +++ b/hecl/extern/RetroCommon @@ -0,0 +1 @@ +Subproject commit de29d08623c8807c85e996f81b71e9339466067c diff --git a/hecl/extern/libSquish b/hecl/extern/libSquish new file mode 160000 index 000000000..7c6789543 --- /dev/null +++ b/hecl/extern/libSquish @@ -0,0 +1 @@ +Subproject commit 7c67895430d88d4971e3197f9a4eeba3ba0f6d35 diff --git a/hecl/hecl.pro b/hecl/hecl.pro index a9431b9bf..1ec2b4aec 100644 --- a/hecl/hecl.pro +++ b/hecl/hecl.pro @@ -20,7 +20,6 @@ HEADERS += \ SUBDIRS += \ extern/blowfish \ extern/libpng \ - extern/Athena \ blender \ lib \ dataspec \ diff --git a/hecl/include/HECL.hpp b/hecl/include/HECL.hpp index 2ab29a878..d1415291d 100644 --- a/hecl/include/HECL.hpp +++ b/hecl/include/HECL.hpp @@ -10,6 +10,7 @@ char* win_realpath(const char* name, char* restrict resolved); #include #endif +#include #include #include #include @@ -20,27 +21,31 @@ char* win_realpath(const char* name, char* restrict resolved); namespace HECL { +#if _WIN32 && UNICODE +#define HECL_UCS2 1 +#endif + std::string WideToUTF8(const std::wstring& src); std::wstring UTF8ToWide(const std::string& src); -#if _WIN32 && UNICODE +#if HECL_UCS2 typedef wchar_t SystemChar; typedef std::wstring SystemString; -class CSystemUTF8View +class SystemUTF8View { std::string m_utf8; public: - CSystemUTF8View(const SystemString& str) + SystemUTF8View(const SystemString& str) : m_utf8(WideToUTF8(str)) {} inline const std::string& utf8_str() {return m_utf8;} }; -class CSystemStringView +class SystemStringView { std::wstring m_sys; public: - CSystemStringView(const std::string& str) + SystemStringView(const std::string& 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 #define _S(val) L ## val @@ -48,19 +53,19 @@ public: #else typedef char SystemChar; typedef std::string SystemString; -class CSystemUTF8View +class SystemUTF8View { const std::string& m_utf8; public: - CSystemUTF8View(const SystemString& str) + SystemUTF8View(const SystemString& str) : m_utf8(str) {} inline const std::string& utf8_str() {return m_utf8;} }; -class CSystemStringView +class SystemStringView { const std::string& m_sys; public: - CSystemStringView(const std::string& str) + SystemStringView(const std::string& str) : m_sys(str) {} inline const std::string& sys_str() {return m_sys;} }; @@ -69,6 +74,31 @@ public: #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) { #if _WIN32 @@ -83,9 +113,18 @@ static inline void MakeDir(const SystemString& dir) #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) { -#if _WIN32 && UNICODE +#if HECL_UCS2 FILE* fp = wfopen(path, mode); #else FILE* fp = fopen(path, mode); @@ -96,6 +135,39 @@ static inline FILE* Fopen(const SystemChar* path, const SystemChar* mode) 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 SystemRegex; typedef std::regex_token_iterator SystemRegexTokenIterator; typedef std::match_results SystemRegexMatch; @@ -115,7 +187,7 @@ enum LogType /** * @brief Logger callback type */ -typedef std::function TLogger; +typedef std::function FLogger; /** * @brief FourCC representation used within HECL's database @@ -183,6 +255,10 @@ class ProjectPath protected: SystemString m_absPath; const SystemChar* m_relPath = NULL; +#if HECL_UCS2 + std::string m_utf8AbsPath; + const char* m_utf8RelPath; +#endif ProjectPath() {} bool _canonAbsPath(const SystemString& path); public: @@ -197,25 +273,47 @@ public: * @brief Determine if ProjectPath represents 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 * @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 * @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) return m_relPath; 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 */ @@ -231,13 +329,13 @@ public: * @brief Get type of path based on syntax and filesystem queries * @return Type of path */ - PathType getPathType(); + PathType getPathType() const; /** * @brief Insert glob matches into existing vector * @param outPaths Vector to add matches to (will not erase existing contents) */ - void getGlobResults(std::vector& outPaths); + void getGlobResults(std::vector& outPaths) const; }; /** diff --git a/hecl/include/HECLDatabase.hpp b/hecl/include/HECLDatabase.hpp index e35cf99d3..97445f6da 100644 --- a/hecl/include/HECLDatabase.hpp +++ b/hecl/include/HECLDatabase.hpp @@ -13,7 +13,9 @@ #include "HECL.hpp" -namespace HECLDatabase +namespace HECL +{ +namespace Database { /** @@ -25,9 +27,9 @@ namespace HECLDatabase * * DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!! */ -class ProjectObjectBase +class ObjectBase { - friend class CProject; + friend class Project; std::string m_path; protected: @@ -69,7 +71,7 @@ protected: DataEndianness endianness, DataPlatform platform) {(void)dataAppender;(void)endianness;(void)platform;return true;} - typedef std::function FDepAdder; + typedef std::function FDepAdder; /** * @brief Optional private method implemented by CProjectObject subclasses to resolve dependencies @@ -83,7 +85,7 @@ protected: {(void)depAdder;} public: - ProjectObjectBase(const std::string& path) + ObjectBase(const std::string& path) : m_path(path) {} inline const std::string& getPath() const {return m_path;} @@ -106,17 +108,17 @@ public: */ class Project { - HECL::SystemString m_rootPath; + ProjectRootPath m_rootPath; public: - Project(const std::string& rootPath); + Project(const HECL::ProjectRootPath& rootPath); class ConfigFile { const Project& m_project; - const HECL::SystemString& m_name; - HECL::SystemString m_filepath; + const SystemString& m_name; + SystemString m_filepath; public: - ConfigFile(const Project& project, const HECL::SystemString& name); + ConfigFile(const Project& project, const SystemString& name); std::vector readLines(); void addLine(const std::string& line); void removeLine(const std::string& refLine); @@ -152,7 +154,7 @@ public: * * 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 @@ -161,7 +163,7 @@ public: * * 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 @@ -170,7 +172,7 @@ public: * * This method blocks while object hashing takes place */ - virtual bool addPaths(const std::vector& paths); + virtual bool addPaths(const std::vector& paths); /** * @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 * directory. It will delete associated cooked objects though. */ - virtual bool removePaths(const std::vector& paths, bool recursive=false); + virtual bool removePaths(const std::vector& paths, bool recursive=false); /** * @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 * 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 * @param path directory to unregister as Dependency Group * @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 @@ -237,7 +239,7 @@ public: * This method blocks execution during the procedure, with periodic * feedback delivered via feedbackCb. */ - virtual bool cookPath(const HECL::SystemString& path, + virtual bool cookPath(const ProjectPath& path, std::function feedbackCb, bool recursive=false); @@ -262,7 +264,7 @@ public: * Developers understand how useful 'clean' is. While ideally not required, * 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 @@ -278,7 +280,7 @@ public: NODE_GROUP } type; std::string path; - ProjectObjectBase* projectObj; + ObjectBase* projectObj; Node* sub; Node* next; }; @@ -294,7 +296,7 @@ public: * @param path Subpath of project to root depsgraph at * @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 { public: - virtual Project::PackageDepsgraph packageData(); }; +} } #endif // HECLDATABASE_HPP diff --git a/hecl/include/HECLRuntime.hpp b/hecl/include/HECLRuntime.hpp index 6e7e245ed..6bdd42ab1 100644 --- a/hecl/include/HECLRuntime.hpp +++ b/hecl/include/HECLRuntime.hpp @@ -7,14 +7,15 @@ #include "HECL.hpp" - -namespace HECLRuntime +namespace HECL +{ +namespace Runtime { -class RuntimeEntity +class Entity { public: - enum ERuntimeEntityType + enum Type { ENTITY_NONE, ENTITY_OBJECT, @@ -22,13 +23,13 @@ public: }; private: - ERuntimeEntityType m_type; + Type m_type; const std::string& m_path; bool m_loaded = false; - friend class RuntimeGroup; - friend class RuntimeObjectBase; - RuntimeEntity(ERuntimeEntityType type, const std::string& path) + friend class Group; + friend class ObjectBase; + Entity(Type type, const std::string& path) : m_type(type), m_path(path) {} public: @@ -36,7 +37,7 @@ public: * @brief Get type of runtime object * @return Type enum */ - inline ERuntimeEntityType getType() const {return m_type;} + inline Type getType() const {return m_type;} /** * @brief Get database entity path @@ -64,15 +65,15 @@ public: * * DO NOT CONSTRUCT THIS DIRECTLY!! */ -class RuntimeGroup : public RuntimeEntity +class Group : public Entity { public: typedef std::vector> GroupObjectsVector; private: friend class HECLRuntime; GroupObjectsVector m_objects; - RuntimeGroup(const std::string& path) - : RuntimeEntity(ENTITY_GROUP, path) {} + Group(const std::string& path) + : Entity(ENTITY_GROUP, path) {} public: inline const GroupObjectsVector& getObjects() const {return m_objects;} }; @@ -86,9 +87,9 @@ public: * * DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!! */ -class RuntimeObjectBase : public RuntimeEntity +class ObjectBase : public Entity { - std::shared_ptr m_parent; + std::shared_ptr m_parent; protected: /** @@ -106,14 +107,14 @@ protected: virtual void _objectWillUnload() {} public: - RuntimeObjectBase(const RuntimeGroup* group, const std::string& path) - : RuntimeEntity(ENTITY_OBJECT, path), m_parent(group) {} + ObjectBase(const Group* group, const std::string& path) + : Entity(ENTITY_OBJECT, path), m_parent(group) {} /** * @brief Get parent group of object * @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 * RuntimeGroup instances as needed. */ -class HECLRuntime +class Runtime { public: /** * @brief Constructs the HECL runtime root * @param hlpkDirectory directory to search for .hlpk files */ - HECLRuntime(const HECL::SystemString& hlpkDirectory); - ~HECLRuntime(); + Runtime(const SystemString& hlpkDirectory); + ~Runtime(); /** * @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. * Paths to groups or individual objects are accepted. */ - std::shared_ptr loadSync(const HECL::Hash& pathHash); + std::shared_ptr loadSync(const Hash& pathHash); /** * @brief Begin an asynchronous group-load transaction @@ -163,11 +164,12 @@ public: * This method returns once all group entity stubs are constructed. * Paths to groups or individual objects are accepted. */ - std::shared_ptr loadAsync(const HECL::Hash& pathHash, - SGroupLoadStatus* statusOut=NULL); + std::shared_ptr loadAsync(const Hash& pathHash, + SGroupLoadStatus* statusOut=NULL); }; +} } #endif // HECLRUNTIME_HPP diff --git a/hecl/lib/ProjectPath.cpp b/hecl/lib/ProjectPath.cpp index bb378062c..87f2a9628 100644 --- a/hecl/lib/ProjectPath.cpp +++ b/hecl/lib/ProjectPath.cpp @@ -22,7 +22,7 @@ bool ProjectPath::_canonAbsPath(const SystemString& path) SystemChar resolvedPath[PATH_MAX]; 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"); return false; } @@ -38,8 +38,8 @@ ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& pa m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(), ((ProjectPath&)rootPath).m_absPath)) { - throw std::invalid_argument("'" + CSystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" + - CSystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'"); + throw std::invalid_argument("'" + SystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" + + SystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'"); return; } if (m_absPath.size() == ((ProjectPath&)rootPath).m_absPath.size()) @@ -52,9 +52,14 @@ ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& pa ++m_relPath; if (m_relPath[0] == _S('\0')) 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)) return PT_GLOB; @@ -123,7 +128,7 @@ static void _recursiveGlob(std::vector& outPaths, #endif } -void ProjectPath::getGlobResults(std::vector& outPaths) +void ProjectPath::getGlobResults(std::vector& outPaths) const { #if _WIN32 TSystemPath itStr; diff --git a/hecl/lib/database/CProject.cpp b/hecl/lib/database/Project.cpp similarity index 75% rename from hecl/lib/database/CProject.cpp rename to hecl/lib/database/Project.cpp index a2ce66498..bbeb4f2eb 100644 --- a/hecl/lib/database/CProject.cpp +++ b/hecl/lib/database/Project.cpp @@ -6,7 +6,9 @@ #include "HECLDatabase.hpp" -namespace HECLDatabase +namespace HECL +{ +namespace Database { /********************************************** @@ -31,10 +33,10 @@ static inline bool CheckNewLineAdvance(std::string::const_iterator& it) 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_filepath = project.m_rootPath + _S("/.hecl/config/") + name; + m_filepath = project.m_rootPath.getAbsolutePath() + _S("/.hecl/config/") + name; } std::vector Project::ConfigFile::readLines() @@ -118,38 +120,39 @@ bool Project::ConfigFile::checkForLine(const std::string& refLine) * Project **********************************************/ -Project::Project(const std::string& rootPath) +Project::Project(const ProjectRootPath& rootPath) : m_rootPath(rootPath) { /* Stat for existing project directory (must already exist) */ 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()); 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 */ - HECL::MakeDir(m_rootPath + "/.hecl"); - HECL::MakeDir(m_rootPath + "/.hecl/cooked"); - HECL::MakeDir(m_rootPath + "/.hecl/config"); + HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl")); + HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/cooked")); + HECL::MakeDir(m_rootPath.getAbsolutePath() + _S("/.hecl/config")); /* 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& paths) +bool Project::addPaths(const std::vector& paths) { } -bool Project::removePaths(const std::vector& paths, bool recursive) +bool Project::removePaths(const std::vector& 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& specs) { } -bool Project::cookPath(const std::string& path, +bool Project::cookPath(const ProjectPath& path, std::function feedbackCb, 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) { } } +} diff --git a/hecl/lib/database/database.pri b/hecl/lib/database/database.pri index 0b8911d0d..716d3ef5e 100644 --- a/hecl/lib/database/database.pri +++ b/hecl/lib/database/database.pri @@ -1,4 +1,4 @@ HEADERS += SOURCES += \ - $$PWD/CProject.cpp + $$PWD/Project.cpp diff --git a/hecl/lib/runtime/HECLRuntime.cpp b/hecl/lib/runtime/HECLRuntime.cpp index a2e868d15..724ecc31b 100644 --- a/hecl/lib/runtime/HECLRuntime.cpp +++ b/hecl/lib/runtime/HECLRuntime.cpp @@ -1,23 +1,26 @@ #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 HECLRuntime::loadSync(const HECL::Hash& pathHash) +std::shared_ptr Runtime::loadSync(const Hash& pathHash) { } -std::shared_ptr HECLRuntime::loadAsync(const HECL::Hash& pathHash, - SGroupLoadStatus* statusOut) +std::shared_ptr Runtime::loadAsync(const Hash& pathHash, + SGroupLoadStatus* statusOut) { } } +}