Repository navigation
Expand file tree
/
Copy pathcppfmu_common.hpp
More file actions
164 lines (139 loc) · 4.37 KB
/
Copy pathcppfmu_common.hpp
File metadata and controls
164 lines (139 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* Copyright 2016-2019, SINTEF Ocean.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef CPPFMU_COMMON_HPP
#define CPPFMU_COMMON_HPP
#include <algorithm> // std::find()
#include <cstddef> // std::size_t
#include <functional> // std::function
#include <memory> // std::shared_ptr, std::unique_ptr
#include <new> // std::bad_alloc
#include <stdexcept> // std::runtime_error
#include <string> // std::basic_string, std::char_traits
#include <utility> // std::forward
#include <vector>
extern "C"
{
#include "fmi/fmi3Functions.h"
}
// CPPFMU_NOEXCEPT evaluates to 'noexcept' on compilers that support it.
#if (__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
# define CPPFMU_NOEXCEPT noexcept
#else
# define CPPFMU_NOEXCEPT
#endif
namespace cppfmu
{
// Aliases for FMI types and enums
typedef fmi3Float64 FMIFloat64;
typedef fmi3Int32 FMIInt32;
typedef fmi3Int64 FMIInt64;
typedef fmi3UInt64 FMIUInt64;
typedef fmi3Boolean FMIBoolean;
typedef fmi3String FMIString;
typedef fmi3LogMessageCallback FMICallbackLogger;
typedef fmi3Instance FMIComponent;
typedef fmi3InstanceEnvironment FMIComponentEnvironment;
typedef fmi3Status FMIStatus;
typedef fmi3ValueReference FMIValueReference;
const FMIBoolean FMIFalse = fmi3False;
const FMIBoolean FMITrue = fmi3True;
const FMIStatus FMIOK = fmi3OK;
const FMIStatus FMIWarning = fmi3Warning;
const FMIStatus FMIDiscard = fmi3Discard;
const FMIStatus FMIError = fmi3Error;
const FMIStatus FMIFatal = fmi3Fatal;
using String = std::string;
// ============================================================================
// ERROR HANDLING
// ============================================================================
/* Exception class that signals "fatal error", i.e. an error which means that
* not only is the current model instance invalid, but all other instances of
* the same model too.
*/
class FatalError : public std::runtime_error
{
public:
FatalError(const char* msg) CPPFMU_NOEXCEPT : std::runtime_error{msg} { }
};
// ============================================================================
// LOGGING
// ============================================================================
namespace detail
{
template<typename Container, typename Item>
bool CanFind(const Container& container, const Item& item)
{
return container.end() != std::find(
container.begin(),
container.end(),
item);
}
}
/* A class that can be used to log messages from model code. All messages are
* forwarded to the logging facilities provided by the simulation environment.
*/
class Logger
{
public:
struct Settings
{
bool debugLoggingEnabled = false;
std::vector<String> loggedCategories;
};
Logger(
FMIComponentEnvironment component,
fmi3LogMessageCallback logCallback,
std::shared_ptr<Settings> settings)
: m_component{component}
, m_fmiLogger{logCallback}
, m_settings{settings}
{
}
// Logs a message.
template<typename... Args>
void Log(
FMIStatus status,
FMIString category,
FMIString message,
Args&&... args) CPPFMU_NOEXCEPT
{
if (m_fmiLogger == nullptr) {
return; // FMI 3.0 allows instantiating without a logger callback
}
if (m_settings->loggedCategories.empty() ||
detail::CanFind(m_settings->loggedCategories, category)) {
m_fmiLogger(
m_component,
status,
category,
message);
}
}
/* Logs a debug message (if debug logging is enabled by the simulation
* environment).
*/
template<typename... Args>
void DebugLog(
FMIStatus status,
FMIString category,
FMIString message,
Args&&... args) CPPFMU_NOEXCEPT
{
if (m_settings->debugLoggingEnabled) {
Log(
status,
category,
message,
std::forward<Args>(args)...);
}
}
private:
const FMIComponentEnvironment m_component;
const FMICallbackLogger m_fmiLogger;
std::shared_ptr<Settings> m_settings;
};
} // namespace cppfmu
#endif // header guard