Files
uLib/src/Core/Object.h

274 lines
9.2 KiB
C++

/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_OBJECT_H
#define U_CORE_OBJECT_H
#include <iostream>
#include <string>
// WARNING: COPILE ERROR if this goes after mpl/vector //
// #include "Core/Vector.h"
#include "Core/Debug.h"
#include "Core/Types.h"
#include "Core/Function.h"
#include "Core/Signal.h"
#include "Core/Mpl.h"
#include "Core/Serializable.h"
#include "Core/Uuid.h"
namespace boost {
namespace archive {
class polymorphic_iarchive;
class polymorphic_oarchive;
} // namespace archive
} // namespace boost
namespace uLib {
class PropertyBase;
class ObjectsContext;
class Version {
public:
static const char *PackageName;
static const char *VersionNumber;
static const char *Release;
};
////////////////////////////////////////////////////////////////////////////////
//// OBJECT ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* @brief Object class is the object base implementation for uLib Framework.
*/
class Object {
public:
// std::string name;
// void PrintName() { std::cout << "Ob name: " << name << "\n"; }
Object();
Object(const Object &copy);
virtual ~Object();
virtual const char *GetClassName() const { return type_name(); }
virtual const char *type_name() const { return "Object"; }
const std::string &GetInstanceName() const;
void SetInstanceName(const std::string &name);
/** @brief Temporarily blocks all signal emissions from this object. Returns
* previous state. */
bool blockSignals(bool block);
/** @brief Checks if signals are currently blocked. */
bool signalsBlocked() const;
////////////////////////////////////////////////////////////////////////////
// PROPERTIES //
virtual void RegisterProperty(PropertyBase *property);
virtual void RegisterDynamicProperty(PropertyBase *property);
virtual void RegisterDisplayProperty(PropertyBase *property);
virtual const std::vector<PropertyBase *> &GetProperties() const;
virtual const std::vector<PropertyBase *> &GetDisplayProperties() const;
PropertyBase *GetProperty(const std::string &name) const;
/** @brief Sends an Updated signal for all properties of this object. useful
* for real-time UI refresh. */
void NotifyPropertiesUpdated();
////////////////////////////////////////////////////////////////////////////
// PARAMETERS //
// FIXX !!!
virtual void DeepCopy(const Object &copy);
/** @brief Returns a nested context for children objects, if any. */
virtual ObjectsContext *GetChildren() { return nullptr; }
////////////////////////////////////////////////////////////////////////////
// SERIALIZATION //
template <class ArchiveT>
void serialize(ArchiveT &ar, const unsigned int version);
virtual void serialize(Archive::xml_oarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::xml_iarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::text_oarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::text_iarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::hrt_oarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::hrt_iarchive &ar,
const unsigned int version) {}
virtual void serialize(Archive::log_archive &ar, const unsigned int version) {
}
template <class ArchiveT>
void save_override(ArchiveT &ar, const unsigned int version) {}
void SaveConfig(std::ostream &os, int version = 0);
void LoadConfig(std::istream &is, int version = 0);
static void SaveXml(std::ostream &os, Object &ob);
static void LoadXml(std::istream &is, Object &ob);
////////////////////////////////////////////////////////////////////////////
// SIGNALS //
signals:
virtual void Updated();
// Qt4 style connector //
static bool connect(const Object *ob1, const char *signal_name,
const Object *receiver, const char *slot_name) {
// // NOT WORKING YET //
// 1) find slot pointer from name
// SignalBase *sig = ob1->findSignal(signal_name);
// GenericMFPtr *slo = receiver->findSlot(slot_name);
// if(sig && slo)
// return Object::connect(sig,slo->operator ()(),receiver);
// else return false;
return false;
}
// Qt5 style connector //
template <typename Func1, typename Func2>
static Connection
connect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf,
typename FunctionPointer<Func2>::Object *receiver, Func2 slof) {
SignalBase *sigb = sender->findOrAddSignal(sigf);
return ConnectSignal<typename FunctionPointer<Func1>::SignalSignature>(
sigb, slof, receiver);
}
// Lambda/Function object connector //
template <typename Func1, typename SlotT>
static Connection connect(typename FunctionPointer<Func1>::Object *sender,
Func1 sigf, SlotT slof) {
SignalBase *sigb = sender->findOrAddSignal(sigf);
typedef typename FunctionPointer<Func1>::SignalSignature SigSignature;
typedef typename Signal<SigSignature>::type SigT;
return reinterpret_cast<SigT *>(sigb)->connect(slof);
}
template <typename Func1, typename Func2>
static bool
disconnect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf,
typename FunctionPointer<Func2>::Object *receiver, Func2 slof) {
// TODO: implement actual disconnect in Signal.h //
return true;
}
template <typename FuncT>
static inline Connection connect(SignalBase *sigb, FuncT slof,
Object *receiver) {
return ConnectSignal<typename FunctionPointer<FuncT>::SignalSignature>(
sigb, slof, receiver);
}
template <typename FuncT>
inline
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type *
addSignal(FuncT fun, const char *name) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
SignalBase *sig = NewSignal(fun);
addSignalImpl(sig, fun, name);
return (SigT *)sig;
}
template <typename FuncT> inline bool addSlot(FuncT fun, const char *name) {
return this->addSlotImpl(GenericMFPtr(fun), name);
}
template <typename FuncT>
inline
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type *
findSignal(FuncT fptr) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
return (SigT *)findSignalImpl(GenericMFPtr(fptr));
}
template <typename FuncT>
inline
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type *
findOrAddSignal(FuncT fptr) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
SignalBase *sig = findSignalImpl(GenericMFPtr(fptr));
if (!sig) {
sig = NewSignal(fptr);
addSignalImpl(sig, fptr, "signal_name_to_be_implemented");
}
return (SigT *)sig;
}
inline SignalBase *findSignal(const char *name) const {
return findSignalImpl(name);
}
inline GenericMFPtr *findSlot(const char *name) const {
return findSlotImpl(name);
}
void PrintSelf(std::ostream &o) const;
Object &operator=(const Object &other);
private:
bool addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name);
bool addSlotImpl(GenericMFPtr fptr, const char *name);
SignalBase *findSignalImpl(const GenericMFPtr &fptr) const;
SignalBase *findSignalImpl(const char *name) const;
GenericMFPtr *findSlotImpl(const char *name) const;
friend class boost::serialization::access;
friend class ObjectPrivate;
class ObjectPrivate *d;
};
} // namespace uLib
////////////////////////////////////////////////////////////////////////////////
// std::ostream & operator << (std::ostream &os, uLib::Object &ob);
// std::ostream & operator << (std::ostream &os, uLib::Object *ob);
// std::istream & operator >> (std::istream &is, uLib::Object &ob);
#endif // U_OBJECT_H