diff --git a/hecl/blender/BlenderConnection.cpp b/hecl/blender/BlenderConnection.cpp index d604cdc0c..eddcfe50d 100644 --- a/hecl/blender/BlenderConnection.cpp +++ b/hecl/blender/BlenderConnection.cpp @@ -314,8 +314,7 @@ BlenderConnection::~BlenderConnection() bool BlenderConnection::createBlend(const SystemString& path) { - std::unique_lock lk(m_lock, std::try_to_lock); - if (!lk) + if (m_lock) { BlenderLog.report(LogVisor::FatalError, "BlenderConnection::createBlend() musn't be called with stream active"); @@ -335,8 +334,7 @@ bool BlenderConnection::createBlend(const SystemString& path) bool BlenderConnection::openBlend(const SystemString& path) { - std::unique_lock lk(m_lock, std::try_to_lock); - if (!lk) + if (m_lock) { BlenderLog.report(LogVisor::FatalError, "BlenderConnection::openBlend() musn't be called with stream active"); @@ -356,8 +354,7 @@ bool BlenderConnection::openBlend(const SystemString& path) bool BlenderConnection::saveBlend() { - std::unique_lock lk(m_lock, std::try_to_lock); - if (!lk) + if (m_lock) { BlenderLog.report(LogVisor::FatalError, "BlenderConnection::saveBlend() musn't be called with stream active"); @@ -376,6 +373,7 @@ void BlenderConnection::deleteBlend() if (m_loadedBlend.size()) { HECL::Unlink(m_loadedBlend.c_str()); + BlenderLog.report(LogVisor::Info, "Deleted '%s'", m_loadedBlend.c_str()); m_loadedBlend.clear(); } } diff --git a/hecl/blender/BlenderConnection.hpp b/hecl/blender/BlenderConnection.hpp index e3adbe0e1..a50d0af40 100644 --- a/hecl/blender/BlenderConnection.hpp +++ b/hecl/blender/BlenderConnection.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include "HECL/HECL.hpp" @@ -24,7 +23,7 @@ extern class BlenderConnection* SharedBlenderConnection; class BlenderConnection { - std::mutex m_lock; + bool m_lock; #if _WIN32 HANDLE m_blenderProc; HANDLE m_readpipe[2]; @@ -61,7 +60,6 @@ public: class PyOutStream : public std::ostream { friend class BlenderConnection; - std::unique_lock m_lk; BlenderConnection* m_parent; bool m_deleteOnError; struct StreamBuf : std::streambuf @@ -75,7 +73,7 @@ public: StreamBuf(StreamBuf&& other) = default; int_type overflow(int_type ch) { - if (!m_parent.m_lk) + if (!m_parent.m_parent || !m_parent.m_parent->m_lock) BlenderLog.report(LogVisor::FatalError, "lock not held for PyOutStream writing"); if (ch != traits_type::eof() && ch != '\n') { @@ -96,11 +94,12 @@ public: } } m_sbuf; PyOutStream(BlenderConnection* parent, bool deleteOnError) - : m_lk(parent->m_lock), m_parent(parent), + : m_parent(parent), m_sbuf(*this, deleteOnError), m_deleteOnError(deleteOnError), std::ostream(&m_sbuf) { + m_parent->m_lock = true; m_parent->_writeLine("PYBEGIN"); char readBuf[16]; m_parent->_readLine(readBuf, 16); @@ -110,27 +109,24 @@ public: public: PyOutStream(const PyOutStream& other) = delete; PyOutStream(PyOutStream&& other) - : m_lk(std::move(other.m_lk)), m_parent(other.m_parent), m_sbuf(std::move(other.m_sbuf)) + : m_parent(other.m_parent), m_sbuf(std::move(other.m_sbuf)) {other.m_parent = nullptr;} ~PyOutStream() {close();} void close() { - if (m_lk) + if (m_parent && m_parent->m_lock) { - if (m_parent) - { - m_parent->_writeLine("PYEND"); - char readBuf[16]; - m_parent->_readLine(readBuf, 16); - if (strcmp(readBuf, "DONE")) - BlenderLog.report(LogVisor::FatalError, "unable to close PyOutStream with blender"); - } - m_lk.unlock(); + m_parent->_writeLine("PYEND"); + char readBuf[16]; + m_parent->_readLine(readBuf, 16); + if (strcmp(readBuf, "DONE")) + BlenderLog.report(LogVisor::FatalError, "unable to close PyOutStream with blender"); + m_parent->m_lock = false; } } void format(const char* fmt, ...) { - if (!m_lk) + if (!m_parent || !m_parent->m_lock) BlenderLog.report(LogVisor::FatalError, "lock not held for PyOutStream::format()"); va_list ap; va_start(ap, fmt); @@ -145,6 +141,8 @@ public: }; inline PyOutStream beginPythonOut(bool deleteOnError=false) { + if (m_lock) + BlenderLog.report(LogVisor::FatalError, "lock already held for BlenderConnection::beginPythonOut()"); return PyOutStream(this, deleteOnError); } @@ -157,10 +155,24 @@ public: return *SharedBlenderConnection; } + inline void closeStream() + { + if (m_lock) + deleteBlend(); + } + static inline void Shutdown() { - delete SharedBlenderConnection; + if (SharedBlenderConnection) + { + SharedBlenderConnection->closeStream(); + SharedBlenderConnection->quitBlender(); + delete SharedBlenderConnection; + SharedBlenderConnection = nullptr; + BlenderLog.report(LogVisor::Info, "BlenderConnection Shutdown Successful"); + } } + }; } diff --git a/hecl/blender/addon/sact/SACTAction.py b/hecl/blender/addon/sact/SACTAction.py index cb9ed1bfe..42007f88e 100644 --- a/hecl/blender/addon/sact/SACTAction.py +++ b/hecl/blender/addon/sact/SACTAction.py @@ -148,6 +148,12 @@ class SACTAction_load(bpy.types.Operator): # Set single action into armature if subtype.linked_armature in bpy.data.objects: armature_obj = bpy.data.objects[subtype.linked_armature] + + for bone in armature_obj.pose.bones: + bone.location = (0,0,0) + bone.rotation_quaternion = (1,0,0,0) + bone.scale = (1,1,1) + if action_data.name in bpy.data.actions: action_obj =\ bpy.data.actions[action_data.name] diff --git a/hecl/driver/main.cpp b/hecl/driver/main.cpp index 37b24af0b..5ed3e1a3c 100644 --- a/hecl/driver/main.cpp +++ b/hecl/driver/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "HECL/Database.hpp" @@ -65,6 +66,13 @@ static const HECL::SystemRegex regOPEN(_S("-o([^\"]*|\\S*)"), std::regex::ECMASc 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); +/* SIGINT will gracefully close blender connections and delete blends in progress */ +static void SIGINTHandler(int sig) +{ + HECL::BlenderConnection::Shutdown(); + exit(1); +} + static LogVisor::LogModule AthenaLog("Athena"); static void AthenaExc(const Athena::error::Level& level, const char* file, const char*, int line, const char* fmt, ...) @@ -86,6 +94,8 @@ int main(int argc, const char** argv) if (term && !strncmp(term, "xterm", 5)) XTERM_COLOR = true; + signal(SIGINT, SIGINTHandler); + LogVisor::RegisterConsoleLogger(); atSetExceptionHandler(AthenaExc); diff --git a/hecl/extern/RetroCommon b/hecl/extern/RetroCommon index 0da7ab7e0..53256dea1 160000 --- a/hecl/extern/RetroCommon +++ b/hecl/extern/RetroCommon @@ -1 +1 @@ -Subproject commit 0da7ab7e01a305f0ecb7ec71d843b652002845f2 +Subproject commit 53256dea15ba37595b2958ed49249ddf370071ba