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