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"]
path = extern/LogVisor
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)
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)
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")
add_subdirectory(lib)
add_subdirectory(blender)

View File

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

View File

@ -206,10 +206,15 @@ int main(int argc, const char** argv)
else
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'"),
toolName.c_str());
#if HECL_UCS2
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;
}
@ -223,10 +228,15 @@ int main(int argc, const char** argv)
{
retval = tool->run();
}
catch (std::exception&)
catch (std::exception& ex)
{
LogModule.report(LogVisor::Error, _S("Error running HECL tool '%s'"),
toolName.c_str());
#if HECL_UCS2
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;
}

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(blowfish)
add_subdirectory(LogVisor)
add_subdirectory(AngelScript)
add_subdirectory(Athena)
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 <stdexcept>
#include <stdint.h>
#include <assert.h>
#include <angelscript.h>
#include <Athena/IStreamReader.hpp>
#include <LogVisor/LogVisor.hpp>
@ -25,6 +27,94 @@ namespace Database
{
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;
/**
@ -62,6 +152,8 @@ public:
class IDataSpec
{
public:
virtual ~IDataSpec() {}
/**
* @brief Extract Pass Info
*

View File

@ -178,6 +178,18 @@ static inline void FPrintf(FILE* fp, const SystemChar* format, ...)
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
static inline SystemString SysFormat(const SystemChar* format, ...)
@ -314,14 +326,15 @@ protected:
const char* m_utf8RelPath;
#endif
ProjectPath() {}
bool _canonAbsPath(const SystemString& path);
bool _canonAbsPath(const SystemString& path, bool& needsMake);
inline void _makeDir() const {MakeDir(getAbsolutePath());}
public:
/**
* @brief Construct a project subpath representation
* @param rootPath previously constructed ProjectRootPath held by HECLDatabase::IProject
* @brief Construct a project subpath representation within another subpath
* @param parentPath previously constructed ProjectPath which ultimately connects to a ProjectRootPath
* @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
@ -422,7 +435,12 @@ class ProjectRootPath : public ProjectPath
{
public:
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
Project.cpp
Registry.cpp)
ASEngine.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 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
#else
SystemChar resolvedPath[PATH_MAX];
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");
return false;
}
else
needsMake = true;
}
m_absPath = resolvedPath;
#endif
return true;
}
ProjectPath::ProjectPath(const ProjectRootPath& rootPath, const SystemString& path)
ProjectPath::ProjectPath(const ProjectPath& parentPath, const SystemString& path)
{
_canonAbsPath(path);
if (m_absPath.size() < ((ProjectPath&)rootPath).m_absPath.size() ||
m_absPath.compare(0, ((ProjectPath&)rootPath).m_absPath.size(),
((ProjectPath&)rootPath).m_absPath))
bool needsMake = false;
if (!_canonAbsPath(parentPath.getRelativePath() + '/' + path, needsMake))
return;
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 '" +
SystemUTF8View(((ProjectPath&)rootPath).m_absPath).utf8_str() + "'");
SystemUTF8View(parentPath.m_absPath).utf8_str() + "'");
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 */
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('/'))
++beginit;
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_utf8RelPath = m_utf8AbsPath.c_str() + ((ProjectPath&)rootPath).m_utf8AbsPath.size();
#endif
if (needsMake)
_makeDir();
}
ProjectPath::PathType ProjectPath::getPathType() const