pythonfmu3 0.1.12__tar.gz → 0.1.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pythonfmu3-0.1.12/pythonfmu3.egg-info → pythonfmu3-0.1.14}/PKG-INFO +6 -4
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/README.md +5 -3
- pythonfmu3-0.1.14/pythonfmu3/_version.py +1 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/fmi3slave.py +1 -1
- pythonfmu3-0.1.14/pythonfmu3/pythonfmu-export/src/pythonfmu/IPyState.hpp +18 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.cpp +67 -8
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.hpp +3 -1
- pythonfmu3-0.1.14/pythonfmu3/pythonfmu-export/src/pythonfmu/PyState.hpp +85 -0
- pythonfmu3-0.1.14/pythonfmu3/resources/binaries/x86_64-linux/libpythonfmu-export.so +0 -0
- pythonfmu3-0.1.14/pythonfmu3/resources/binaries/x86_64-windows/pythonfmu-export.dll +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/variables.py +1 -1
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14/pythonfmu3.egg-info}/PKG-INFO +6 -4
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/SOURCES.txt +1 -0
- pythonfmu3-0.1.12/pythonfmu3/_version.py +0 -1
- pythonfmu3-0.1.12/pythonfmu3/pythonfmu-export/src/pythonfmu/PyState.hpp +0 -41
- pythonfmu3-0.1.12/pythonfmu3/resources/binaries/x86_64-linux/libpythonfmu-export.so +0 -0
- pythonfmu3-0.1.12/pythonfmu3/resources/binaries/x86_64-windows/pythonfmu-export.dll +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/LICENSE +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/MANIFEST.in +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/__init__.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/__main__.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/builder.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/default_experiment.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/deploy.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/enums.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/logmsg.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/osutil.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/.clang-format +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/CMakeLists.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/build_unix.sh +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/build_win.sh +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/CMakeLists.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_common.hpp +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.cpp +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.hpp +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/fmi_functions.cpp +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/fmi/fmi3FunctionTypes.h +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/fmi/fmi3Functions.h +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/fmi/fmi3PlatformTypes.h +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/__init__.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/conftest.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/data/csvdemo.csv +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/data/hello.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/slaves/PythonSlaveWithException.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/slaves/localmodule.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/slaves/pythonslave.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/slaves/pythonslave_read_file.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/slaves/slavewithdep.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_builder.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_deploy.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_fmi3slave.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_integration.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_logger.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_multiple_fmus.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/test_variables.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/tests/utils.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/unit.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/variable_types.py +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/dependency_links.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/entry_points.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/not-zip-safe +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/requires.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3.egg-info/top_level.txt +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/setup.cfg +0 -0
- {pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pythonfmu3
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: A lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs.
|
|
5
5
|
Home-page: https://github.com/stephensmith25/PythonFMU3
|
|
6
6
|
Author: Stephen Smith
|
|
@@ -131,16 +131,18 @@ from pythonfmu3 import Fmi3Causality, Fmi3Slave, Boolean, Int32, Float64, String
|
|
|
131
131
|
|
|
132
132
|
class PythonSlave(Fmi3Slave):
|
|
133
133
|
|
|
134
|
-
author = "John Doe"
|
|
135
|
-
description = "A simple description"
|
|
136
|
-
|
|
137
134
|
def __init__(self, **kwargs):
|
|
138
135
|
super().__init__(**kwargs)
|
|
139
136
|
|
|
137
|
+
self.author = "John Doe"
|
|
138
|
+
self.description = "A simple description"
|
|
139
|
+
|
|
140
|
+
self.time = 0.0
|
|
140
141
|
self.intOut = 1
|
|
141
142
|
self.realOut = 3.0
|
|
142
143
|
self.booleanVariable = True
|
|
143
144
|
self.stringVariable = "Hello World!"
|
|
145
|
+
self.register_variable(Float64("time", causality=Fmi3Causality.independent))
|
|
144
146
|
self.register_variable(Int32("intOut", causality=Fmi3Causality.output))
|
|
145
147
|
self.register_variable(Float64("realOut", causality=Fmi3Causality.output))
|
|
146
148
|
self.register_variable(Boolean("booleanVariable", causality=Fmi3Causality.local))
|
|
@@ -105,16 +105,18 @@ from pythonfmu3 import Fmi3Causality, Fmi3Slave, Boolean, Int32, Float64, String
|
|
|
105
105
|
|
|
106
106
|
class PythonSlave(Fmi3Slave):
|
|
107
107
|
|
|
108
|
-
author = "John Doe"
|
|
109
|
-
description = "A simple description"
|
|
110
|
-
|
|
111
108
|
def __init__(self, **kwargs):
|
|
112
109
|
super().__init__(**kwargs)
|
|
113
110
|
|
|
111
|
+
self.author = "John Doe"
|
|
112
|
+
self.description = "A simple description"
|
|
113
|
+
|
|
114
|
+
self.time = 0.0
|
|
114
115
|
self.intOut = 1
|
|
115
116
|
self.realOut = 3.0
|
|
116
117
|
self.booleanVariable = True
|
|
117
118
|
self.stringVariable = "Hello World!"
|
|
119
|
+
self.register_variable(Float64("time", causality=Fmi3Causality.independent))
|
|
118
120
|
self.register_variable(Int32("intOut", causality=Fmi3Causality.output))
|
|
119
121
|
self.register_variable(Float64("realOut", causality=Fmi3Causality.output))
|
|
120
122
|
self.register_variable(Boolean("booleanVariable", causality=Fmi3Causality.local))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.14"
|
|
@@ -188,7 +188,7 @@ class Fmi3Slave(ABC):
|
|
|
188
188
|
raise Exception(f"Unsupported type {type(var)}!")
|
|
189
189
|
var.start = refs if len(getattr(var, "dimensions", [])) > 0 else refs[0]
|
|
190
190
|
|
|
191
|
-
def register_variable(self, var: ModelVariable, nested: bool = True,
|
|
191
|
+
def register_variable(self, var: ModelVariable, nested: bool = True, var_type: Any = None):
|
|
192
192
|
"""Register a variable as FMU interface.
|
|
193
193
|
|
|
194
194
|
Args:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#ifndef PYTHONFMU_IPYTHONSTATE_HPP
|
|
2
|
+
#define PYTHONFMU_IPYTHONSTATE_HPP
|
|
3
|
+
|
|
4
|
+
namespace pythonfmu
|
|
5
|
+
{
|
|
6
|
+
class IPyState
|
|
7
|
+
{
|
|
8
|
+
public:
|
|
9
|
+
IPyState() = default;
|
|
10
|
+
IPyState(IPyState const& other) = delete;
|
|
11
|
+
IPyState(IPyState&& other) = delete;
|
|
12
|
+
IPyState& operator=(IPyState const& other) = delete;
|
|
13
|
+
IPyState& operator=(IPyState&& other) = delete;
|
|
14
|
+
virtual ~IPyState() = default;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#endif //PYTHONFMU_IPYTHONSTATE_HPP
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
#include "pythonfmu/IPyState.hpp"
|
|
2
3
|
#include "pythonfmu/PySlaveInstance.hpp"
|
|
3
4
|
|
|
4
5
|
#include "pythonfmu/PyState.hpp"
|
|
@@ -7,6 +8,7 @@
|
|
|
7
8
|
|
|
8
9
|
#include <fstream>
|
|
9
10
|
#include <functional>
|
|
11
|
+
#include <mutex>
|
|
10
12
|
#include <regex>
|
|
11
13
|
#include <sstream>
|
|
12
14
|
#include <utility>
|
|
@@ -44,8 +46,9 @@ inline void py_safe_run(const std::function<void(PyGILState_STATE gilState)>& f)
|
|
|
44
46
|
PyGILState_Release(gil_state);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
PySlaveInstance::PySlaveInstance(std::string instanceName, std::string resources, const cppfmu::Logger& logger, const bool visible)
|
|
48
|
-
:
|
|
49
|
+
PySlaveInstance::PySlaveInstance(std::string instanceName, std::string resources, const cppfmu::Logger& logger, const bool visible, std::shared_ptr<IPyState> pyState)
|
|
50
|
+
: pyState_{ std::move(pyState) }
|
|
51
|
+
, instanceName_(std::move(instanceName))
|
|
49
52
|
, resources_(std::move(resources))
|
|
50
53
|
, logger_(logger)
|
|
51
54
|
, visible_(visible)
|
|
@@ -441,9 +444,14 @@ void PySlaveInstance::GetUInt64(const cppfmu::FMIValueReference* vr, std::size_t
|
|
|
441
444
|
}
|
|
442
445
|
|
|
443
446
|
for (int i = 0; i < nvr; i++) {
|
|
444
|
-
PyObject*
|
|
445
|
-
|
|
447
|
+
PyObject* item = PyList_GetItem(refs, i);
|
|
448
|
+
PyObject* value = PyObject_GetAttrString(item, "value");
|
|
449
|
+
if (value && PyLong_Check(value))
|
|
450
|
+
{
|
|
451
|
+
values[i] = static_cast<cppfmu::FMIUInt64>(PyLong_AsUnsignedLongLong(value));
|
|
452
|
+
}
|
|
446
453
|
}
|
|
454
|
+
|
|
447
455
|
Py_DECREF(refs);
|
|
448
456
|
clearLogBuffer();
|
|
449
457
|
});
|
|
@@ -625,7 +633,10 @@ PySlaveInstance::~PySlaveInstance()
|
|
|
625
633
|
|
|
626
634
|
} // namespace pythonfmu
|
|
627
635
|
|
|
628
|
-
|
|
636
|
+
namespace {
|
|
637
|
+
std::mutex pyStateMutex{};
|
|
638
|
+
std::shared_ptr<pythonfmu::PyState> pyState{};
|
|
639
|
+
}
|
|
629
640
|
|
|
630
641
|
std::unique_ptr<cppfmu::SlaveInstance> CppfmuInstantiateSlave(
|
|
631
642
|
cppfmu::FMIString instanceName,
|
|
@@ -650,9 +661,57 @@ std::unique_ptr<cppfmu::SlaveInstance> CppfmuInstantiateSlave(
|
|
|
650
661
|
#endif
|
|
651
662
|
}
|
|
652
663
|
|
|
653
|
-
|
|
654
|
-
|
|
664
|
+
{
|
|
665
|
+
auto const ensurePyStateAlive = [&]() {
|
|
666
|
+
auto const lock = std::lock_guard{pyStateMutex};
|
|
667
|
+
if (nullptr == pyState) pyState = std::make_shared<pythonfmu::PyState>();
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
ensurePyStateAlive();
|
|
671
|
+
return std::make_unique<pythonfmu::PySlaveInstance>(
|
|
672
|
+
instanceName, resources, logger, visible, pyState);
|
|
655
673
|
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
extern "C" {
|
|
656
677
|
|
|
657
|
-
|
|
678
|
+
// The PyState instance owns it's own thread for constructing and destroying the Py* from the same thread.
|
|
679
|
+
// Creation of an std::thread increments ref counter of a shared library. So, when the client unloads the library
|
|
680
|
+
// the library won't be freed, as std::thread is alive, and the std::thread itself waits for de-initialization request.
|
|
681
|
+
// Thus, use DllMain on Windows and __attribute__((destructor)) on Linux for signaling to the PyState about de-initialization.
|
|
682
|
+
void finalizePythonInterpreter()
|
|
683
|
+
{
|
|
684
|
+
pyState = nullptr;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
namespace
|
|
689
|
+
{
|
|
690
|
+
#ifdef _WIN32
|
|
691
|
+
#include <windows.h>
|
|
692
|
+
|
|
693
|
+
BOOL APIENTRY DllMain(HMODULE hModule,
|
|
694
|
+
DWORD ul_reason_for_call,
|
|
695
|
+
LPVOID lpReserved)
|
|
696
|
+
{
|
|
697
|
+
switch (ul_reason_for_call) {
|
|
698
|
+
case DLL_PROCESS_ATTACH:
|
|
699
|
+
break;
|
|
700
|
+
case DLL_THREAD_ATTACH:
|
|
701
|
+
case DLL_THREAD_DETACH:
|
|
702
|
+
break;
|
|
703
|
+
case DLL_PROCESS_DETACH:
|
|
704
|
+
finalizePythonInterpreter();
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
return TRUE;
|
|
708
|
+
}
|
|
709
|
+
#elif defined(__linux__)
|
|
710
|
+
__attribute__((destructor)) void onLibraryUnload()
|
|
711
|
+
{
|
|
712
|
+
finalizePythonInterpreter();
|
|
713
|
+
}
|
|
714
|
+
#else
|
|
715
|
+
#error port the code
|
|
716
|
+
#endif
|
|
658
717
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#define PYTHONFMU_SLAVEINSTANCE_HPP
|
|
4
4
|
|
|
5
5
|
#include "cppfmu/cppfmu_cs.hpp"
|
|
6
|
+
#include "pythonfmu/IPyState.hpp"
|
|
6
7
|
|
|
7
8
|
#include <Python.h>
|
|
8
9
|
#include <string>
|
|
@@ -15,7 +16,7 @@ class PySlaveInstance : public cppfmu::SlaveInstance
|
|
|
15
16
|
{
|
|
16
17
|
|
|
17
18
|
public:
|
|
18
|
-
PySlaveInstance(std::string instanceName, std::string resources, const cppfmu::Logger& logger, bool visible);
|
|
19
|
+
PySlaveInstance(std::string instanceName, std::string resources, const cppfmu::Logger& logger, bool visible, std::shared_ptr<IPyState> pyState);
|
|
19
20
|
|
|
20
21
|
void initialize(PyGILState_STATE gilState);
|
|
21
22
|
|
|
@@ -53,6 +54,7 @@ public:
|
|
|
53
54
|
~PySlaveInstance() override;
|
|
54
55
|
|
|
55
56
|
private:
|
|
57
|
+
std::shared_ptr<IPyState> pyState_;
|
|
56
58
|
PyObject* pClass_;
|
|
57
59
|
PyObject* pInstance_{};
|
|
58
60
|
PyObject* pMessages_{};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
#ifndef PYTHONFMU_PYTHONSTATE_HPP
|
|
3
|
+
#define PYTHONFMU_PYTHONSTATE_HPP
|
|
4
|
+
|
|
5
|
+
#include "IPyState.hpp"
|
|
6
|
+
#include <Python.h>
|
|
7
|
+
#include <condition_variable>
|
|
8
|
+
#include <iostream>
|
|
9
|
+
#include <mutex>
|
|
10
|
+
#include <thread>
|
|
11
|
+
|
|
12
|
+
namespace pythonfmu
|
|
13
|
+
{
|
|
14
|
+
class PyState : public IPyState
|
|
15
|
+
{
|
|
16
|
+
public:
|
|
17
|
+
PyState()
|
|
18
|
+
: _initDeinitPyThread_{ &PyState::Worker, this }
|
|
19
|
+
{
|
|
20
|
+
auto lock = std::unique_lock{ mutex_ };
|
|
21
|
+
conditionalVariable_.wait(lock, [&] { return consructed_; });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
~PyState() override
|
|
25
|
+
{
|
|
26
|
+
{
|
|
27
|
+
auto const lock = std::lock_guard{ mutex_ };
|
|
28
|
+
destroyRequested_ = true;
|
|
29
|
+
}
|
|
30
|
+
conditionalVariable_.notify_one();
|
|
31
|
+
if (_initDeinitPyThread_.joinable()) _initDeinitPyThread_.join();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private:
|
|
35
|
+
|
|
36
|
+
// In accordance to the documentation https://docs.python.org/3/c-api/init.html#c.Py_FinalizeEx
|
|
37
|
+
// the Py_Initialize/Py_Finalize should be called from the same
|
|
38
|
+
// thread. The FMI standard allows to call fmi functions from different threads, also different threads
|
|
39
|
+
// could be used for loading unloading the FMU libraries. There is a deadlock, when the simulation tool
|
|
40
|
+
// unloads the FMU library from the thread which is differs from the thread where the Py_Initialize was called.
|
|
41
|
+
// Create a new thread which is used for calling Py_Initialize and Py_Deinitialize. The thread waits for
|
|
42
|
+
// notification from destructor and then calls Py_Deinitialize.
|
|
43
|
+
|
|
44
|
+
void Worker()
|
|
45
|
+
{
|
|
46
|
+
// It will be nullptr in case when some other tool already called Py_IsInitialized.
|
|
47
|
+
// There is no need to call Py_Finalize thus, this thread can exit ASAP.
|
|
48
|
+
auto const mainPyThread = []() -> PyThreadState* {
|
|
49
|
+
auto const justInitialized = !Py_IsInitialized();
|
|
50
|
+
if (justInitialized) {
|
|
51
|
+
Py_SetProgramName(L"./PythonFMU");
|
|
52
|
+
Py_Initialize();
|
|
53
|
+
#if PY_VERSION_HEX < 0x03070000
|
|
54
|
+
PyEval_InitThreads();
|
|
55
|
+
#endif
|
|
56
|
+
return PyEval_SaveThread();
|
|
57
|
+
}
|
|
58
|
+
return nullptr;
|
|
59
|
+
}();
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
auto const lock = std::lock_guard{ mutex_ };
|
|
63
|
+
consructed_ = true;
|
|
64
|
+
}
|
|
65
|
+
conditionalVariable_.notify_one();
|
|
66
|
+
|
|
67
|
+
if (nullptr != mainPyThread) {
|
|
68
|
+
auto lock = std::unique_lock{ mutex_ };
|
|
69
|
+
conditionalVariable_.wait(lock, [&] { return destroyRequested_; });
|
|
70
|
+
|
|
71
|
+
PyEval_RestoreThread(mainPyThread);
|
|
72
|
+
Py_Finalize();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
bool consructed_ = false;
|
|
77
|
+
bool destroyRequested_ = false;
|
|
78
|
+
std::condition_variable conditionalVariable_;
|
|
79
|
+
std::mutex mutex_;
|
|
80
|
+
std::thread _initDeinitPyThread_;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
} // namespace pythonfmu
|
|
84
|
+
|
|
85
|
+
#endif //PYTHONFMU_PYTHONSTATE_HPP
|
|
Binary file
|
|
Binary file
|
|
@@ -144,7 +144,7 @@ class Dimension(object):
|
|
|
144
144
|
if self.start:
|
|
145
145
|
return self.start
|
|
146
146
|
else:
|
|
147
|
-
result = next((
|
|
147
|
+
result = next((value for vr, value in vars.items() if vr == int(self.value_reference)), None)
|
|
148
148
|
return result.getter()
|
|
149
149
|
|
|
150
150
|
def to_xml(self) -> Element:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pythonfmu3
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: A lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs.
|
|
5
5
|
Home-page: https://github.com/stephensmith25/PythonFMU3
|
|
6
6
|
Author: Stephen Smith
|
|
@@ -131,16 +131,18 @@ from pythonfmu3 import Fmi3Causality, Fmi3Slave, Boolean, Int32, Float64, String
|
|
|
131
131
|
|
|
132
132
|
class PythonSlave(Fmi3Slave):
|
|
133
133
|
|
|
134
|
-
author = "John Doe"
|
|
135
|
-
description = "A simple description"
|
|
136
|
-
|
|
137
134
|
def __init__(self, **kwargs):
|
|
138
135
|
super().__init__(**kwargs)
|
|
139
136
|
|
|
137
|
+
self.author = "John Doe"
|
|
138
|
+
self.description = "A simple description"
|
|
139
|
+
|
|
140
|
+
self.time = 0.0
|
|
140
141
|
self.intOut = 1
|
|
141
142
|
self.realOut = 3.0
|
|
142
143
|
self.booleanVariable = True
|
|
143
144
|
self.stringVariable = "Hello World!"
|
|
145
|
+
self.register_variable(Float64("time", causality=Fmi3Causality.independent))
|
|
144
146
|
self.register_variable(Int32("intOut", causality=Fmi3Causality.output))
|
|
145
147
|
self.register_variable(Float64("realOut", causality=Fmi3Causality.output))
|
|
146
148
|
self.register_variable(Boolean("booleanVariable", causality=Fmi3Causality.local))
|
|
@@ -35,6 +35,7 @@ pythonfmu3/pythonfmu-export/src/cppfmu/fmi_functions.cpp
|
|
|
35
35
|
pythonfmu3/pythonfmu-export/src/fmi/fmi3FunctionTypes.h
|
|
36
36
|
pythonfmu3/pythonfmu-export/src/fmi/fmi3Functions.h
|
|
37
37
|
pythonfmu3/pythonfmu-export/src/fmi/fmi3PlatformTypes.h
|
|
38
|
+
pythonfmu3/pythonfmu-export/src/pythonfmu/IPyState.hpp
|
|
38
39
|
pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.cpp
|
|
39
40
|
pythonfmu3/pythonfmu-export/src/pythonfmu/PySlaveInstance.hpp
|
|
40
41
|
pythonfmu3/pythonfmu-export/src/pythonfmu/PyState.hpp
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.12"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#ifndef PYTHONFMU_PYTHONSTATE_HPP
|
|
3
|
-
#define PYTHONFMU_PYTHONSTATE_HPP
|
|
4
|
-
|
|
5
|
-
#include <Python.h>
|
|
6
|
-
#include <iostream>
|
|
7
|
-
|
|
8
|
-
namespace pythonfmu
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
class PyState
|
|
12
|
-
{
|
|
13
|
-
public:
|
|
14
|
-
PyState()
|
|
15
|
-
{
|
|
16
|
-
was_initialized_ = Py_IsInitialized();
|
|
17
|
-
|
|
18
|
-
if (!was_initialized_) {
|
|
19
|
-
Py_SetProgramName(L"./PythonFMU");
|
|
20
|
-
Py_Initialize();
|
|
21
|
-
PyEval_InitThreads();
|
|
22
|
-
_mainPyThread = PyEval_SaveThread();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
~PyState()
|
|
27
|
-
{
|
|
28
|
-
if (!was_initialized_) {
|
|
29
|
-
PyEval_RestoreThread(_mainPyThread);
|
|
30
|
-
Py_Finalize();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private:
|
|
35
|
-
bool was_initialized_;
|
|
36
|
-
PyThreadState* _mainPyThread;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
} // namespace pythonfmu
|
|
40
|
-
|
|
41
|
-
#endif //PYTHONFMU_PYTHONSTATE_HPP
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_common.hpp
RENAMED
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.cpp
RENAMED
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/cppfmu_cs.hpp
RENAMED
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/cppfmu/fmi_functions.cpp
RENAMED
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/fmi/fmi3FunctionTypes.h
RENAMED
|
File without changes
|
|
File without changes
|
{pythonfmu3-0.1.12 → pythonfmu3-0.1.14}/pythonfmu3/pythonfmu-export/src/fmi/fmi3PlatformTypes.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|