Skip to content

Commit

Permalink
Closes #63
Browse files Browse the repository at this point in the history
1. Use `find` instead of `operator []` in `getProxy`.
2. Add `getTypedProxy`.
3. Error if `getProxy` returns a `nullptr`.
4. Add virtual destructor to `Proxy` class.
  • Loading branch information
sgilmore10 authored Jul 10, 2023
1 parent 77f3d72 commit a01993d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
3 changes: 3 additions & 0 deletions libmexclass/cpp/source/include/libmexclass/proxy/Proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ namespace libmexclass::proxy {
class Proxy {
public:
Proxy() : methods{} { }

virtual ~Proxy() {}

std::optional<libmexclass::error::Error> invoke(libmexclass::proxy::method::Method& method);
protected:
std::unordered_map<libmexclass::proxy::method::Name, libmexclass::proxy::method::Object> methods;
Expand Down
24 changes: 24 additions & 0 deletions libmexclass/cpp/source/include/libmexclass/proxy/ProxyManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

#include "libmexclass/proxy/ID.h"
#include "libmexclass/proxy/Proxy.h"
#include "libmexclass/error/Error.h"

#include <memory>
#include <unordered_map>
#include <variant>

namespace libmexclass::proxy {

template <typename T>
using ProxyResult = std::variant<std::shared_ptr<T>, libmexclass::error::Error>;

// ProxyMangager
// Manages Proxy instances by placing them inside of a map which maps unique IDs
// to Proxy instances. NOTE: ProxyManager uses the "Singleton" design pattern to
Expand All @@ -17,6 +23,23 @@ class ProxyManager {
static void unmanageProxy(ID id);
static std::shared_ptr<Proxy> getProxy(ID id);

template <typename T>
static ProxyResult<T> getTypedProxy(ID id) {
auto proxy = libmexclass::proxy::ProxyManager::getProxy(id);
if (!proxy) {
std::string msg = "Invalid Proxy ID: " + std::to_string(id);
return libmexclass::error::Error{"libmexclass:proxy:InvalidID", msg};
}

auto typed_proxy = std::dynamic_pointer_cast<T>(proxy);
if (!typed_proxy) {
std::string msg = "Failed to cast proxy to expected type";
return libmexclass::error::Error{"libmexclass:proxy:InvalidProxyType", msg};
}

return typed_proxy;
}

private:
static ProxyManager singleton;
// The internal map used to associate Proxy instances with unique IDs.
Expand All @@ -31,4 +54,5 @@ class ProxyManager {
// increment it.
ID current_proxy_id = 0;
};

} // namespace libmexclass::proxy
7 changes: 5 additions & 2 deletions libmexclass/cpp/source/libmexclass/action/MethodCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ std::optional<libmexclass::error::Error> MethodCall::execute() {
// TODO: Implement ID retrieval logic from MethodCall properties.
// Retrieve the appropriate polymorphic proxy::Proxy instance from the
// proxy::ProxyManager using the given proxy::ID.
std::shared_ptr<libmexclass::proxy::Proxy> proxy =
libmexclass::proxy::ProxyManager::getProxy(proxy_id);
auto proxy = libmexclass::proxy::ProxyManager::getProxy(proxy_id);

if (!proxy) {
return libmexclass::error::Error{"libmexclass:proxy:UnknownProxyID", "Unknown proxy ID " + std::to_string(proxy_id)};
}

// Invoke the appropriate method on the proxy::Proxy instance.
// Note: To assign/return outputs from a method call, proxy::Proxy
Expand Down
7 changes: 6 additions & 1 deletion libmexclass/cpp/source/libmexclass/proxy/ProxyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ void ProxyManager::unmanageProxy(ID id) {
}

std::shared_ptr<Proxy> ProxyManager::getProxy(ID id) {
return ProxyManager::singleton.proxy_map[id];
auto proxy_key_value = ProxyManager::singleton.proxy_map.find(id);
if (proxy_key_value != ProxyManager::singleton.proxy_map.end()) {
return proxy_key_value->second;
} else {
return nullptr;
}
}

ProxyManager ProxyManager::singleton{};
Expand Down

0 comments on commit a01993d

Please sign in to comment.