|
|
@ -0,0 +1,204 @@ |
|
|
|
//
|
|
|
|
// Created by zwsd
|
|
|
|
//
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
|
|
|
#include <set>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <typeindex>
|
|
|
|
#include <typeinfo>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief |
|
|
|
* |
|
|
|
* service: ServiceContrainer |
|
|
|
* |
|
|
|
* 监听事件: |
|
|
|
* 依赖状态: |
|
|
|
* 依赖服务: |
|
|
|
* 作用: |
|
|
|
* |
|
|
|
*/ |
|
|
|
// std::shared_ptr<Buffer> buf(new Buffer());
|
|
|
|
// ZserviceContainerAny any(buf);
|
|
|
|
// std::shared_ptr<Buffer> b = any.Get<std::shared_ptr<Buffer>>();
|
|
|
|
// assert(buf.get() == b.get());
|
|
|
|
namespace iflytop { |
|
|
|
using namespace std; |
|
|
|
|
|
|
|
class ZserviceContainerAny { |
|
|
|
public: |
|
|
|
ZserviceContainerAny() : content_(nullptr) {} |
|
|
|
~ZserviceContainerAny() { delete content_; } |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
explicit ZserviceContainerAny(const ValueType& value) : content_(new Holder<ValueType>(value)) {} |
|
|
|
|
|
|
|
ZserviceContainerAny(const ZserviceContainerAny& other) |
|
|
|
: content_(other.content_ ? other.content_->clone() : nullptr) {} |
|
|
|
|
|
|
|
public: |
|
|
|
ZserviceContainerAny& swap(ZserviceContainerAny& rhs) { |
|
|
|
std::swap(content_, rhs.content_); |
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
ZserviceContainerAny& operator=(const ValueType& rhs) { |
|
|
|
ZserviceContainerAny(rhs).swap(*this); |
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
ZserviceContainerAny& operator=(const ZserviceContainerAny& rhs) { |
|
|
|
ZserviceContainerAny(rhs).swap(*this); |
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
bool IsEmpty() const { return !content_; } |
|
|
|
|
|
|
|
const std::type_info& GetType() const { return content_ ? content_->GetType() : typeid(void); } |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
ValueType operator()() const { |
|
|
|
return Get<ValueType>(); |
|
|
|
} |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
ValueType Get() const { |
|
|
|
if (GetType() == typeid(ValueType)) { |
|
|
|
return static_cast<ZserviceContainerAny::Holder<ValueType>*>(content_)->held_; |
|
|
|
} else { |
|
|
|
return ValueType(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected: |
|
|
|
class ZPlaceHolder { |
|
|
|
public: |
|
|
|
virtual ~ZPlaceHolder() {} |
|
|
|
|
|
|
|
public: |
|
|
|
virtual const std::type_info& GetType() const = 0; |
|
|
|
virtual ZPlaceHolder* clone() const = 0; |
|
|
|
}; |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
class Holder : public ZPlaceHolder { |
|
|
|
public: |
|
|
|
Holder(const ValueType& value) : held_(value) {} |
|
|
|
|
|
|
|
virtual const std::type_info& GetType() const { return typeid(ValueType); } |
|
|
|
|
|
|
|
virtual ZPlaceHolder* clone() const { return new Holder(held_); } |
|
|
|
|
|
|
|
ValueType held_; |
|
|
|
}; |
|
|
|
|
|
|
|
protected: |
|
|
|
ZPlaceHolder* content_; |
|
|
|
template <typename ValueType> |
|
|
|
friend ValueType* zany_cast(ZserviceContainerAny*); |
|
|
|
}; |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
ValueType* zany_cast(ZserviceContainerAny* any) { |
|
|
|
if (any && any->GetType() == typeid(ValueType)) { |
|
|
|
return &(static_cast<ZserviceContainerAny::Holder<ValueType>*>(any->content_)->held_); |
|
|
|
} |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
const ValueType* zany_cast(const ZserviceContainerAny* any) { |
|
|
|
return zany_cast<ValueType>(const_cast<ZserviceContainerAny*>(any)); |
|
|
|
} |
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
|
ValueType zany_cast(const ZserviceContainerAny& any) { |
|
|
|
const ValueType* result = zany_cast<ValueType>(&any); |
|
|
|
assert(result); |
|
|
|
|
|
|
|
if (!result) { |
|
|
|
return ValueType(); |
|
|
|
} |
|
|
|
|
|
|
|
return *result; |
|
|
|
} |
|
|
|
|
|
|
|
class ServiceContrainer { |
|
|
|
map<type_index, ZserviceContainerAny> services; |
|
|
|
ServiceContrainer(){}; |
|
|
|
|
|
|
|
public: |
|
|
|
static ServiceContrainer& get(); |
|
|
|
|
|
|
|
template <typename T> |
|
|
|
void regAndInitializeService(shared_ptr<T> object) { |
|
|
|
if (object == nullptr) { |
|
|
|
return; |
|
|
|
} |
|
|
|
object->initialize(); |
|
|
|
type_index index = typeid(T); |
|
|
|
services[index] = ZserviceContainerAny(object); |
|
|
|
}; |
|
|
|
template <typename T> |
|
|
|
void regService(shared_ptr<T> object) { |
|
|
|
if (object == nullptr) { |
|
|
|
return; |
|
|
|
} |
|
|
|
type_index index = typeid(T); |
|
|
|
services[index] = ZserviceContainerAny(object); |
|
|
|
}; |
|
|
|
template <typename T> |
|
|
|
shared_ptr<T> getService() { |
|
|
|
type_index index = typeid(T); |
|
|
|
auto result = services.find(index); |
|
|
|
if (result == services.end()) { |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
return result->second.Get<std::shared_ptr<T>>(); |
|
|
|
}; |
|
|
|
|
|
|
|
template <typename T> |
|
|
|
void getToService(shared_ptr<T>& service) { |
|
|
|
type_index index = typeid(T); |
|
|
|
auto result = services.find(index); |
|
|
|
if (result == services.end()) { |
|
|
|
service = nullptr; |
|
|
|
} |
|
|
|
service = result->second.Get<std::shared_ptr<T>>(); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
#define GET_SERVICE(type) (ServiceContrainer::get().getService<type>())
|
|
|
|
#define GET_TO_SERVICE(value) \
|
|
|
|
ServiceContrainer::get().getToService(value); \ |
|
|
|
if (value == nullptr) { \ |
|
|
|
logger->error("[{}:{}]GET_TO_SERVICE({}) fail", __FILE__, __LINE__, #value); \ |
|
|
|
exit(-1); \ |
|
|
|
}; |
|
|
|
|
|
|
|
#define BUILD_AND_REG_SERRVICE(type, ...) \
|
|
|
|
logger->info("build {}.....", #type); \ |
|
|
|
shared_ptr<type> type##_val(new type(__VA_ARGS__)); \ |
|
|
|
ServiceContrainer::get().regService(type##_val); |
|
|
|
|
|
|
|
#define REG_SERRVICE(type,object) \
|
|
|
|
shared_ptr<type> type##_val(object); \ |
|
|
|
ServiceContrainer::get().regService(type##_val); |
|
|
|
|
|
|
|
#define BUILD_AND_REG_MOCK_SERRVICE(type, mocktype, ...) \
|
|
|
|
logger->info("build {}.....", #type); \ |
|
|
|
shared_ptr<type> type##_val(new mocktype(__VA_ARGS__)); \ |
|
|
|
ServiceContrainer::get().regService(type##_val); |
|
|
|
|
|
|
|
} // namespace iflytop
|