Commit 114c8513 authored by Ronan's avatar Ronan

feat(Object): meta info on signals are registered correctly

parent 8e601e98
......@@ -279,11 +279,79 @@ namespace Private {
#define L_DECL_C_STRUCT_PREFIX_LESS(STRUCT) typedef struct STRUCT STRUCT;
// -----------------------------------------------------------------------------
// Generic helpers.
// Index Sequence (C++11 impl).
// -----------------------------------------------------------------------------
template<std::size_t...>
struct IndexSequence {
using type = IndexSequence;
};
namespace Private {
template<class S1, class S2>
struct ConcatSequence;
template<std::size_t... S1, std::size_t... S2>
struct ConcatSequence<IndexSequence<S1...>, IndexSequence<S2...>> :
IndexSequence<S1..., (sizeof...(S1) + S2)...> {};
template<std::size_t N>
struct MakeIndexSequence : ConcatSequence<
typename MakeIndexSequence<N / 2>::type,
typename MakeIndexSequence<N - N / 2>::type
> {};
template<>
struct MakeIndexSequence<0> : IndexSequence<> {};
template<>
struct MakeIndexSequence<1> : IndexSequence<0> {};
}
template<std::size_t N>
using MakeIndexSequence = typename Private::MakeIndexSequence<N>::type;
// -----------------------------------------------------------------------------
// Compil-time string.
// -----------------------------------------------------------------------------
namespace Private {
constexpr bool equal (const char *a, const char *b) {
return *a == *b ? (*a == '\0' || equal(a + 1, b + 1)) : false;
}
}
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf
template<int N> using StringLiteral = const char [N];
template<std::size_t N> using RawStringLiteral = const char [N];
template<std::size_t N, typename = MakeIndexSequence<N>>
struct StringLiteral;
template<std::size_t N, std::size_t... Index>
struct StringLiteral<N, IndexSequence<Index...>> {
constexpr StringLiteral (RawStringLiteral<N> &inRaw) : raw{ (inRaw[Index])... } {}
constexpr char operator[] (std::size_t p) const {
return raw[p];
}
template<std::size_t M>
constexpr bool operator== (const StringLiteral<M> &other) const {
return N != M ? false : Private::equal(raw, other.raw);
}
template<std::size_t M>
constexpr bool operator!= (const StringLiteral<M> &other) const {
return !(*this == other);
}
RawStringLiteral<N> raw;
};
template<std::size_t N>
constexpr StringLiteral<N> makeStringLiteral (RawStringLiteral<N> &raw) {
return StringLiteral<N>(raw);
}
#endif // ifdef __cplusplus
......
......@@ -248,6 +248,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
object/base-object.cpp
object/clonable-object.cpp
object/connection.cpp
object/internal/signal-emitter.cpp
object/object.cpp
object/property-container.cpp
sal/call-op.cpp
......
/*
* signal-emitter.cpp
* Copyright (C) 2010-2017 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "signal-emitter.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
namespace Private {
void activateSignal (Object *sender, int signalIndex, void **args) {
// TODO.
}
}
LINPHONE_END_NAMESPACE
......@@ -132,8 +132,8 @@ namespace Private {
};
template<typename Signal, int NameLength>
constexpr MetaObjectSignalInfo<Signal, NameLength> makeMetaObjectSignalInfo (Signal signal, StringLiteral<NameLength> &name) {
return { signal, *name };
constexpr MetaObjectSignalInfo<Signal, NameLength> makeMetaObjectSignalInfo (Signal signal, RawStringLiteral<NameLength> &name) {
return { signal, { name } };
}
};
......
......@@ -30,8 +30,19 @@ using namespace LinphonePrivate;
// -----------------------------------------------------------------------------
#define CHECK_SIGNAL(NAME, INDEX) \
#define GET_SIGNAL_INFO(INDEX) \
get<INDEX>(lMetaSignals( \
Private::MetaObjectCounter<INDEX + 1>(), \
static_cast<lType **>(nullptr) \
))
#define CHECK_SIGNAL_INDEX(INDEX, NAME) \
static_assert(L_INTERNAL_SIGNAL_INDEX(NAME, __LINE__) == INDEX, "Bad signal index.");
#define CHECK_SIGNAL_META_INTO(INDEX, NAME, ARGS_NUMBER) \
static_assert(GET_SIGNAL_INFO(INDEX).argumentsNumber == ARGS_NUMBER, "Unexpected arguments number in `" NAME "`."); \
static_assert(GET_SIGNAL_INFO(INDEX).name == makeStringLiteral(NAME), "Unexpected signal name for `" NAME "`.");
class TestObjectPrivate : public ObjectPrivate {
public:
};
......@@ -42,15 +53,12 @@ class TestObject : public Object {
public:
TestObject () : Object(*new TestObjectPrivate) {}
L_SIGNAL(signal1, (int, float), toto, tata); CHECK_SIGNAL(signal1, 0);
L_SIGNAL(signal2, (bool, float, int), a, b, c); CHECK_SIGNAL(signal2, 1);
static void toto () {
lMetaSignals(
LinphonePrivate::Private::MetaObjectCounter<5>(),
static_cast<lType **>(nullptr)
);
L_SIGNAL(signal1, (int, float), toto, tata); CHECK_SIGNAL_INDEX(0, signal1);
L_SIGNAL(signal2, (bool, float, int), a, b, c); CHECK_SIGNAL_INDEX(1, signal2);
static void checkMetaInfoAtCompileTime () {
CHECK_SIGNAL_META_INTO(0, "signal1", 2);
CHECK_SIGNAL_META_INTO(1, "signal2", 3);
}
private:
......@@ -62,7 +70,6 @@ private:
static void check_object_creation () {
TestObject *object = new TestObject();
TestObject::toto();
delete object;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment