Skip to content

Commit 8f3b08a

Browse files
knopers8Barthelemy
authored andcommitted
Common class factory using ROOT reflection (#255)
1 parent 9bb4e84 commit 8f3b08a

5 files changed

Lines changed: 87 additions & 83 deletions

File tree

Framework/include/QualityControl/PostProcessingFactory.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
#ifndef QUALITYCONTROL_POSTPROCESSINGFACTORY_H
1717
#define QUALITYCONTROL_POSTPROCESSINGFACTORY_H
1818

19-
// O2
20-
#include <Common/Exceptions.h>
21-
2219
#include "QualityControl/PostProcessingConfig.h"
2320

2421
namespace o2::quality_control::postprocessing
@@ -36,9 +33,6 @@ class PostProcessingFactory
3633
PostProcessingFactory() = default;
3734
virtual ~PostProcessingFactory() = default;
3835

39-
using FatalException = AliceO2::Common::FatalException;
40-
using errinfo_details = AliceO2::Common::errinfo_details;
41-
4236
/// \brief Create a new instance of a PostProcessingInterface.
4337
/// The PostProcessingInterface actual class is decided based on the parameters passed.
4438
PostProcessingInterface* create(const PostProcessingConfig& config);

Framework/include/QualityControl/TaskFactory.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
// STL
2020
#include <memory>
21-
// O2
22-
#include <Common/Exceptions.h>
2321
// QC
2422
#include "QualityControl/TaskConfig.h"
2523

@@ -39,9 +37,6 @@ class TaskFactory
3937
TaskFactory() = default;
4038
virtual ~TaskFactory() = default;
4139

42-
using FatalException = AliceO2::Common::FatalException;
43-
using errinfo_details = AliceO2::Common::errinfo_details;
44-
4540
/// \brief Create a new instance of a TaskInterface.
4641
/// The TaskInterface actual class is decided based on the parameters passed.
4742
/// \todo make it static ?

Framework/src/PostProcessingFactory.cxx

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@
1414
///
1515

1616
#include "QualityControl/PostProcessingFactory.h"
17-
18-
#include "QualityControl/QcInfoLogger.h"
19-
// ROOT
20-
#include <TClass.h>
21-
#include <TROOT.h>
22-
#include <TSystem.h>
17+
#include "RootClassFactory.h"
2318

2419
using namespace o2::quality_control::core;
2520

@@ -29,35 +24,7 @@ namespace o2::quality_control::postprocessing
2924
// todo: consider having a common helper for each class which loads tasks like below (QC tasks, checks, pp)
3025
PostProcessingInterface* PostProcessingFactory::create(const PostProcessingConfig& config)
3126
{
32-
PostProcessingInterface* result = nullptr;
33-
QcInfoLogger& logger = QcInfoLogger::GetInstance();
34-
35-
// Load the library
36-
std::string library = "lib" + config.moduleName;
37-
logger << "Loading library " << library << AliceO2::InfoLogger::InfoLogger::endm;
38-
int libLoaded = gSystem->Load(library.c_str(), "", true);
39-
if (libLoaded < 0) {
40-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details("Failed to load Detector Publisher Library"));
41-
}
42-
43-
// Get the class and instantiate
44-
logger << "Loading class " << config.className << AliceO2::InfoLogger::InfoLogger::endm;
45-
TClass* cl = TClass::GetClass(config.className.c_str());
46-
std::string tempString("Failed to instantiate Quality Control Module");
47-
if (!cl) {
48-
tempString += " because no dictionary for class named \"";
49-
tempString += config.className;
50-
tempString += "\" could be retrieved";
51-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
52-
}
53-
logger << "Instantiating class " << config.className << " (" << cl << ")"
54-
<< AliceO2::InfoLogger::InfoLogger::endm;
55-
result = static_cast<PostProcessingInterface*>(cl->New());
56-
if (!result) {
57-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
58-
}
59-
60-
logger << "QualityControl Module " << config.moduleName << " loaded " << AliceO2::InfoLogger::InfoLogger::endm;
61-
return result;
27+
return root_class_factory::create<PostProcessingInterface>(config.moduleName, config.className);
6228
}
29+
6330
} // namespace o2::quality_control::postprocessing

