Skip to content

Commit

Permalink
allow lambdas too
Browse files Browse the repository at this point in the history
  • Loading branch information
markaren committed Dec 3, 2024
1 parent 8746355 commit ff365e2
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 10 deletions.
12 changes: 12 additions & 0 deletions export/include/fmu4cpp/fmu_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,24 @@ namespace fmu4cpp {

protected:
IntVariable integer(const std::string &name, int *ptr);
IntVariable integer(const std::string &name,
const std::function<int()> &getter,
const std::optional<std::function<void(int)>> &setter = std::nullopt);

RealVariable real(const std::string &name, double *ptr);
RealVariable real(const std::string &name,
const std::function<double()> &getter,
const std::optional<std::function<void(double)>> &setter = std::nullopt);

BoolVariable boolean(const std::string &name, bool *ptr);
BoolVariable boolean(const std::string &name,
const std::function<bool()> &getter,
const std::optional<std::function<void(bool)>> &setter);

StringVariable string(const std::string &name, std::string *ptr);
StringVariable string(const std::string &name,
const std::function<std::string()> &getter,
const std::optional<std::function<void(std::string)>> &setter = std::nullopt);

void register_variable(IntVariable v);
void register_variable(RealVariable v);
Expand Down
52 changes: 48 additions & 4 deletions export/include/fmu4cpp/fmu_variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#ifndef FMU4CPP_FMU_VARIABLE_HPP
#define FMU4CPP_FMU_VARIABLE_HPP

#include "variable_access.hpp"

#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
Expand Down Expand Up @@ -36,6 +39,7 @@ namespace fmu4cpp {
std::string to_string(const variability_t &v);
std::string to_string(const initial_t &i);


class VariableBase {

protected:
Expand Down Expand Up @@ -95,18 +99,27 @@ namespace fmu4cpp {
Variable(
const std::string &name,
unsigned int vr, size_t index, T *ptr)
: VariableBase(name, vr, index), ptr_(ptr) {}
: VariableBase(name, vr, index), access_(std::make_unique<PtrAccess<T>>(ptr)) {}

Variable(
const std::string &name,
unsigned int vr, size_t index,
std::function<T()> getter,
std::optional<std::function<void(T)>> setter)
: VariableBase(name, vr, index),
access_(std::make_unique<LambdaAccess<T>>(std::move(getter), std::move(setter))) {}

[[nodiscard]] T get() const {
return *ptr_;

return access_->get();
}

void set(T value) {
if (causality_ == causality_t::LOCAL || causality_ == causality_t::OUTPUT) {
throw std::logic_error("Cannot set value for variable with causality: " + to_string(causality_));
}

*ptr_ = value;
access_->set(value);
}

V &setCausality(causality_t causality) {
Expand All @@ -132,7 +145,7 @@ namespace fmu4cpp {
}

private:
T *ptr_;
std::shared_ptr<VariableAccess<T>> access_;
};

class IntVariable final : public Variable<int, IntVariable> {
Expand All @@ -143,6 +156,13 @@ namespace fmu4cpp {
unsigned int vr, size_t index, int *ptr)
: Variable(name, vr, index, ptr) {}

IntVariable(
const std::string &name,
unsigned int vr, size_t index,
const std::function<int()> &getter,
const std::optional<std::function<void(int)>> &setter)
: Variable(name, vr, index, getter, setter) {}

[[nodiscard]] std::optional<int> getMin() const {
return min_;
}
Expand Down Expand Up @@ -177,6 +197,16 @@ namespace fmu4cpp {
variability_ = variability_t::CONTINUOUS;
}

RealVariable(
const std::string &name,
unsigned int vr, size_t index,
const std::function<double()> &getter,
const std::optional<std::function<void(double)>> &setter)
: Variable(name, vr, index, getter, setter) {

variability_ = variability_t::CONTINUOUS;
}

[[nodiscard]] std::optional<double> getMin() const {
return min_;
}
Expand Down Expand Up @@ -207,6 +237,13 @@ namespace fmu4cpp {
const std::string &name,
unsigned int vr, size_t index, bool *ptr)
: Variable(name, vr, index, ptr) {}

BoolVariable(
const std::string &name,
unsigned int vr, size_t index,
const std::function<bool()> &getter,
const std::optional<std::function<void(bool)>> &setter)
: Variable(name, vr, index, getter, setter) {}
};

class StringVariable final : public Variable<std::string, StringVariable> {
Expand All @@ -216,6 +253,13 @@ namespace fmu4cpp {
const std::string &name,
unsigned int vr, size_t index, std::string *ptr)
: Variable(name, vr, index, ptr) {}

StringVariable(
const std::string &name,
unsigned int vr, size_t index,
const std::function<std::string()> &getter,
const std::optional<std::function<void(std::string)>> &setter)
: Variable(name, vr, index, getter, setter) {}
};

bool requires_start(const VariableBase &v);
Expand Down
62 changes: 62 additions & 0 deletions export/include/fmu4cpp/variable_access.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#ifndef VARIABLEACCESS_HPP
#define VARIABLEACCESS_HPP

#include <functional>
#include <optional>
#include <utility>

namespace fmu4cpp {

template<typename T>
struct VariableAccess {
virtual T get() = 0;
virtual void set(T value) = 0;

virtual ~VariableAccess() = default;
};

template<typename T>
class PtrAccess final : public VariableAccess<T> {

public:
explicit PtrAccess(T *ptr) : ptr_(ptr) {}

T get() override {
return *ptr_;
}

void set(T value) override {
*ptr_ = value;
}

private:
T *ptr_;
};

template<typename T>
class LambdaAccess final : public VariableAccess<T> {

public:
LambdaAccess(std::function<T()> getter, std::optional<std::function<void(T)>> setter)
: getter_(std::move(getter)),
setter_(std::move(setter)) {}

T get() override {
return getter_();
}

void set(T value) override {
if (setter_) {
setter_->operator()(value);
}
}

private:
std::function<T()> getter_;
std::optional<std::function<void(T)>> setter_;
};

}// namespace fmu4cpp

#endif//VARIABLEACCESS_HPP
24 changes: 20 additions & 4 deletions export/src/fmu4cpp/fmu_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,38 @@ namespace fmu4cpp {
return ss.str();
}

IntVariable fmu_base::integer(const std::string &name, int* ptr) {
IntVariable fmu_base::integer(const std::string &name, int *ptr) {
return {name, static_cast<unsigned int>(integers_.size()), numVariables_++, ptr};
}

RealVariable fmu_base::real(const std::string &name, double* ptr) {
IntVariable fmu_base::integer(const std::string &name, const std::function<int()> &getter, const std::optional<std::function<void(int)>> &setter) {
return {name, static_cast<unsigned int>(integers_.size()), numVariables_++, getter, setter};
}

RealVariable fmu_base::real(const std::string &name, double *ptr) {
return {name, static_cast<unsigned int>(reals_.size()), numVariables_++, ptr};
}

BoolVariable fmu_base::boolean(const std::string &name, bool* ptr) {
RealVariable fmu_base::real(const std::string &name, const std::function<double()> &getter, const std::optional<std::function<void(double)>> &setter) {
return {name, static_cast<unsigned int>(reals_.size()), numVariables_++, getter, setter};
}

BoolVariable fmu_base::boolean(const std::string &name, bool *ptr) {
return {name, static_cast<unsigned int>(booleans_.size()), numVariables_++, ptr};
}

StringVariable fmu_base::string(const std::string &name, std::string* ptr) {
BoolVariable fmu_base::boolean(const std::string &name, const std::function<bool()> &getter, const std::optional<std::function<void(bool)>> &setter) {
return {name, static_cast<unsigned int>(booleans_.size()), numVariables_++, getter, setter};
}

StringVariable fmu_base::string(const std::string &name, std::string *ptr) {
return {name, static_cast<unsigned int>(strings_.size()), numVariables_++, ptr};
}

StringVariable fmu_base::string(const std::string &name, const std::function<std::string()> &getter, const std::optional<std::function<void(std::string)>> &setter) {
return {name, static_cast<unsigned int>(strings_.size()), numVariables_++, getter, setter};
}

void fmu_base::register_variable(IntVariable v) {
integers_.emplace_back(std::move(v));
}
Expand Down
3 changes: 1 addition & 2 deletions export/tests/identity_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Model : public fmu4cpp::fmu_base {
.setInitial(fmu4cpp::initial_t::CALCULATED)
.setDependencies({get_bool_variable("booleanIn")->index()}));

register_variable(string("stringOut", &string_)
register_variable(string("stringOut", [this] { return string_; })
.setCausality(fmu4cpp::causality_t::OUTPUT)
.setVariability(fmu4cpp::variability_t::DISCRETE)
.setInitial(fmu4cpp::initial_t::CALCULATED)
Expand All @@ -64,7 +64,6 @@ class Model : public fmu4cpp::fmu_base {
}

bool do_step(double currentTime, double dt) override {
log(fmi2OK, "hello@ " + std::to_string(currentTime));
return true;
}

Expand Down

0 comments on commit ff365e2

Please sign in to comment.