Skip to content

Commit

Permalink
Added Service and ServiceToolbox
Browse files Browse the repository at this point in the history
  • Loading branch information
Noah Oblath committed Dec 29, 2023
1 parent 06a1156 commit 27ed29c
Show file tree
Hide file tree
Showing 10 changed files with 617 additions and 4 deletions.
15 changes: 11 additions & 4 deletions Cpp/Library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set( DATA_DIR Data )
set( IMPL_DIR Implementation )
#set( IO_DIR IO )
set( PROC_DIR Processor )
set( SVC_DIR Service )
set( UTIL_DIR Utility )

include_directories( BEFORE
Expand All @@ -14,6 +15,7 @@ include_directories( BEFORE
${CMAKE_CURRENT_SOURCE_DIR}/${IMPL_DIR}
# ${CMAKE_CURRENT_SOURCE_DIR}/${IO_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${PROC_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${SVC_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${UTIL_DIR}
)

Expand All @@ -22,6 +24,9 @@ set( NYMPH_HEADERFILES
${UTIL_DIR}/Exception.hh
${UTIL_DIR}/MemberVariable.hh

${SVC_DIR}/Service.hh
${SVC_DIR}/ServiceToolbox.hh

${PROC_DIR}/PrimaryProcessor.hh
${PROC_DIR}/Processor.hh
${PROC_DIR}/ProcessorToolbox.hh
Expand All @@ -47,15 +52,17 @@ set( NYMPH_SOURCEFILES
${UTIL_DIR}/ConfigException.cc
${UTIL_DIR}/Exception.cc

${DATA_DIR}/Data.cc
${DATA_DIR}/DataFrame.cc
${SVC_DIR}/Service.cc
${SVC_DIR}/ServiceToolbox.cc

${PROC_DIR}/PrimaryProcessor.cc
${PROC_DIR}/Processor.cc
${PROC_DIR}/ProcessorToolbox.cc
${PROC_DIR}/SignalSlotBase.cc


${DATA_DIR}/Data.cc
${DATA_DIR}/DataFrame.cc

${CONT_DIR}/ControlAccess.cc
${CONT_DIR}/Controller.cc
${CONT_DIR}/ReturnBuffer.cc
Expand Down
22 changes: 22 additions & 0 deletions Cpp/Library/Service/Service.cc
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 */
61 changes: 61 additions & 0 deletions Cpp/Library/Service/Service.hh
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_ */
187 changes: 187 additions & 0 deletions Cpp/Library/Service/ServiceToolbox.cc
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 */
Loading

0 comments on commit 27ed29c

Please sign in to comment.