123 lines
3.0 KiB
C++
123 lines
3.0 KiB
C++
/**
|
|
*
|
|
* DrClassMap.cc
|
|
* An Tao
|
|
*
|
|
* Copyright 2018, An Tao. All rights reserved.
|
|
* https://github.com/an-tao/drogon
|
|
* Use of this source code is governed by a MIT license
|
|
* that can be found in the License file.
|
|
*
|
|
* Drogon
|
|
*
|
|
*/
|
|
|
|
#include <drogon/DrClassMap.h>
|
|
#include <drogon/DrObject.h>
|
|
#include <trantor/utils/Logger.h>
|
|
|
|
using namespace drogon;
|
|
|
|
namespace drogon
|
|
{
|
|
namespace internal
|
|
{
|
|
static std::unordered_map<std::string, std::shared_ptr<DrObjectBase>> &
|
|
getObjsMap()
|
|
{
|
|
static std::unordered_map<std::string, std::shared_ptr<DrObjectBase>>
|
|
singleInstanceMap;
|
|
return singleInstanceMap;
|
|
}
|
|
|
|
static std::mutex &getMapMutex()
|
|
{
|
|
static std::mutex mtx;
|
|
return mtx;
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace drogon
|
|
|
|
void DrClassMap::registerClass(const std::string &className,
|
|
const DrAllocFunc &func,
|
|
const DrSharedAllocFunc &sharedFunc)
|
|
{
|
|
LOG_TRACE << "Register class:" << className;
|
|
getMap().insert(
|
|
std::make_pair(className, std::make_pair(func, sharedFunc)));
|
|
}
|
|
|
|
DrObjectBase *DrClassMap::newObject(const std::string &className)
|
|
{
|
|
auto iter = getMap().find(className);
|
|
if (iter != getMap().end())
|
|
{
|
|
return iter->second.first();
|
|
}
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<DrObjectBase> DrClassMap::newSharedObject(
|
|
const std::string &className)
|
|
{
|
|
auto iter = getMap().find(className);
|
|
if (iter != getMap().end())
|
|
{
|
|
if (iter->second.second)
|
|
return iter->second.second();
|
|
else
|
|
return std::shared_ptr<DrObjectBase>(iter->second.first());
|
|
}
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
const std::shared_ptr<DrObjectBase> &DrClassMap::getSingleInstance(
|
|
const std::string &className)
|
|
{
|
|
auto &mtx = internal::getMapMutex();
|
|
auto &singleInstanceMap = internal::getObjsMap();
|
|
{
|
|
std::lock_guard<std::mutex> lock(mtx);
|
|
auto iter = singleInstanceMap.find(className);
|
|
if (iter != singleInstanceMap.end())
|
|
return iter->second;
|
|
}
|
|
auto newObj = newSharedObject(className);
|
|
{
|
|
std::lock_guard<std::mutex> lock(mtx);
|
|
auto ret = singleInstanceMap.insert(
|
|
std::make_pair(className, std::move(newObj)));
|
|
return ret.first->second;
|
|
}
|
|
}
|
|
|
|
void DrClassMap::setSingleInstance(const std::shared_ptr<DrObjectBase> &ins)
|
|
{
|
|
auto &mtx = internal::getMapMutex();
|
|
auto &singleInstanceMap = internal::getObjsMap();
|
|
std::lock_guard<std::mutex> lock(mtx);
|
|
singleInstanceMap[ins->className()] = ins;
|
|
}
|
|
|
|
std::vector<std::string> DrClassMap::getAllClassName()
|
|
{
|
|
std::vector<std::string> ret;
|
|
for (auto const &iter : getMap())
|
|
{
|
|
ret.push_back(iter.first);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
std::unordered_map<std::string, std::pair<DrAllocFunc, DrSharedAllocFunc>> &
|
|
DrClassMap::getMap()
|
|
{
|
|
static std::unordered_map<std::string,
|
|
std::pair<DrAllocFunc, DrSharedAllocFunc>>
|
|
map;
|
|
return map;
|
|
}
|