Complete refactor of basyx::vab and basyx::shared in C++ sdk, introducing new object type system basyx::object
Change-Id: I0058ddcb07c5005dc40e3c81b648efe7621c3121
Signed-off-by: Thomas Psota <thomas.psota@iese.fraunhofer.de>
diff --git a/sdks/c++/basys.sdk.cc/src/shared/basyx/object/obj_function.h b/sdks/c++/basys.sdk.cc/src/shared/basyx/object/obj_function.h
new file mode 100644
index 0000000..48c81f8
--- /dev/null
+++ b/sdks/c++/basys.sdk.cc/src/shared/basyx/object/obj_function.h
@@ -0,0 +1,112 @@
+#ifndef OBJ_FUNCTION_H
+#define OBJ_FUNCTION_H
+
+#include <functional>
+
+#include <basyx/object/object_header.h>
+
+#include <json/json.hpp>
+
+namespace basyx {
+namespace detail {
+
+class functionWrapper
+{
+private:
+ std::function<basyx::object(basyx::object*)> func;
+
+ template <typename R, typename... Args, std::size_t... Is>
+ static R invoke_helper(std::function<R(Args...)> f, basyx::object::object_list_t & params, util::index_sequence<Is...>)
+ {
+ return f(params[Is].Get<Args&>()...);
+ };
+public:
+ // Invoke wrapped function with no arguments
+ basyx::object invoke()
+ {
+ return func(nullptr);
+ };
+
+ // Invoke wrapped function with argument
+ // Has to be primitive object or object list
+ basyx::object invoke(basyx::object & obj)
+ {
+ return func(&obj);
+ };
+
+ // Wrap function with no arguments
+ template<typename RetType>
+ static functionWrapper wrap_func(std::function<RetType(void)> f)
+ {
+ functionWrapper fw;
+ fw.func = [f](basyx::object*)
+ {
+ return basyx::object{ f() };
+ };
+ return fw;
+ };
+
+ // Wrap function with single argument
+ template<typename RetType, typename Arg>
+ static functionWrapper wrap_func(std::function<RetType(Arg)> f)
+ {
+ functionWrapper fw;
+ fw.func = [f](basyx::object * obj)
+ {
+ // Only allow primitive object types
+ if (obj != nullptr && obj->GetObjectType() == basyx::type::objectType::Primitive && obj->GetValueType() == basyx::type::basyx_type<Arg>::value_type)
+ {
+ // Cast object to argument type and invoke
+ auto & i = obj->Get<Arg&>();
+ return basyx::object{ f(i) };
+ };
+
+ return basyx::object::make_null();
+ };
+ return fw;
+ };
+
+ // Wrap function with argument list
+ template<typename RetType, typename... Args>
+ static functionWrapper wrap_func(std::function<RetType(Args...)> f)
+ {
+ functionWrapper fw;
+ fw.func = [f](basyx::object * obj)
+ {
+ // Only allow object lists
+ if (obj != nullptr && obj->GetObjectType() == basyx::type::objectType::List && obj->GetValueType() == basyx::type::valueType::Object)
+ {
+ auto & list = obj->Get<basyx::object::object_list_t&>();
+
+ // if size of argument list differs from the functions parameter list, return null
+ if (list.size() != sizeof...(Args))
+ return basyx::object::make_null();
+
+ // TODO: type check arguments
+
+ // Invoke, using an integer sequence to pass the values from the list as single parameters to the function
+ return basyx::object{ invoke_helper<RetType, Args...>(f, list, util::make_index_sequence<sizeof...(Args)>{}) };
+ };
+
+ return basyx::object::make_null();
+ };
+ return fw;
+ };
+
+ template<typename T>
+ bool operator==(const T &) const
+ {
+ return false;
+ };
+};
+
+static void to_json(nlohmann::json & json, const functionWrapper &)
+{
+ return;
+};
+
+}
+}
+
+
+#endif /* OBJ_FUNCTION_H */