-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Noah Oblath
committed
Dec 29, 2023
1 parent
06a1156
commit 27ed29c
Showing
10 changed files
with
617 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Service.cc | ||
* | ||
* Created on: Dec 28, 2023 | ||
* Author: N.S. Oblath | ||
*/ | ||
|
||
#include "Service.hh" | ||
|
||
namespace Nymph | ||
{ | ||
//KTLOGGER(servicelog, "Service"); | ||
|
||
Service::Service( const std::string& name ) : | ||
fName( name ) | ||
{ | ||
} | ||
|
||
Service::~Service() | ||
{} | ||
|
||
} /* namespace Nymph */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
@file Service.hh | ||
@brief Base class for processors | ||
@author: N. S. Oblath | ||
@date: Dec 28, 2023 | ||
*/ | ||
|
||
#ifndef NYMPH_SERVICE_HH_ | ||
#define NYMPH_SERVICE_HH_ | ||
|
||
#include "Exception.hh" | ||
#include "MemberVariable.hh" | ||
|
||
#include "factory.hh" | ||
#include "param.hh" | ||
|
||
#include <map> | ||
|
||
namespace Nymph | ||
{ | ||
struct ServiceException : virtual public Exception {}; | ||
|
||
class Service | ||
{ | ||
public: | ||
Service( const std::string& name ); | ||
virtual ~Service(); | ||
|
||
template< class XDerivedProc > | ||
static scarab::registrar< Nymph::Service, XDerivedProc, const std::string& >* RegisterService( const std::string& name ); | ||
|
||
public: | ||
/// Configure the processor with a param_node | ||
virtual void Configure( const scarab::param_node& node ) = 0; | ||
|
||
MEMVAR_REF( std::string, Name ); | ||
}; | ||
|
||
|
||
template< class XDerivedProc > | ||
scarab::registrar< Service, XDerivedProc, const std::string& >* Service::RegisterService( const std::string& name ) | ||
{ | ||
return new scarab::registrar< Service, XDerivedProc, const std::string& >( name ); | ||
} | ||
|
||
#define REGISTER_SERVICE_NONAMESPACE(proc_class, proc_name) \ | ||
static ::scarab::registrar< ::Nymph::Service, proc_class, const std::string& > sProc##proc_class##Registrar( proc_name ); | ||
|
||
#define REGISTER_SERVICE_NAMESPACE(proc_namespace, proc_class, proc_name) \ | ||
static ::scarab::registrar< ::Nymph::Service, ::proc_namespace::proc_class, const std::string& > sProc##proc_class##Registrar( proc_name ); | ||
|
||
// Macro overloading trick from here: https://stackoverflow.com/a/11763277 | ||
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME | ||
/// Services defined in a namespace need to specify the namespace first: | ||
/// [no namespace]: REGISTER_PROCESSOR( [class], [name in quotes] ) | ||
/// [with namespace]: REGISTER_PROCESSOR( [namespace], [class], [name in quotes] ) | ||
#define REGISTER_SERVICE(...) GET_MACRO(__VA_ARGS__, REGISTER_SERVICE_NAMESPACE, REGISTER_SERVICE_NONAMESPACE, )(__VA_ARGS__) | ||
|
||
} /* namespace Nymph */ | ||
|
||
#endif /* NYMPH_SERVICE_HH_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* ServiceToolbox.cc | ||
* | ||
* Created on: Dec 28, 2023 | ||
* Author: N.S. Oblath | ||
*/ | ||
|
||
#include "ServiceToolbox.hh" | ||
|
||
#include "ConfigException.hh" | ||
#include "Service.hh" | ||
|
||
#include "factory.hh" | ||
#include "logger.hh" | ||
#include "param_codec.hh" | ||
|
||
#include <map> | ||
|
||
using std::string; | ||
|
||
namespace Nymph | ||
{ | ||
LOGGER(servicelog, "ServiceToolbox"); | ||
|
||
ServiceToolbox::ServiceToolbox( const std::string& name ) : | ||
fServiceFactory( scarab::factory< Service, const std::string& >::get_instance() ), | ||
fServiceMap() | ||
{ | ||
} | ||
|
||
ServiceToolbox::~ServiceToolbox() | ||
{} | ||
|
||
void ServiceToolbox::Configure( const scarab::param_node& node ) | ||
{ | ||
LPROG( servicelog, "Configuring service toolbox" ); | ||
|
||
// Deal with "service" blocks | ||
if( ! node.has("services") ) | ||
{ | ||
LWARN( servicelog, "No services were specified" ); | ||
} | ||
else | ||
{ | ||
ConfigureServices( node["services"].as_array() ); | ||
} | ||
|
||
return; | ||
} | ||
|
||
|
||
void ServiceToolbox::ConfigureServices( const scarab::param_array& array ) | ||
{ | ||
for( auto serviceIt = array.begin(); serviceIt != array.end(); ++serviceIt ) | ||
{ | ||
if( ! serviceIt->is_node() ) | ||
{ | ||
THROW_EXCEPT_HERE( ConfigException(array) << "Invalid service entry (not a node): " << *serviceIt ); | ||
} | ||
const scarab::param_node& serviceNode = serviceIt->as_node(); | ||
|
||
if( ! serviceNode.has("type") ) | ||
{ | ||
THROW_EXCEPT_HERE( ConfigException(array) << "Unable to create service: no service type given" ); | ||
} | ||
string serviceType = serviceNode["type"]().as_string(); | ||
|
||
string serviceName; | ||
if( ! serviceNode.has("name") ) | ||
{ | ||
LINFO(servicelog, "No name given for service of type <" << serviceType << ">; using type as name."); | ||
serviceName = serviceType; | ||
} | ||
else | ||
{ | ||
serviceName = serviceNode["name"]().as_string(); | ||
} | ||
|
||
std::shared_ptr< Service > newProc ( fServiceFactory->create(serviceType, serviceName) ); | ||
if( newProc == nullptr ) | ||
{ | ||
THROW_EXCEPT_HERE( ConfigException(array) << "Unable to create service of type <" << serviceType << ">" ); | ||
} | ||
|
||
LDEBUG( servicelog, "Attempting to configure service <" << serviceName << ">" ); | ||
try | ||
{ | ||
newProc->Configure(serviceNode); | ||
} | ||
catch( scarab::base_exception& e ) | ||
{ | ||
THROW_NESTED_EXCEPT_HERE( Exception() << "An error occurred while configuring service <" << serviceName << ">" ); | ||
} | ||
|
||
if( ! AddService( serviceName, newProc ) ) | ||
{ | ||
THROW_EXCEPT_HERE( ConfigException(array) << "Unable to add service <" << serviceName << ">" ); | ||
} | ||
} | ||
|
||
return; | ||
} | ||
|
||
std::shared_ptr< Service > ServiceToolbox::GetService( const std::string& serviceName ) | ||
{ | ||
if( auto it = fServiceMap.find( serviceName ); it != fServiceMap.end() ) | ||
{ | ||
return it->second.fService; | ||
} | ||
LWARN( servicelog, "Service <" << serviceName << "> was not found." ); | ||
return nullptr; | ||
} | ||
|
||
const std::shared_ptr< Service > ServiceToolbox::GetService( const std::string& serviceName ) const | ||
{ | ||
if( auto it = fServiceMap.find( serviceName ); it != fServiceMap.end() ) | ||
{ | ||
return it->second.fService; | ||
} | ||
LWARN( servicelog, "Service <" << serviceName << "> was not found." ); | ||
return nullptr; | ||
} | ||
|
||
bool ServiceToolbox::AddService( const std::string& serviceName, std::shared_ptr< Service > service ) | ||
{ | ||
if( auto it = fServiceMap.find( serviceName); it == fServiceMap.end() ) | ||
{ | ||
ServiceInfo pInfo; | ||
pInfo.fService = service; | ||
fServiceMap.insert( ServiceMap::value_type(serviceName, pInfo) ); | ||
LDEBUG( servicelog, "Added service <" << serviceName << "> (a.k.a. " << service->Name() << ")" ); | ||
return true; | ||
} | ||
LWARN( servicelog, "Service <" << serviceName << "> already exists; new service was not added." ); | ||
return false; | ||
} | ||
|
||
bool ServiceToolbox::AddService( const std::string& serviceType, const std::string& serviceName ) | ||
{ | ||
if( auto it = fServiceMap.find( serviceName ); it == fServiceMap.end() ) | ||
{ | ||
std::shared_ptr< Service > newProc ( fServiceFactory->create(serviceType, serviceType) ); | ||
if( newProc == nullptr ) | ||
{ | ||
LERROR( servicelog, "Unable to create service of type <" << serviceType << ">" ); | ||
return false; | ||
} | ||
if( ! AddService(serviceName, newProc) ) | ||
{ | ||
LERROR( servicelog, "Unable to add service <" << serviceName << ">" ); | ||
return false; | ||
} | ||
return true; | ||
} | ||
LWARN( servicelog, "Service <" << serviceName << "> already exists; new service was not added." ); | ||
return false; | ||
} | ||
|
||
bool ServiceToolbox::RemoveService( const std::string& serviceName ) | ||
{ | ||
if( auto serviceToRemove = ReleaseService( serviceName ); serviceToRemove != nullptr ) | ||
{ | ||
LDEBUG( servicelog, "Service <" << serviceName << "> deleted." ); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
std::shared_ptr< Service > ServiceToolbox::ReleaseService( const std::string& serviceName ) | ||
{ | ||
if( auto it = fServiceMap.find( serviceName ); it != fServiceMap.end() ) | ||
{ | ||
std::shared_ptr< Service > serviceToRelease = it->second.fService; | ||
fServiceMap.erase( it ); | ||
return serviceToRelease; | ||
} | ||
LWARN( servicelog, "Service <" << serviceName << "> was not found." ); | ||
return nullptr; | ||
} | ||
|
||
void ServiceToolbox::ClearServices() | ||
{ | ||
fServiceMap.clear(); | ||
return; | ||
} | ||
|
||
} /* namespace Nymph */ |
Oops, something went wrong.