X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=include%2Fafb%2Fc%2B%2B%2Fbinding-wrap.hpp;h=f94d1bc56375372bef16a93c89bf348293cf6dc2;hb=33ddfb569b0fb223e212408ab3994bdae70861d7;hp=a23e5537a033cfc94963dc4a90e71fca304ff626;hpb=78fcce21a8b611de175223bff67f4a49fa95e64e;p=src%2Fapp-framework-binder.git diff --git a/include/afb/c++/binding-wrap.hpp b/include/afb/c++/binding-wrap.hpp index a23e5537..f94d1bc5 100644 --- a/include/afb/c++/binding-wrap.hpp +++ b/include/afb/c++/binding-wrap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author: José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,7 @@ #include #include #include +#include /* ensure version */ #ifndef AFB_BINDING_VERSION @@ -258,8 +259,6 @@ public: void failf(const char *error, const char *info, ...) const; void failv(const char *error, const char *info, va_list args) const; - template < class T > T *context() const; - void addref() const; void unref() const; @@ -294,6 +293,54 @@ public: int get_uid() const; json_object *get_client_info() const; + + template < class T = void > + class contextclass { + + friend class req; + afb_req_t req_; + contextclass(afb_req_t r) : req_(r) {} + + public: + inline operator T *() const { return get(); } + inline operator T &() const { return *get(); } + inline T* get() const { + return reinterpret_cast( + afb_req_context(req_, 0, + nullptr, + nullptr, + nullptr)); + } + + inline void set(T *value, void (*destroyer)(T*) = [](T*t){delete t;}) const { + afb_req_context(req_, 1, + nullptr, + reinterpret_cast(destroyer), + reinterpret_cast(value)); + } + + inline void unset() { set(nullptr); } + inline void clear() { set(nullptr); } + + inline T *lazy(T *(*allocator)() = []()->T*{return new T();}, void (*destroyer)(T*) = [](T*t){delete t;}) const { + return reinterpret_cast( + afb_req_context(req_, 0, + [allocator](void*)->T*{return allocator();}, + reinterpret_cast(destroyer), + nullptr)); + } + + template + inline T *lazy(I *i, T *(*allocator)(I*) = [](I*i)->T*{return new T(i);}, void (*destroyer)(T*) = [](T*t){delete t;}) const { + return reinterpret_cast( + afb_req_context(req_, 0, + [allocator](void*i)->T*{return allocator(reinterpret_cast(i));}, + reinterpret_cast(destroyer), + reinterpret_cast(i))); + } + }; + + template < class T > contextclass context() const { return contextclass(req_); } }; /*************************************************************************/ @@ -476,16 +523,6 @@ inline void req::failf(const char *error, const char *info, ...) const va_end(args); } -template < class T > -inline T *req::context() const -{ - T* (*creater)(void*) = [](){return new T();}; - void (*freer)(T*) = [](T*t){delete t;}; - return reinterpret_cast(afb_req_context(req_, 0, - reinterpret_cast(creater), - reinterpret_cast(freer), nullptr)); -} - inline void req::addref() const { afb_req_addref(req_); } inline void req::unref() const { afb_req_unref(req_); } @@ -717,15 +754,7 @@ constexpr afb_verb_t verb( void *vcbdata = nullptr ) { - afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 }; - r.verb = name; - r.callback = callback; - r.info = info; - r.session = session; - r.auth = auth; - r.glob = (uint16_t)glob; - r.vcbdata = vcbdata; - return r; + return { name, callback, auth, info, vcbdata, session, glob }; } void __attribute__((weak)) __afb__verb__cb__for__global__(afb_req_t r) @@ -740,12 +769,11 @@ void __attribute__((weak)) __afb__verb__cb__for__global__(afb_req_t r) constexpr afb_verb_t verb( const char *name, - void (&callback)(req), + void (*callback)(req), const char *info = nullptr, uint16_t session = 0, const afb_auth *auth = nullptr, - bool glob = false, - void *vcbdata = nullptr + bool glob = false ) { return verb( @@ -755,14 +783,13 @@ constexpr afb_verb_t verb( session, auth, glob, - (void*)(&callback) + *(void**)(&callback) ); } constexpr afb_verb_t verbend() { - afb_verb_t r = verb(nullptr, nullptr); - return r; + return { 0, 0, 0, 0, 0, 0, 0 }; } constexpr afb_binding_t binding( @@ -777,17 +804,9 @@ constexpr afb_binding_t binding( void *userdata = nullptr ) { - afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - r.api = name; - r.specification = specification; - r.info = info; - r.verbs = verbs; - r.preinit = preinit; - r.init = init; - r.onevent = onevent; - r.noconcurrency = noconcurrency ? 1 : 0; - r.userdata = userdata; - return r; + return { + name, specification, info, verbs, preinit, init, onevent, userdata, + nullptr, nullptr, nullptr, static_cast(noconcurrency) }; }; /*************************************************************************/