From f9f5977cca139382aa9a04f93b5c286f6212adbf Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 21 Apr 2021 12:45:42 +0100 Subject: [PATCH] NasalEmeserayInterface to an explicit pointer. Also move to its own file, and give it a real header so it can be directly initialised. (Requires corresponding FlightGear commit) --- simgear/nasal/CMakeLists.txt | 2 + simgear/nasal/NasalEmesaryInterface.cxx | 132 ++++++++++++++++++ simgear/nasal/NasalEmesaryInterface.hxx | 26 ++++ simgear/nasal/cppbind/CMakeLists.txt | 1 - .../nasal/cppbind/NasalEmesaryInterface.hxx | 119 ---------------- .../nasal/cppbind/detail/to_nasal_helper.cxx | 9 +- 6 files changed, 164 insertions(+), 125 deletions(-) create mode 100644 simgear/nasal/NasalEmesaryInterface.cxx create mode 100644 simgear/nasal/NasalEmesaryInterface.hxx delete mode 100644 simgear/nasal/cppbind/NasalEmesaryInterface.hxx diff --git a/simgear/nasal/CMakeLists.txt b/simgear/nasal/CMakeLists.txt index 8f4d2c90..e8a3fe36 100644 --- a/simgear/nasal/CMakeLists.txt +++ b/simgear/nasal/CMakeLists.txt @@ -5,6 +5,7 @@ set(HEADERS naref.h nasal.h iolib.h + NasalEmesaryInterface.hxx ) set(SOURCES @@ -28,6 +29,7 @@ set(SOURCES code.h data.h parse.h + NasalEmesaryInterface.cxx ) simgear_component(nasal nasal "${SOURCES}" "${HEADERS}") diff --git a/simgear/nasal/NasalEmesaryInterface.cxx b/simgear/nasal/NasalEmesaryInterface.cxx new file mode 100644 index 00000000..7cffcb7f --- /dev/null +++ b/simgear/nasal/NasalEmesaryInterface.cxx @@ -0,0 +1,132 @@ + +// Nasal Emesary receipient interface. +// +// Copyright (C) 2019 Richard Harrison rjh@zaretto.com +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include + + +extern"C" { + // these are declared inside nasal/gc.c + extern int GCglobalAlloc(); + extern int naGarbageCollect(); + + // these are used by the detailed debug in the Nasal GC. + SGTimeStamp global_timestamp; + void global_stamp() { + global_timestamp.stamp(); + } + extern int global_elapsedUSec() + { + return global_timestamp.elapsedUSec(); + } +} + +namespace nasal +{ + +class ThreadedGarbageCollector : public SGExclusiveThread { +public: + ThreadedGarbageCollector() : SGExclusiveThread() {} + virtual ~ThreadedGarbageCollector() {} + + int process() override{ + return naGarbageCollect(); + } +}; + +class NasalMainLoopRecipient : public simgear::Emesary::IReceiver { +public: + NasalMainLoopRecipient() + { + simgear::Emesary::GlobalTransmitter::instance()->Register(this); + } + + virtual ~NasalMainLoopRecipient() { + simgear::Emesary::GlobalTransmitter::instance()->DeRegister(this); + } + + + simgear::Emesary::ReceiptStatus Receive(simgear::Emesary::INotificationPtr n) override + { + auto mln = dynamic_pointer_cast(n); + + if (mln) { + switch (mln->GetValue()) { + case simgear::Notifications::MainLoopNotification::Type::Begin: + if (gct.is_running()) { + if (Active && CanWait) + gct.awaitCompletion(); + else + gct.clearAwaitCompletionTime(); + } + break; + case simgear::Notifications::MainLoopNotification::Type::End: + if (Active) { + if (gct.is_running()) + gct.release(); + } + break; + case simgear::Notifications::MainLoopNotification::Type::Started: + gct.ensure_running(); + break; + case simgear::Notifications::MainLoopNotification::Type::Stopped: + gct.terminate(); + break; + } + return simgear::Emesary::ReceiptStatus::OK; + } + auto gccn = dynamic_pointer_cast(n); + + if (gccn) { + CanWait = gccn->GetCanWait(); + Active = gccn->GetActive(); + return simgear::Emesary::ReceiptStatus::OK; + } + return simgear::Emesary::ReceiptStatus::NotProcessed; + } +protected: + bool CanWait = false; + bool Active = false; + ThreadedGarbageCollector gct; + std::atomic receiveCount{0}; +}; + +static std::unique_ptr static_nasalMainLoopRecipient; + +void initMainLoopRecipient() +{ + static_nasalMainLoopRecipient.reset(new NasalMainLoopRecipient); +} + +} // namespace nasal + diff --git a/simgear/nasal/NasalEmesaryInterface.hxx b/simgear/nasal/NasalEmesaryInterface.hxx new file mode 100644 index 00000000..601db760 --- /dev/null +++ b/simgear/nasal/NasalEmesaryInterface.hxx @@ -0,0 +1,26 @@ + +// Nasal Emesary receipient interface. +// +// Copyright (C) 2019 Richard Harrison rjh@zaretto.com +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#pragma once +namespace nasal +{ + +void initMainLoopRecipient(); + +} // namespace nasal diff --git a/simgear/nasal/cppbind/CMakeLists.txt b/simgear/nasal/cppbind/CMakeLists.txt index a2a1cc9e..75e980ff 100644 --- a/simgear/nasal/cppbind/CMakeLists.txt +++ b/simgear/nasal/cppbind/CMakeLists.txt @@ -5,7 +5,6 @@ set(HEADERS Ghost.hxx NasalCallContext.hxx NasalContext.hxx - NasalEmesaryInterface.hxx NasalHash.hxx NasalMe.hxx NasalMethodHolder.hxx diff --git a/simgear/nasal/cppbind/NasalEmesaryInterface.hxx b/simgear/nasal/cppbind/NasalEmesaryInterface.hxx deleted file mode 100644 index 1af86abb..00000000 --- a/simgear/nasal/cppbind/NasalEmesaryInterface.hxx +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef NASALEMESARYINTERFACE_INCLUDED -#define NASALEMESARYINTERFACE_INCLUDED 1 -// Nasal Emesary receipient interface. -// -// Copyright (C) 2019 Richard Harrison rjh@zaretto.com -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - - -namespace nasal -{ - extern"C" { - extern int GCglobalAlloc(); - extern int naGarbageCollect(); - // these are used by the detailed debug in the Nasal GC. - SGTimeStamp global_timestamp; - void global_stamp() { - global_timestamp.stamp(); - } - extern int global_elapsedUSec() - { - return global_timestamp.elapsedUSec(); - } - } - - class ThreadedGarbageCollector : public SGExclusiveThread { - public: - ThreadedGarbageCollector() : SGExclusiveThread() {} - virtual ~ThreadedGarbageCollector() {} - - virtual int process(){ - return naGarbageCollect(); - } - }; - - class NasalMainLoopRecipient : public simgear::Emesary::IReceiver { - public: - NasalMainLoopRecipient() : receiveCount(0), CanWait(false), Active(false) { - simgear::Emesary::GlobalTransmitter::instance()->Register(this); - } - virtual ~NasalMainLoopRecipient() { - simgear::Emesary::GlobalTransmitter::instance()->DeRegister(this); - } - - std::atomic receiveCount; - virtual simgear::Emesary::ReceiptStatus Receive(simgear::Emesary::INotificationPtr n) - { - auto mln = dynamic_pointer_cast(n); - - if (mln) { - switch (mln->GetValue()) { - case simgear::Notifications::MainLoopNotification::Type::Begin: - if (gct.is_running()) { - if (Active && CanWait) - gct.awaitCompletion(); - else - gct.clearAwaitCompletionTime(); - } - break; - case simgear::Notifications::MainLoopNotification::Type::End: - if (Active) { - if (gct.is_running()) - gct.release(); - } - break; - case simgear::Notifications::MainLoopNotification::Type::Started: - gct.ensure_running(); - break; - case simgear::Notifications::MainLoopNotification::Type::Stopped: - gct.terminate(); - break; - } - return simgear::Emesary::ReceiptStatus::OK; - } - auto gccn = dynamic_pointer_cast(n); - - if (gccn) { - CanWait = gccn->GetCanWait(); - Active = gccn->GetActive(); - return simgear::Emesary::ReceiptStatus::OK; - } - return simgear::Emesary::ReceiptStatus::NotProcessed; - } - protected: - bool CanWait; - bool Active; - ThreadedGarbageCollector gct; - }; - -} // namespace nasal -#endif diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx index 6c339c94..79212016 100644 --- a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx +++ b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx @@ -17,9 +17,11 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA #include "to_nasal_helper.hxx" + +#include + #include #include -#include #include #include @@ -27,10 +29,7 @@ namespace nasal { - // create single instance of the main loop recipient for Nasal - this will self register at the - // global transmitter - and that's all that is needed to link up the background GC to the main - // loop in FG that will send out the MainLoop notifications. - NasalMainLoopRecipient mrl; + //---------------------------------------------------------------------------- naRef to_nasal_helper(naContext c, const std::string& str)