added AngelScript; work on extractor

This commit is contained in:
Jack Andersen 2015-07-15 16:03:38 -10:00
parent 58fe87b13d
commit 4252bd6e39
15 changed files with 227 additions and 33 deletions

3
hecl/.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "extern/LogVisor"] [submodule "extern/LogVisor"]
path = extern/LogVisor path = extern/LogVisor
url = https://github.com/RetroView/LogVisor.git url = https://github.com/RetroView/LogVisor.git
[submodule "extern/AngelScript"]
path = extern/AngelScript
url = https://github.com/RetroView/AngelScript.git

View File

@ -1,8 +1,12 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
project(hecl) project(hecl)
set(HECL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE PATH "HECL include dir" FORCE) set(HECL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(ATHENA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/Athena/include)
set(LOG_VISOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/LogVisor/include)
set(ANGELSCRIPT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/AngelScript/angelscript/include)
add_definitions(-DAS_USE_NAMESPACE=1)
add_subdirectory(extern) add_subdirectory(extern)
include_directories(include ${LOG_VISOR_INCLUDE_DIR} ${ATHENA_INCLUDE_DIR}) include_directories(include ${LOG_VISOR_INCLUDE_DIR} ${ATHENA_INCLUDE_DIR} ${ANGELSCRIPT_INCLUDE_DIR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_subdirectory(lib) add_subdirectory(lib)
add_subdirectory(blender) add_subdirectory(blender)

View File

@ -20,7 +20,6 @@ list(APPEND DATA_SPEC_LIBS
DNAMP3) DNAMP3)
target_link_libraries(hecl target_link_libraries(hecl
HECLDatabase "-Wl,-whole-archive" HECLDatabaseInit ${DATA_SPEC_LIBS} "-Wl,-no-whole-archive"
"-Wl,-whole-archive" ${DATA_SPEC_LIBS} "-Wl,-no-whole-archive" HECLDatabase HECL AthenaCore AngelScript NOD LogVisor blowfish z lzo2
HECL AthenaCore NOD LogVisor blowfish z lzo2 pthread
) )

View File

@ -206,10 +206,15 @@ int main(int argc, const char** argv)
else else
LogModule.report(LogVisor::FatalError, _S("unrecognized tool '%s'"), toolName.c_str()); LogModule.report(LogVisor::FatalError, _S("unrecognized tool '%s'"), toolName.c_str());
} }
catch (std::exception&) catch (std::exception& ex)
{ {
LogModule.report(LogVisor::Error, _S("Unable to construct HECL tool '%s'"), #if HECL_UCS2
toolName.c_str()); LogModule.report(LogVisor::Error, _S("Unable to construct HECL tool '%s': %S"),
toolName.c_str(), ex.what());
#else
LogModule.report(LogVisor::Error, _S("Unable to construct HECL tool '%s': %s"),
toolName.c_str(), ex.what());
#endif
return -1; return -1;
} }
@ -223,10 +228,15 @@ int main(int argc, const char** argv)
{ {
retval = tool->run(); retval = tool->run();
} }
catch (std::exception&) catch (std::exception& ex)
{ {
LogModule.report(LogVisor::Error, _S("Error running HECL tool '%s'"), #if HECL_UCS2
toolName.c_str()); LogModule.report(LogVisor::Error, _S("Error running HECL tool '%s': %S"),
toolName.c_str(), ex.what());
#else
LogModule.report(LogVisor::Error, _S("Error running HECL tool '%s': %s"),
toolName.c_str(), ex.what());
#endif
return -1; return -1;
} }

1
hecl/extern/AngelScript vendored Submodule

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

2
hecl/extern/Athena vendored

@ -1 +1 @@
Subproject commit 87306a18d87c136930bd3252775303ad7bff77ec Subproject commit 7442d618e7f82acdc8f986baca040033c1f411f9

View File

