CYCLUS
Loading...
Searching...
No Matches
dynamic_module.cc
Go to the documentation of this file.
1#include "dynamic_module.h"
2
3#include <boost/filesystem.hpp>
4#include <boost/algorithm/string.hpp>
5#include <boost/algorithm/string/predicate.hpp>
6
7#include "context.h"
8#include "env.h"
9#include "agent.h"
10#include "platform.h"
11#include "pyhooks.h"
12
13#include DYNAMICLOADLIB
14
15namespace fs = boost::filesystem;
16
17namespace cyclus {
18
19AgentSpec::AgentSpec(std::string path, std::string lib, std::string agent,
20 std::string alias)
21 : path_(path), lib_(lib), agent_(agent), alias_(alias) {
22 if (lib_ == "") {
23 lib_ = agent_;
24 }
25 if (alias_ == "") {
26 alias = agent_;
27 }
28}
29
31 agent_ = t->GetString("name");
32 lib_ = OptionalQuery<std::string>(t, "lib", agent_);
33 path_ = OptionalQuery<std::string>(t, "path", "");
34 alias_ = OptionalQuery<std::string>(t, "alias", agent_);
35}
36
37AgentSpec::AgentSpec(std::string str_spec) {
38 std::vector<std::string> strs;
39 boost::split(strs, str_spec, boost::is_any_of(":"));
40 if (strs.size() != 3) {
41 throw ValueError("invalid agent spec string '" + str_spec + "'");
42 }
43 path_ = strs[0];
44 lib_ = strs[1];
45 agent_ = strs[2];
46 alias_ = agent_;
47}
48
49std::string AgentSpec::Sanitize() {
50 std::string s = str();
51 boost::replace_all(s, "/", "_");
52 boost::replace_all(s, "-", "_");
53 boost::replace_all(s, ":", "_");
54 boost::replace_all(s, ".", "_");
55 return s;
56}
57
58std::string AgentSpec::LibPath() {
59 return (fs::path(path_) / fs::path("lib" + lib_ + SUFFIX)).string();
60}
61
62std::string AgentSpec::str() {
63 return path_ + ":" + lib_ + ":" + agent_;
64}
65
66std::map<std::string, DynamicModule*> DynamicModule::modules_;
67std::map<std::string, AgentCtor*> DynamicModule::man_ctors_;
68
70 if (man_ctors_.count(spec.str()) > 0) { // for testing
71 Agent* a = man_ctors_[spec.str()](ctx);
72 a->spec(spec.str());
73 return a;
74 } else if (modules_.count(spec.str()) == 0) {
75 DynamicModule* dyn = new DynamicModule(spec);
76 modules_[spec.str()] = dyn;
77 }
78
79 DynamicModule* dyn = modules_[spec.str()];
80 Agent* a;
81 if (boost::starts_with(dyn->path(), "<py>")) {
82 /// go down a separate execution pathway if we are asked to load a
83 /// Python module.
84 a = MakePyAgent(spec.lib(), spec.agent(), ctx);
85 } else {
86 // build a C++ agent.
87 a = dyn->ConstructInstance(ctx);
88 }
89 a->spec(spec.str());
90 return a;
91}
92
94 bool rtn = true;
95 try {
96 DynamicModule dyn(spec);
97 } catch (cyclus::Error& e) {
98 rtn = false;
99 }
100 return rtn;
101}
102
104 std::map<std::string, DynamicModule*>::iterator it;
105 for (it = modules_.begin(); it != modules_.end(); it++) {
106 it->second->CloseLibrary();
107 delete it->second;
108 }
109 modules_.clear();
110 man_ctors_.clear();
112}
113
115 bool rtn = false;
116 if (DynamicModule::Exists(spec) &&
117 boost::starts_with(modules_[spec.str()]->path(), "<py>")) {
118 rtn = true;
119 }
120 return rtn;
121}
122
123DynamicModule::DynamicModule(AgentSpec spec) : module_library_(0), ctor_(NULL) {
124 path_ = Env::FindModule(spec.LibPath(), spec.lib());
125 if (boost::starts_with(path_, "<py>")) {
126 /// python module, so no need to do more
127 return;
128 }
129 ctor_name_ = "Construct" + spec.agent();
130 OpenLibrary();
131 SetConstructor();
132}
133
134Agent* DynamicModule::ConstructInstance(Context* ctx) {
135 return ctor_(ctx);
136}
137
138std::string DynamicModule::path() {
139 return path_;
140}
141
142} // namespace cyclus
std::string alias()
std::string path()
std::string Sanitize()
std::string str()
std::string agent()
std::string LibPath()
std::string lib()
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:50
std::string spec()
The string representation of the agent spec that uniquely identifies the concrete agent class/module.
Definition agent.h:353
A simulation context provides access to necessary simulation-global functions and state.
Definition context.h:146
static void CloseAll()
Closes all statically loaded dynamic modules.
static bool IsPyAgent(AgentSpec spec)
Tests that an agent spec is for a Python Agent.
DynamicModule()
Do-nothing constructor.
static Agent * Make(Context *ctx, AgentSpec spec)
Returns a newly constructed agent for the given module spec.
static bool Exists(AgentSpec spec)
Tests that an agent spec really exists.
std::string path()
The path to the module's shared object library.
static std::string FindModule(std::string path)
Returns the full path to a module by searching through default install and CYCLUS_PATH directories.
Definition env.cc:179
A generic mechanism to manually manage exceptions.
Definition error.h:12
A class for extracting information from a given XML parser.
Definition infile_tree.h:22
virtual std::string GetString(std::string query, int index=0)
investigates the current status and returns a string representing the content of a query at a given i...
For values that are too big, too small, etc.
Definition error.h:37
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
void ClearPyAgentRefs(void)
Removes all Python agents from the internal cache.
Definition pyhooks.cc:105
Agent * MakePyAgent(std::string lib, std::string agent, void *ctx)
Finds a Python module and returns an agent pointer from it.
Definition pyhooks.cc:99
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
#define SUFFIX
Definition platform.h:1