Skip to content

Commit

Permalink
Making use of PMPL with the AutoNetServer
Browse files Browse the repository at this point in the history
  • Loading branch information
codemercenary committed Aug 14, 2014
1 parent 656190f commit 85406b9
Show file tree
Hide file tree
Showing 5 changed files with 532 additions and 495 deletions.
168 changes: 8 additions & 160 deletions autowiring/AutoNetServer.h
@@ -1,177 +1,25 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include "CoreThread.h"
#include "Autowired.h"
#include "AutowiringEvents.h"
#include <json11/json11.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <map>
#include <set>

struct TypeIdentifierBase;

class AutoNetServer:
public CoreThread,
public virtual AutowiringEvents
public CoreThread
{
public:
protected:
AutoNetServer();
virtual ~AutoNetServer();

//Types
typedef websocketpp::server<websocketpp::config::asio> server;
typedef server::message_ptr message_ptr;

// Functions from CoreContext
virtual void Run(void) override;
virtual void OnStop(void) override;
public:
virtual ~AutoNetServer();
static AutoNetServer* New(void);

// Server Handler functions
void OnOpen(websocketpp::connection_hdl hdl);
void OnClose(websocketpp::connection_hdl hdl);
void OnMessage(websocketpp::connection_hdl hdl, message_ptr p_message);

/// <summary>
/// Waits until resume message is sent from the visualizer
/// </summary>
/// <param name="name">The identifier for this breakpoint</param>
void Breakpoint(std::string name);
virtual void Breakpoint(std::string name) = 0;

/// <summary>
/// Updates server when a new context is created
/// </summary>
/// <param name="ctxt">The new context</param>
virtual void NewContext(CoreContext& ctxt) override;

/// <summary>
/// Updates server when a context has expired
/// </summary>
/// <param name="ctxt">The expired context</param>
virtual void ExpiredContext(CoreContext& ctxt) override;

/// <summary>
/// Updates server when a new object is created
/// </summary>
/// <param name="ctxt">Context containing the object</param>
/// <param name="obj">The object</param>
virtual void NewObject(CoreContext& ctxt, const AnySharedPointer& obj) override;

/// <summary>
/// Updates server when a context has expired
/// </summary>
/// <param name="ctxt">The expired context</param>
/// <param name="evtInfo">The event type</param>
virtual void EventFired(CoreContext& ctxt, const std::type_info& evtInfo) override;
// Allows a breakpoint previously set with Breakpoint to be resumed
virtual void HandleResumeFromBreakpoint(std::string name) = 0;

protected:
/// <summary>
/// Sends a message to specified client.
/// </summary>
/// <param name="hdl">Connection pointer on which to send message</param>
/// <param name="pRecipient">Message name in CamelCase</param>
/// <param name="args...">Arguments to be passed to client side event handler</param>
/// <remarks>
/// Client callback with same number of arguments passed here will be called
/// </remarks>
template<typename... Args>
void SendMessage(websocketpp::connection_hdl hdl, const char* p_type, Args&&... args){
using json11::Json;

Json msg = Json::object {
{"type", p_type},
{"args", Json::array{args...}}
};

m_Server->send(hdl, msg.dump(), websocketpp::frame::opcode::text);
}

/// <summary>
/// Broadcast a message to all subscribers.
/// </summary>
/// <param name="pRecipient">Message name in CamelCase</param>
/// <param name="args...">An arg to be passed to client side event handler</param>
template<typename ...Args>
void BroadcastMessage(const char* p_type, Args&&... args) {
for (websocketpp::connection_hdl ptr : m_Subscribers)
SendMessage(ptr, p_type, std::forward<Args>(args)...);
}

/// <summary>
/// Called when a "Subscribe" event is sent from a client
/// </summary>
/// <param name="client">Client that sent event</param>
void HandleSubscribe(websocketpp::connection_hdl hdl);

/// <summary>
/// Called when a "Unsubscribe" event is sent from a client
/// </summary>
/// <param name="client">Client that sent event</param>
void HandleUnsubscribe(websocketpp::connection_hdl hdl);

/// <summary>
/// Called when a "terminateContext" event is sent from a client
/// </summary>
/// <param name="contextID">ID of the context to be terminated</param>
void HandleTerminateContext(int contextID);

/// <summary>
/// Called when a "injectContextMember" event is sent from a client
/// </summary>
/// <param name="contextID">ID of the context to inject the type</param>
/// <param name="typeName">Name of the type to inject. From std::type_info.name()</param>
void HandleInjectContextMember(int contextID, std::string typeName);

/// <summary>
/// Called when a "injectContextMember" event is sent from a client
/// </summary>
/// <param name="name">Name of the breakpoint to resume</param>
void HandleResumeFromBreakpoint(std::string name);

/// <summary>
/// Assigns each context a unique ID number
/// </summary>
/// <param name="ctxt">Client that sent event</param>
int ResolveContextID(CoreContext* ctxt);
CoreContext* ResolveContextID(int id);

/// <summary>
/// Append a lambda to this queue that will poll CoreThreads for their utilization
/// </summary>
void PollThreadUtilization(std::chrono::milliseconds period);


/*******************************************
* Member variables *
*******************************************/

// Set of all subscribers
std::set<websocketpp::connection_hdl, std::owner_less<websocketpp::connection_hdl>> m_Subscribers;

// one-to-one map of contexts to integers
std::map<CoreContext*, int> m_ContextIDs;
std::map<int, CoreContext*> m_ContextPtrs;

// All event types
std::set<std::shared_ptr<TypeIdentifierBase>> m_EventTypes;

// All ContextMembers
std::map<std::string, std::function<void(void)>> m_AllTypes;

// All CoreThreads
struct ThreadStats {
// Last amount of time the thread was known to be running
std::chrono::milliseconds m_lastRuntimeKM;
std::chrono::milliseconds m_lastRuntimeUM;
};
std::map<std::weak_ptr<BasicThread>, ThreadStats, std::owner_less<std::weak_ptr<BasicThread>>> m_Threads;

// Breakpoint functionality
std::mutex m_mutex;
std::condition_variable m_breakpoint_cv;
std::set<std::string> m_breakpoints;

// The actual server
std::shared_ptr<server> m_Server;
const int m_Port; // Port to listen on
};

0 comments on commit 85406b9

Please sign in to comment.