@ -1,6 +1,6 @@
set(ATHENA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Athena/include CACHE PATH "Athena include dir" FORCE)
add_subdirectory(libpng) add_subdirectory(libpng)
add_subdirectory(blowfish) add_subdirectory(blowfish)
add_subdirectory(LogVisor) add_subdirectory(LogVisor)
add_subdirectory(AngelScript)
add_subdirectory(Athena) add_subdirectory(Athena)
add_subdirectory(RetroCommon) add_subdirectory(RetroCommon)

@ -1 +1 @@
Subproject commit 462971b134432330b30b60898d8c8b5c758bacb7 Subproject commit c2bfffa6cf1d07986fecaf7dde42acb29fe1f6e6

@ -1 +1 @@
Subproject commit a4d1fdbcfa2ea1331ae1c8d9a1e96822e1dce52e Subproject commit 94a6707dd32e6aed988c7606c6c28836a398ad6d

View File

@ -13,7 +13,9 @@
#include <atomic> #include <atomic>
#include <stdexcept> #include <stdexcept>
#include <stdint.h> #include <stdint.h>
#include <assert.h>
#include <angelscript.h>
#include <Athena/IStreamReader.hpp> #include <Athena/IStreamReader.hpp>
#include <LogVisor/LogVisor.hpp> #include <LogVisor/LogVisor.hpp>
@ -25,6 +27,94 @@ namespace Database
{ {
class Project; class Project;
extern AngelScript::asIScriptEngine* asENGINE;
void InitASEngine();
template <class ASCLASS>
class ASType
{
static void Constructor(ASCLASS* self)
{
new(self) ASCLASS();
}
static void Destructor(ASCLASS* self)
{
self->~ASCLASS();
}
const char* m_name;
int m_typeid;
public:
ASType(const char* namesp, const char* name) : m_name(name)
{
InitASEngine();
assert(asENGINE->SetDefaultNamespace(namesp) >= 0);
assert((m_typeid = asENGINE->RegisterObjectType(name, sizeof(ASCLASS), AngelScript::asOBJ_VALUE)) >= 0);
assert(asENGINE->RegisterObjectBehaviour(name, AngelScript::asBEHAVE_CONSTRUCT, "void f()",
AngelScript::asFUNCTION(Constructor),
AngelScript::asCALL_CDECL_OBJLAST) >= 0);
assert(asENGINE->RegisterObjectBehaviour(name, AngelScript::asBEHAVE_DESTRUCT, "void f()",
AngelScript::asFUNCTION(Destructor),
AngelScript::asCALL_CDECL_OBJLAST) >= 0);
}
inline const char* getName() const {return m_name;}
inline int getTypeID() const {return m_typeid;}
};
template <class ASELEMCLASS>
class ASListType
{
struct ASListInst
{
std::vector<ASELEMCLASS*> m_items;
ASListInst(void* list)
{
AngelScript::asUINT count = *(AngelScript::asUINT*)list;
ASELEMCLASS* items = (ASELEMCLASS*)((char*)list + 4);
m_items.reserve(count);
for (AngelScript::asUINT i=0 ; i<count ; ++i)
m_items.push_back(&items[i]);
}
};
static void ListConstructor(void* list, ASListInst* self)
{
new(self) ASListInst(list);
}
static void ListDestructor(ASListInst* self)
{
self->~ASListInst();
}
const char* m_name;
const char* m_elemName;
int m_typeid;
public:
ASListType(const char* namesp, const char* name, const char* elemName) : m_name(name), m_elemName(elemName)
{
InitASEngine();
assert(asENGINE->SetDefaultNamespace(namesp) >= 0);
assert((m_typeid = asENGINE->RegisterObjectType(name, sizeof(ASListInst), AngelScript::asOBJ_VALUE)) >= 0);
assert(asENGINE->RegisterObjectBehaviour(name, AngelScript::asBEHAVE_LIST_CONSTRUCT,
("void f(int &in) {repeat " + std::string(elemName) + "}").c_str(),
AngelScript::asFUNCTION(ListConstructor),
AngelScript::asCALL_CDECL_OBJLAST) >= 0);
assert(asENGINE->RegisterObjectBehaviour(name, AngelScript::asBEHAVE_DESTRUCT, "void f()",
AngelScript::asFUNCTION(ListDestructor),
AngelScript::asCALL_CDECL_OBJLAST) >= 0);
}
inline const char* getName() const {return m_name;}
inline const char* getElemName() const {return m_elemName;}
inline int getTypeID() const {return m_typeid;}
inline std::vector<ASELEMCLASS*>& vectorCast(void* addr) const
{return static_cast<ASListInst*>(addr)->m_items;}
inline const std::vector<ASELEMCLASS*>& vectorCast(const void* addr) const
{return static_cast<const ASListInst*>(addr)->m_items;}
};
struct ASStringType : ASType<std::string>
{
ASStringType();
};
extern ASStringType asSTRINGTYPE;
extern LogVisor::LogModule LogModule; extern LogVisor::LogModule LogModule;
/** /**
@ -62,6 +152,8 @@ public:
class IDataSpec class IDataSpec
{ {
public: public:
virtual ~IDataSpec() {}
/** /**
* @brief Extract Pass Info * @brief Extract Pass Info
* *

View File

@ -178,6 +178,18 @@ static inline void FPrintf(FILE* fp, const SystemChar* format, ...)
va_end(va); va_end(va);
} }
static inline void SNPrintf(SystemChar* str, size_t maxlen, const SystemChar* format, ...)
{
va_list va;
va_start(va, format);
#if HECL_UCS2
vsnwprintf(str, maxlen, format, va);
#else
vsnprintf(str, maxlen, format, va);
#endif
va_end(va);
}
#define FORMAT_BUF_SZ 1024 #define FORMAT_BUF_SZ 1024
static inline SystemString SysFormat(const SystemChar* format, ...) static inline SystemString SysFormat(const SystemChar* format, ...)
@ -314,14 +326,15 @@ protected:
const char* m_utf8RelPath; const char* m_utf8RelPath;
#endif #endif
ProjectPath() {} ProjectPath() {}
bool _canonAbsPath(const SystemString& path); bool _canonAbsPath(const SystemString& path, bool& needsMake);
inline void _makeDir() const {MakeDir(getAbsolutePath());}
public: public:
/** /**
* @brief Construct a project subpath representation * @brief Construct a project subpath representation within another subpath
* @param rootPath previously constructed ProjectRootPath held by HECLDatabase::IProject * @param parentPath previously constructed ProjectPath which ultimately connects to a ProjectRootPath
* @param path valid filesystem-path (relative or absolute) to subpath * @param path valid filesystem-path (relative or absolute) to subpath
*/ */
ProjectPath(const ProjectRootPath& rootPath, const SystemString& path); ProjectPath(const ProjectPath& parentPath, const SystemString& path);
/** /**
* @brief Determine if ProjectPath represents project root directory * @brief Determine if ProjectPath represents project root directory
@ -422,7 +435,12 @@ class ProjectRootPath : public ProjectPath
{ {
public: public:
ProjectRootPath(const SystemString& path) ProjectRootPath(const SystemString& path)
{_canonAbsPath(path);} {
bool needsMake = false;
_canonAbsPath(path, needsMake);
if (needsMake)
_makeDir();
}
}; };
/** /**

View File

@ -0,0 +1,21 @@
#include "HECL/Database.hpp"
namespace HECL
{
namespace Database
{
/* Centralized AngelScript engine */
AngelScript::asIScriptEngine* asENGINE = nullptr;
static bool InitEntered = false;
void InitASEngine()
{
if (InitEntered)
return;
InitEntered = true;
assert(asENGINE = AngelScript::asCreateScriptEngine(ANGELSCRIPT_VERSION));
}
}
}