Framework/src/RootClassFactory.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
//
11+
12+
///
13+
/// \author Piotr Konopka
14+
/// \file RootClassFactory.h
15+
///
16+
#ifndef QUALITYCONTROL_ROOTCLASSFACTORY_H
17+
#define QUALITYCONTROL_ROOTCLASSFACTORY_H
18+
19+
#include <string>
20+
// O2
21+
#include <Common/Exceptions.h>
22+
// ROOT
23+
#include <TClass.h>
24+
#include <TROOT.h>
25+
#include <TSystem.h>
26+
// Boost
27+
#include <boost/filesystem/path.hpp>
28+
// QC
29+
#include "QualityControl/QcInfoLogger.h"
30+
31+
namespace bfs = boost::filesystem;
32+
33+
namespace o2::quality_control::core
34+
{
35+
36+
namespace root_class_factory
37+
{
38+
39+
using FatalException = AliceO2::Common::FatalException;
40+
using errinfo_details = AliceO2::Common::errinfo_details;
41+
42+
template <typename T>
43+
T* create(std::string moduleName, std::string className)
44+
{
45+
T* result = nullptr;
46+
QcInfoLogger& logger = QcInfoLogger::GetInstance();
47+
48+
// Load the library
49+
std::string library = bfs::path(moduleName).is_absolute() ? moduleName : "lib" + moduleName;
50+
logger << "Loading library " << library << AliceO2::InfoLogger::InfoLogger::endm;
51+
int libLoaded = gSystem->Load(library.c_str(), "", true);
52+
if (libLoaded < 0) {
53+
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details("Failed to load Detector Publisher Library"));
54+
}
55+
56+
// Get the class and instantiate
57+
logger << "Loading class " << className << AliceO2::InfoLogger::InfoLogger::endm;
58+
TClass* cl = TClass::GetClass(className.c_str());
59+
std::string tempString("Failed to instantiate Quality Control Module");
60+
if (!cl) {
61+
tempString += " because no dictionary for class named \"";
62+
tempString += className;
63+
tempString += "\" could be retrieved";
64+
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
65+
}
66+
logger << "Instantiating class " << className << " (" << cl << ")"
67+
<< AliceO2::InfoLogger::InfoLogger::endm;
68+
result = static_cast<T*>(cl->New());
69+
if (!result) {
70+
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
71+
}
72+
logger << "QualityControl Module " << moduleName << " loaded " << AliceO2::InfoLogger::InfoLogger::endm;
73+
74+
return result;
75+
}
76+
77+
} // namespace root_class_factory
78+
79+
} // namespace o2::quality_control::core
80+
81+
#endif //QUALITYCONTROL_ROOTCLASSFACTORY_H

Framework/src/TaskFactory.cxx

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,21 @@
1212
/// \file TaskFactory.cxx
1313
/// \author Barthelemy von Haller
1414
///
15+
1516
#include "QualityControl/TaskFactory.h"
1617

1718
#include "QualityControl/QcInfoLogger.h"
18-
// ROOT
19-
#include <TClass.h>
20-
#include <TROOT.h>
21-
#include <TSystem.h>
22-
// Boost
23-
#include <boost/filesystem/path.hpp>
24-
25-
namespace bfs = boost::filesystem;
19+
#include "RootClassFactory.h"
2620

2721
namespace o2::quality_control::core
2822
{
2923

3024
TaskInterface* TaskFactory::create(TaskConfig& taskConfig, std::shared_ptr<ObjectsManager> objectsManager)
3125
{
32-
TaskInterface* result = nullptr;
33-
QcInfoLogger& logger = QcInfoLogger::GetInstance();
34-
35-
// Load the library
36-
std::string library = bfs::path(taskConfig.moduleName).is_absolute() ? taskConfig.moduleName : "lib" + taskConfig.moduleName;
37-
logger << "Loading library " << library << AliceO2::InfoLogger::InfoLogger::endm;
38-
int libLoaded = gSystem->Load(library.c_str(), "", true);
39-
if (libLoaded < 0) {
40-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details("Failed to load Detector Publisher Library"));
41-
}
42-
43-
// Get the class and instantiate
44-
logger << "Loading class " << taskConfig.className << AliceO2::InfoLogger::InfoLogger::endm;
45-
TClass* cl = TClass::GetClass(taskConfig.className.c_str());
46-
std::string tempString("Failed to instantiate Quality Control Module");
47-
if (!cl) {
48-
tempString += " because no dictionary for class named \"";
49-
tempString += taskConfig.className;
50-
tempString += "\" could be retrieved";
51-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
52-
}
53-
logger << "Instantiating class " << taskConfig.className << " (" << cl << ")"
54-
<< AliceO2::InfoLogger::InfoLogger::endm;
55-
result = static_cast<TaskInterface*>(cl->New());
56-
if (!result) {
57-
BOOST_THROW_EXCEPTION(FatalException() << errinfo_details(tempString));
58-
}
26+
TaskInterface* result = root_class_factory::create<TaskInterface>(taskConfig.moduleName, taskConfig.className);
5927
result->setName(taskConfig.taskName);
6028
result->setObjectsManager(objectsManager);
6129
result->setCustomParameters(taskConfig.customParameters);
62-
logger << "QualityControl Module " << taskConfig.moduleName << " loaded " << AliceO2::InfoLogger::InfoLogger::endm;
6330

6431
return result;
6532
}

0 commit comments

Comments
 (0)