2019-10-24 06:36:42 -07:00
|
|
|
/*
|
|
|
|
* Copyright 2019 by its authors. See AUTHORS.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
#ifndef EET_HH_
|
|
|
|
#define EET_HH_
|
|
|
|
|
|
|
|
#include <Eet.h>
|
|
|
|
|
|
|
|
#include <eet_type.hh>
|
|
|
|
#include <eet_register.hh>
|
|
|
|
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
#include <eina_fold.hh>
|
|
|
|
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
#include <type_traits>
|
|
|
|
#include <cassert>
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <array>
|
|
|
|
|
|
|
|
namespace efl { namespace eet { namespace _detail {
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void* _allocate( ::size_t size )
|
|
|
|
{
|
|
|
|
assert(size == sizeof(T));
|
|
|
|
(void)size;
|
|
|
|
return new T();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void _deallocate( void* p )
|
|
|
|
{
|
|
|
|
delete static_cast<T*>(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
struct descriptor_type
|
|
|
|
{
|
|
|
|
struct push_back
|
|
|
|
{
|
|
|
|
template <typename A, typename B>
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
struct apply : eina::_mpl::push_back<A, typename _detail::member_type<typename B::member_type>::type> {};
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
};
|
|
|
|
|
eldbus-cxx: Implementation of eldbus C++ API
Summary:
Applications can:
void method_callback(void* data, const Eldbus_Service_Interface* iface,
const Eldbus_Message* message);
struct { ... } data_struct;
Eldbus_Method methods[] =
{
"method1", ELDBUS_ARGS("b", "bool"), ELDBUS_ARGS("b", "bool"), ELDBUS_METHOD_FLAG_HAS_DATA
, (Eldbus_Method_Cb)&method_callback, &data_struct
};
And method_callback will be called with data parameter pointing to data_struct global object.
Also, Eldbus-cxx supports registering an interface passing a lambda or
function object as method. For example:
edb::service_interface iface = edb::service_interface_register
(c, path, interface
, es::method("SendStringAndBool"
, [expected_string, expected_bool] (std::string const& n, bool b
, bool* out)
{
std::cout << "Running SendStringAndBool" << std::endl;
ck_assert(n == expected_string);
ck_assert(b == expected_bool);
*out = b;
return n;
}
, es::ins<std::string, bool>("string", "bool")
, es::outs<std::string, bool>("string", "bool")
)
);
When a request for "SendStringAndBool" with the proper signature is
called, executes the lambda and replies with the return value and
its bool* out parameter value.
Reviewers: cedric, woohyun, raster
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D1052
2014-07-03 00:28:22 -07:00
|
|
|
typedef typename eina::_mpl::fold< std::tuple<Args...>, push_back
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
, descriptor<T> >::type type;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#define EET_CXX_MEMBER(C, I) ::efl::eet::type(#I, &C::I)
|
|
|
|
|
|
|
|
template <typename F>
|
|
|
|
_detail::member_info<F, void> type(const char* name, F f)
|
|
|
|
{
|
|
|
|
typedef typename _detail::member_type<F>::type member_type;
|
|
|
|
static_assert(is_eet_primitive<member_type>::value, "");
|
|
|
|
static_assert(std::is_member_pointer<F>::value, "");
|
|
|
|
return _detail::member_info<F, void>{name, f};
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename F, typename U, typename... Args>
|
|
|
|
_detail::member_info<F, U, Args...> type(const char* name, F f, descriptor<U, Args...> const& descriptor)
|
|
|
|
{
|
|
|
|
typedef typename _detail::member_type<F>::type member_type;
|
|
|
|
static_assert(!is_eet_primitive<member_type>::value, "");
|
|
|
|
static_assert(std::is_member_pointer<F>::value, "");
|
|
|
|
return _detail::member_info<F, U, Args...>{name, f, &descriptor};
|
|
|
|
}
|
|
|
|
|
|
|
|
struct eet_init
|
|
|
|
{
|
|
|
|
eet_init()
|
|
|
|
{
|
|
|
|
::eet_init();
|
|
|
|
}
|
|
|
|
~eet_init()
|
|
|
|
{
|
|
|
|
::eet_shutdown();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
struct descriptor
|
|
|
|
{
|
|
|
|
typedef T object_type;
|
|
|
|
|
|
|
|
descriptor() : _descriptor(nullptr) {}
|
2014-07-03 15:35:40 -07:00
|
|
|
descriptor( ::Eet_Data_Descriptor* descriptor_
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
, std::array<_detail::member_desc_info, sizeof...(Args)> member_info)
|
2014-07-03 15:35:40 -07:00
|
|
|
: _descriptor(descriptor_), _member_info(member_info)
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
descriptor(descriptor&& other)
|
|
|
|
: _descriptor(other._descriptor)
|
|
|
|
{
|
|
|
|
other._descriptor = 0;
|
|
|
|
}
|
|
|
|
descriptor& operator=(descriptor&& other)
|
|
|
|
{
|
|
|
|
if(_descriptor)
|
|
|
|
eet_data_descriptor_free(_descriptor);
|
|
|
|
_descriptor = other._descriptor;
|
|
|
|
other._descriptor = 0;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
~descriptor()
|
|
|
|
{
|
|
|
|
if(_descriptor)
|
|
|
|
eet_data_descriptor_free(_descriptor);
|
|
|
|
}
|
|
|
|
typedef ::Eet_Data_Descriptor const* const_native_handle_type;
|
|
|
|
typedef ::Eet_Data_Descriptor* native_handle_type;
|
|
|
|
const_native_handle_type native_handle() const
|
|
|
|
{
|
|
|
|
return _descriptor;
|
|
|
|
}
|
|
|
|
native_handle_type native_handle()
|
|
|
|
{
|
|
|
|
return _descriptor;
|
|
|
|
}
|
|
|
|
typedef std::integral_constant<std::size_t, sizeof...(Args)> members;
|
|
|
|
|
|
|
|
std::array<_detail::member_desc_info, sizeof...(Args)> get_member_info() const { return _member_info; }
|
|
|
|
private:
|
|
|
|
::Eet_Data_Descriptor* _descriptor;
|
|
|
|
typedef descriptor<T, Args...> _self_type;
|
|
|
|
descriptor(descriptor const&) = delete;
|
|
|
|
descriptor& operator=(descriptor const&) = delete;
|
|
|
|
std::array<_detail::member_desc_info, sizeof...(Args)> _member_info;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
std::unique_ptr<T> read_by_ptr(Eet_File* file, const char* name, descriptor<T, Args...> const& d)
|
|
|
|
{
|
|
|
|
void* p = eet_data_read(file, const_cast<descriptor<T, Args...>&>(d).native_handle(), name);
|
|
|
|
return std::unique_ptr<T>(static_cast<T*>(p));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
T read(Eet_File* file, const char* name, descriptor<T, Args...> const& d)
|
|
|
|
{
|
|
|
|
typename std::aligned_storage<sizeof(T), alignof(T)>::type buffer;
|
|
|
|
void * p =
|
|
|
|
::eet_data_read_cipher_buffer
|
|
|
|
(file
|
|
|
|
, const_cast<descriptor<T, Args...>&>(d).native_handle()
|
|
|
|
, name, 0
|
|
|
|
, static_cast<char*>(static_cast<void*>(&buffer))
|
|
|
|
, sizeof(buffer));
|
|
|
|
if(p)
|
|
|
|
{
|
|
|
|
assert(p == &buffer);
|
|
|
|
return *static_cast<T*>(p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw std::runtime_error("");
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace _detail {
|
|
|
|
|
|
|
|
template <typename O>
|
|
|
|
inline void _item_fill(O*, ::Eet_Data_Descriptor*, member_desc_info*) {}
|
|
|
|
|
|
|
|
template <typename O, typename F, typename D, typename... Args, typename... FArgs>
|
|
|
|
inline void _item_fill(O* obj, ::Eet_Data_Descriptor* cls, member_desc_info* offset
|
|
|
|
, _detail::member_info<F, D, Args...> arg0, FArgs... args)
|
|
|
|
{
|
|
|
|
static_assert(std::is_member_object_pointer<F>::value, "");
|
|
|
|
offset->offset = static_cast<char*>( static_cast<void*>( &(obj ->* arg0.member) ))
|
|
|
|
- static_cast<char*>( static_cast<void*>( obj ) );
|
|
|
|
offset->name = arg0.name;
|
|
|
|
_detail::_item_fill(obj, cls, ++offset, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename F, typename D, typename... OArgs, typename... Args>
|
|
|
|
typename _detail::descriptor_type
|
|
|
|
<typename _detail::object_type<F>::type
|
|
|
|
, _detail::member_info<F, D, OArgs...>, Args...
|
|
|
|
>::type make_descriptor(const char* name, _detail::member_info<F, D, OArgs...> a0, Args... args)
|
|
|
|
{
|
|
|
|
typedef F member_pointer;
|
|
|
|
static_assert(std::is_member_object_pointer<member_pointer>::value, "");
|
|
|
|
typedef typename _detail::object_type<member_pointer>::type object_type;
|
|
|
|
|
|
|
|
typedef typename _detail::descriptor_type
|
|
|
|
<object_type, _detail::member_info<F, D, OArgs...>, Args...>::type descriptor_type;
|
|
|
|
|
2014-04-09 03:11:46 -07:00
|
|
|
::Eet_Data_Descriptor_Class cls;
|
|
|
|
eet_eina_file_data_descriptor_class_set(&cls, sizeof(cls), name, sizeof(object_type));
|
|
|
|
cls.func.mem_alloc = & _detail::_allocate<object_type>;
|
|
|
|
cls.func.mem_free = & _detail::_deallocate<object_type>;
|
eet-cxx: add implementation for eet C++.
Usage example:
struct type
{
int foo;
float bar;
};
type t0;
auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
type t = read(file, "type", descriptor);
@feature
Reviewers: cedric, smohanty
Reviewed By: cedric
CC: savio, cedric
Differential Revision: https://phab.enlightenment.org/D659
Signed-off-by: Cedric BAIL <cedric.bail@free.fr>
2014-04-01 03:08:07 -07:00
|
|
|
::Eet_Data_Descriptor* native_handle = eet_data_descriptor_stream_new(&cls);
|
|
|
|
if(!native_handle)
|
|
|
|
throw std::runtime_error("");
|
|
|
|
|
|
|
|
typename std::aligned_storage<sizeof(object_type), alignof(object_type)>::type buffer;
|
|
|
|
object_type* p = static_cast<object_type*>(static_cast<void*>(&buffer));
|
|
|
|
|
|
|
|
std::array<_detail::member_desc_info, sizeof...(Args)+1> offsets;
|
|
|
|
_detail::_item_fill(p, native_handle, &offsets[0], a0, args...);
|
|
|
|
_detail::descriptor_type_register(native_handle, &offsets[0], a0, args...);
|
|
|
|
|
|
|
|
return descriptor_type(native_handle, offsets);
|
|
|
|
}
|
|
|
|
|
|
|
|
} }
|
|
|
|
|
|
|
|
#endif
|