OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ClientInterfaceObjectManager.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
26 #include <osvr/Common/PathTree.h>
33 #include <osvr/Util/Verbosity.h>
35 
36 // Library/third-party includes
37 #include <boost/assert.hpp>
38 
39 // Standard includes
40 #include <unordered_set>
41 
42 namespace osvr {
43 namespace client {
44  ClientInterfaceObjectManager::ClientInterfaceObjectManager(
45  common::PathTreeOwner &tree, RemoteHandlerFactory &handlerFactory,
46  common::ClientContext &ctx)
47  : m_pathTree(tree.get()), m_treeObserver(tree.makeObserver()),
48  m_factory(handlerFactory), m_ctx(&ctx) {
49  m_treeObserver->setEventCallback(
50  common::PathTreeEvents::AboutToUpdate,
51  [&](common::PathTree &) { m_interfaces.clearHandlers(); });
52  m_treeObserver->setEventCallback(
53  common::PathTreeEvents::AfterUpdate,
54  [&](common::PathTree &) { m_connectNeededCallbacks(); });
55  }
56 
58  common::ClientInterfacePtr const &iface, bool verboseFailure) {
59  auto pin = iface;
60  const auto isNew = m_interfaces.addInterface(pin);
61  if (isNew) {
62  m_connectCallbacksOnPath(pin->getPath(), verboseFailure);
63  }
64  }
65  void ClientInterfaceObjectManager::releaseInterface(
66  common::ClientInterfacePtr const &iface) {
67  auto pin = iface;
68  const auto isEmpty = m_interfaces.removeInterface(pin);
69  if (isEmpty) {
70  m_removeCallbacksOnPath(pin->getPath());
71  }
72  }
73 
75  m_interfaces.updateHandlers();
76  }
77 
78  bool ClientInterfaceObjectManager::m_connectCallbacksOnPath(
79  std::string const &path, bool verboseFailure) {
83  m_interfaces.eraseHandlerForPath(path);
84 
85  auto source = common::resolveTreeNode(m_pathTree, path);
86  if (!source.is_initialized()) {
87  if (verboseFailure) {
88  logger()->info() << "Could not resolve source for " << path;
89  }
90  return false;
91  }
92 
93  auto handler = m_factory.invokeFactory(
94  *source, m_interfaces.getInterfacesForPath(path), *m_ctx);
95 
96  if (handler) {
97  logger()->info() << "Successfully produced handler for " << path;
98  // Store the new handler in the interface tree
99  auto oldHandler = m_interfaces.replaceHandlerForPath(path, handler);
100  BOOST_ASSERT_MSG(
101  !oldHandler,
102  "We removed the old handler before so it should be null now");
103  return true;
104  }
105 
106  logger()->info() << "Could not produce handler for " << path;
107  return false;
108  }
109 
112  void ClientInterfaceObjectManager::m_removeCallbacksOnPath(
113  std::string const &path) {
114  m_interfaces.eraseHandlerForPath(path);
115  }
116 
117  void ClientInterfaceObjectManager::m_connectNeededCallbacks() {
118  auto failedPaths = std::unordered_set<std::string>{};
119  auto successfulPaths = size_t{0};
122  m_interfaces.visitPathsWithoutHandlers([&](std::string const &path) {
123  auto success = m_connectCallbacksOnPath(path);
124  if (success) {
125  successfulPaths++;
126  } else {
127  failedPaths.insert(path);
128  }
129  });
130  logger()->info() << "Connected " << successfulPaths << " of "
131  << successfulPaths + failedPaths.size()
132  << " unconnected paths successfully";
133  }
134 
135  util::log::LoggerPtr const &ClientInterfaceObjectManager::logger() const {
136  return m_ctx->logger();
137  }
138 } // namespace client
139 } // namespace osvr
ref_type_at_key< Derived, Key >::type get(TypeKeyedBase< Derived > &c)
Definition: TypeKeyed.h:200
shared_ptr< ClientInterface > ClientInterfacePtr
Pointer for holding ClientInterface objects safely.
RemoteHandlerPtr eraseHandlerForPath(std::string const &path)
Clears and returns the handler for a given path.
FactoryProduct invokeFactory(common::OriginalSource const &source, common::InterfaceList &ifaces, common::ClientContext &ctx) const
bool addInterface(common::ClientInterfacePtr const &iface)
Add an interface to the tree.
RemoteHandlerPtr replaceHandlerForPath(std::string const &path, RemoteHandlerPtr const &handler)
Sets the handler for a given path, returning the old handler if any.
void updateHandlers()
Call the update method on all handlers.
common::InterfaceList & getInterfacesForPath(std::string const &path)
Returns a reference to the list of interfaces registered for a given path.
bool removeInterface(common::ClientInterfacePtr const &iface)
Remove an interface from the tree.
void visitPathsWithoutHandlers(F &&func)
Visit all paths with interfaces in their list but no handler.
Definition: InterfaceTree.h:97
Header.
void addInterface(common::ClientInterfacePtr const &iface, bool verboseFailure=true)
Internal, configured header file for verbosity macros.
osvr::util::log::LoggerPtr const & logger() const
Provides logger access for related internal classes.
void updateHandlers()
run update on all remote handlers