MotionLib  1.0.0
SamBuCa motion library
PlatformFactory.cpp
1 /*
2  * Copyright (C) 2021 CERN
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty. In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  * claim that you wrote the original software. If you use this software
14  * in a product, an acknowledgment in the product documentation would be
15  * appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  * misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  *
20  * Created on: 2021-10-29
21  * Author: Michal Mysior <mmysior> <michal.mysior@cern.ch>
22  *
23  */
24 
25 #include "PlatformFactory.hpp"
26 
27 #include <map>
28 
29 #include <ccut/Exception.hpp>
30 #include <logger/Logger.hpp>
31 
32 #include "Exception.hpp"
33 #include "MotionLibConfig.hpp"
34 #include "platform/PlatformBase.hpp"
35 #include "specialized/GrblPlatform/GrblPlatform.hpp"
36 #include "specialized/MGrblPlatform/MGrblPlatform.hpp"
37 #include "specialized/MockPlatform/MockPlatform.hpp"
38 
39 #ifdef PLATFORM_SAMBUCA
40 #include "specialized/MFEPlatform/MFEPlatform.hpp"
41 #endif
42 
43 using namespace logger;
44 namespace yml = ccut::yml;
45 
46 namespace smc {
47 namespace internal {
48 
49 static const std::string s_loggerCat{"smc:platform"};
50 static std::map<std::string,
51  std::function<PlatformBase::Shared(yml::NodeRef node)>>
52  s_registry{{"MockPlatform", MockPlatform::create},
53  {"GrblPlatform", GrblPlatform::create},
54  {"MGrblPlatform", MGrblPlatform::create},
55 #ifdef PLATFORM_SAMBUCA
56  {"MFEPlatform", MFEPlatform::create}
57 #endif
58  };
59 
60 PlatformFactory::~PlatformFactory()
61 {
62  for (PlatformBase::Shared p : m_platforms)
63  p->stop();
64 }
65 
66 std::size_t PlatformFactory::buildPlatforms(const std::string &platformDesc)
67 {
68  try
69  {
70  yml::Parser parser;
71  yml::Tree tree = parser.parse_in_arena("<yml>",
72  yml::to_csubstr(platformDesc));
73  yml::NodeRef platformsNode = yml::get(tree.rootref(), "platforms");
74  return buildPlatforms(platformsNode, &parser);
75  }
76  catch (std::exception &ex)
77  {
78  error(s_loggerCat) << "failed to parse platform: " << ex.what();
79  }
80  return 0;
81 }
82 
83 std::size_t PlatformFactory::buildPlatforms(const yml::NodeRef &platformsNode,
84  const yml::Parser *parser)
85 {
86  std::size_t newPlatformCount = 0;
87  try
88  {
89  if (!platformsNode.valid() || !platformsNode.is_seq())
90  throw Exception(ErrorCode::InvalidArguments,
91  "platforms description must be an array");
92 
93  for (yml::NodeRef node : platformsNode)
94  {
95  std::string type;
96  yml::get(node, "type") >> yml::default_to(type, std::string());
97  if (type.empty())
98  {
99  if (parser)
100  throw yml::make_error(*parser, node, "type not found");
101  else
102  throw ccut::Exception(ccut::ErrorCode::InvalidArguments,
103  "type not found");
104  }
105 
106  decltype(s_registry)::const_iterator it = s_registry.find(type);
107  if (it == s_registry.end())
108  error(s_loggerCat) << "unknown platform: " << type;
109  else
110  {
111  try
112  {
113  PlatformBase::Shared platform{(it->second)(node)};
114  {
115  const std::lock_guard<std::mutex> lock{m_platformsMutex};
116  m_platforms.emplace_back(platform);
117  }
118  newPlatformCount++;
119  }
120  catch (std::exception &ex)
121  {
122  error(s_loggerCat)
123  << "failed to create platform: " << ex.what();
124  }
125  }
126  }
127  }
128  catch (std::exception &ex)
129  {
130  error(s_loggerCat) << "failed to parse platform: " << ex.what();
131  }
132  info(s_loggerCat) << newPlatformCount << " platforms created";
133  return newPlatformCount;
134 }
135 
136 std::list<PlatformBase::Shared> PlatformFactory::getPlatforms()
137 {
138  const std::lock_guard<std::mutex> lock{m_platformsMutex};
139  std::list<PlatformBase::Shared> newList{m_platforms};
140  return newList;
141 }
142 
143 } /* namespace internal */
144 } /* namespace smc */
Exception thrown by MotionController in case of issues with command.
Definition: Exception.hpp:61
main motion-lib namespace
Definition: Client.cpp:30