View File

@ -0,0 +1,24 @@
#include "HECL/Database.hpp"
namespace HECL
{
namespace Database
{
static std::string StringFactory(unsigned int byteLength, const char *s)
{
return std::string(s, byteLength);
}
ASStringType asSTRINGTYPE;
ASStringType::ASStringType() : ASType<std::string>("", "string")
{
assert(asENGINE->RegisterStringFactory("string",
AngelScript::asFUNCTION(StringFactory),
AngelScript::asCALL_CDECL) >= 0);
}
}
}

View File

@ -1,3 +1,7 @@
add_library(HECLDatabaseInit
Registry.cpp
ASInit.cpp)
add_library(HECLDatabase add_library(HECLDatabase
Project.cpp ASEngine.cpp
Registry.cpp) Project.cpp)

View File

@ -15,39 +15,54 @@ static const SystemRegex regGLOB(_S("\\*"), SystemRegex::ECMAScript|SystemRegex:
static const SystemRegex regPATHCOMP(_S("/([^/]+)"), SystemRegex::ECMAScript|SystemRegex::optimize); static const SystemRegex regPATHCOMP(_S("/([^/]+)"), SystemRegex::ECMAScript|SystemRegex::optimize);
static const SystemRegex regDRIVELETTER(_S("^([^/]*)/"), SystemRegex::ECMAScript|SystemRegex::optimize); static const SystemRegex regDRIVELETTER(_S("^([^/]*)/"), SystemRegex::ECMAScript|SystemRegex::optimize);
bool ProjectPath::_canonAbsPath(const SystemString& path) inline bool isAbsolute(const SystemString& path)
{
if (path.size() && path[0] == '/')
return true;
return false;
}
bool ProjectPath::_canonAbsPath(const SystemString& path, bool& needsMake)
{ {
#if _WIN32 #if _WIN32
#else #else
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 '" + SystemUTF8View(path).utf8_str() + if (errno != ENOENT)
{
throw std::system_error(errno, std::system_category(),
"Unable to resolve '" + SystemUTF8View(path).utf8_str() +
"' as a canonicalized path"); "' as a canonicalized path");
return false; return false;
}
else
needsMake = true;
} }
m_absPath = resolvedPath; m_absPath = resolvedPath;
#endif #endif
return true; return true;
} }
ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& path) ProjectPath::ProjectPath(const ProjectPath& parentPath, const SystemString& path)
{ {
_canonAbsPath(path); bool needsMake = false;
if (m_absPath.size() < ((ProjectPath&)rootPath).m_absPath.size() || if (!_canonAbsPath(parentPath.getRelativePath() + '/' + path, needsMake))
m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(), return;
((ProjectPath&)rootPath).m_absPath)) if (m_absPath.size() < parentPath.m_absPath.size() ||
m_absPath.compare(0, parentPath.m_absPath.size(),
parentPath.m_absPath))
{ {
throw std::invalid_argument("'" + SystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" + throw std::invalid_argument("'" + SystemUTF8View(m_absPath).utf8_str() + "' is not a subpath of '" +
SystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'"); SystemUTF8View(parentPath.m_absPath).utf8_str() + "'");
return; return;
} }
if (m_absPath.size() == ((ProjectPath&)rootPath).m_absPath.size()) if (m_absPath.size() == parentPath.m_absPath.size())
{ {
/* Copies of the project root are permitted */ /* Copies of the project root are permitted */
return; return;
} }
SystemString::iterator beginit = m_absPath.begin() + ((ProjectPath&)rootPath).m_absPath.size(); SystemString::iterator beginit = m_absPath.begin() + parentPath.m_absPath.size();
if (*beginit == _S('/')) if (*beginit == _S('/'))
++beginit; ++beginit;
m_relPath = SystemString(beginit, m_absPath.end()); m_relPath = SystemString(beginit, m_absPath.end());
@ -57,6 +72,9 @@ ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& pa
m_utf8AbsPath = WideToUTF8(m_absPath); m_utf8AbsPath = WideToUTF8(m_absPath);
m_utf8RelPath = m_utf8AbsPath.c_str() + ((ProjectPath&)rootPath).m_utf8AbsPath.size(); m_utf8RelPath = m_utf8AbsPath.c_str() + ((ProjectPath&)rootPath).m_utf8AbsPath.size();
#endif #endif
if (needsMake)
_makeDir();
} }
ProjectPath::PathType ProjectPath::getPathType() const ProjectPath::PathType ProjectPath::getPathType() const