logic: IDE Communication
Network code and controller added to communicate with IDE plugins. Does not include GUI integration though.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
#include "IDECommunicationController.h"
|
||||
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
#include "component/controller/helper/NetworkProtocolHelper.h"
|
||||
|
||||
IDECommunicationController::IDECommunicationController()
|
||||
{
|
||||
}
|
||||
|
||||
IDECommunicationController::~IDECommunicationController()
|
||||
{
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleIncomingMessage(const std::string& message)
|
||||
{
|
||||
LOG_WARNING_STREAM(<< message);
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage parsedMessage = NetworkProtocolHelper::parseMessage(message);
|
||||
|
||||
if (parsedMessage.valid)
|
||||
{
|
||||
// TODO: set active token
|
||||
}
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleMessage(MessageMoveIDECursor* message)
|
||||
{
|
||||
std::string networkMessage = NetworkProtocolHelper::buildMessage(message->FilePosition, message->Row, message->Column);
|
||||
|
||||
sendMessage(networkMessage);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef IDE_COMMUNICATION_CONTROLLER_H
|
||||
#define IDE_COMMUNICATION_CONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageMoveIDECursor.h"
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
|
||||
class IDECommunicationController
|
||||
: public Controller
|
||||
, public MessageListener<MessageMoveIDECursor>
|
||||
{
|
||||
public:
|
||||
IDECommunicationController();
|
||||
virtual ~IDECommunicationController();
|
||||
|
||||
void handleIncomingMessage(const std::string& message);
|
||||
|
||||
private:
|
||||
virtual void handleMessage(MessageMoveIDECursor* message);
|
||||
virtual void sendMessage(const std::string& message) const = 0;
|
||||
};
|
||||
|
||||
#endif // IDE_COMMUNICATION_CONTROLLER_H
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "component/controller/NetworkFactory.h"
|
||||
|
||||
NetworkFactory::NetworkFactory()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkFactory::~NetworkFactory()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef NETWORK_FACTORY_H
|
||||
#define NETWORK_FACTORY_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
class IDECommunicationController;
|
||||
|
||||
class NetworkFactory
|
||||
{
|
||||
public:
|
||||
NetworkFactory();
|
||||
virtual ~NetworkFactory();
|
||||
|
||||
virtual std::shared_ptr<IDECommunicationController> createIDECommunicationController() const = 0;
|
||||
};
|
||||
|
||||
#endif // NETWORK_FACTORY_H
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
|
||||
unsigned int GraphPostprocessor::s_cellSize = GraphViewStyle::s_gridCellSize;
|
||||
unsigned int GraphPostprocessor::s_cellWidth = GraphViewStyle::s_gridCellSize;
|
||||
unsigned int GraphPostprocessor::s_cellHeight = GraphViewStyle::s_gridCellSize;
|
||||
unsigned int GraphPostprocessor::s_cellPadding = GraphViewStyle::s_gridCellPadding;
|
||||
|
||||
void GraphPostprocessor::doPostprocessing(std::vector<DummyNode>& nodes)
|
||||
{
|
||||
unsigned int atomarGridSize = s_cellSize;
|
||||
unsigned int atomarGridWidth = s_cellWidth;
|
||||
unsigned int atomarGridHeight = s_cellHeight;
|
||||
|
||||
if (nodes.size() < 2)
|
||||
{
|
||||
@@ -16,42 +18,43 @@ void GraphPostprocessor::doPostprocessing(std::vector<DummyNode>& nodes)
|
||||
}
|
||||
|
||||
// determine center of mass (CoD) which is used to get outliers closer to the rest of the graph
|
||||
int divisor = 999999;
|
||||
int maxNodeSize = 0;
|
||||
int divisorWidth = 999999;
|
||||
int divisorHeight = 999999;
|
||||
int maxNodeWidth = 0;
|
||||
int maxNodeHeight = 0;
|
||||
Vec2i centerOfMass(0, 0);
|
||||
float totalMass = 0.0f;
|
||||
|
||||
for (const DummyNode& node : nodes)
|
||||
{
|
||||
const Vec2i& size = node.size;
|
||||
|
||||
if (size.x < divisor)
|
||||
if (node.size.x < divisorWidth)
|
||||
{
|
||||
divisor = size.x;
|
||||
divisorWidth = node.size.x;
|
||||
}
|
||||
|
||||
if (size.y < divisor)
|
||||
if (node.size.y < divisorHeight)
|
||||
{
|
||||
divisor = size.y;
|
||||
divisorHeight = node.size.y;
|
||||
}
|
||||
|
||||
if (size.x > maxNodeSize)
|
||||
if (node.size.x > maxNodeWidth)
|
||||
{
|
||||
maxNodeSize = size.x;
|
||||
maxNodeWidth = node.size.x;
|
||||
}
|
||||
else if (size.y > maxNodeSize)
|
||||
else if (node.size.y > maxNodeHeight)
|
||||
{
|
||||
maxNodeSize = size.y;
|
||||
maxNodeHeight = node.size.y;
|
||||
}
|
||||
|
||||
float nodeMass = size.getLengthSquared();
|
||||
float nodeMass = node.size.x * node.size.y;
|
||||
centerOfMass += node.position * nodeMass;
|
||||
totalMass += nodeMass;
|
||||
}
|
||||
|
||||
centerOfMass /= totalMass;
|
||||
|
||||
divisor = (int)atomarGridSize + s_cellPadding; //std::min(divisor, (int)atomarGridSize);
|
||||
divisorWidth = (int)atomarGridWidth + s_cellPadding; //std::min(divisor, (int)atomarGridSize);
|
||||
divisorHeight = (int)atomarGridHeight + s_cellPadding;
|
||||
|
||||
resolveOutliers(nodes, centerOfMass);
|
||||
|
||||
@@ -62,9 +65,9 @@ void GraphPostprocessor::doPostprocessing(std::vector<DummyNode>& nodes)
|
||||
alignNodeOnRaster(node);
|
||||
}
|
||||
|
||||
MatrixDynamicBase<unsigned int> heatMap = buildHeatMap(nodes, divisor, maxNodeSize);
|
||||
MatrixDynamicBase<unsigned int> heatMap = buildHeatMap(nodes, divisorWidth, divisorHeight, maxNodeWidth, maxNodeHeight);
|
||||
|
||||
resolveOverlap(nodes, heatMap, divisor);
|
||||
resolveOverlap(nodes, heatMap, divisorWidth, divisorHeight);
|
||||
}
|
||||
|
||||
void GraphPostprocessor::alignNodeOnRaster(DummyNode& node)
|
||||
@@ -74,7 +77,7 @@ void GraphPostprocessor::alignNodeOnRaster(DummyNode& node)
|
||||
|
||||
Vec2i GraphPostprocessor::alignOnRaster(Vec2i position)
|
||||
{
|
||||
int rasterPosDivisor = s_cellSize + s_cellPadding;
|
||||
int rasterPosDivisor = s_cellWidth + s_cellPadding;
|
||||
|
||||
if (position.x % rasterPosDivisor != 0)
|
||||
{
|
||||
@@ -148,20 +151,17 @@ void GraphPostprocessor::resolveOutliers(std::vector<DummyNode>& nodes, const Ve
|
||||
}
|
||||
|
||||
MatrixDynamicBase<unsigned int> GraphPostprocessor::buildHeatMap(
|
||||
const std::vector<DummyNode>& nodes, const int atomarNodeSize, const int maxNodeSize
|
||||
){
|
||||
// theoretically the nodes could horizontally or vertically far from the center, therefore '*5' (it's kinda arbitrary,
|
||||
// generally *2 should suffice, I use *5 to prevent problems in extrem cases)
|
||||
int heatMapWidth = (maxNodeSize * nodes.size() / atomarNodeSize) * 5;
|
||||
int heatMapHeight = heatMapWidth;
|
||||
const std::vector<DummyNode>& nodes, const int atomarNodeWidth, const int atomarNodeHeight, const int maxNodeWidth, const int maxNodeHeight)
|
||||
{
|
||||
int heatMapWidth = (maxNodeWidth * nodes.size() / atomarNodeWidth) * 5; // theoretically the nodes could horizontally or vertically far from the center, therefore '*5' (it's kinda arbitrary, generally *2 should suffice, I use *5 to prevent problems in extrem cases)
|
||||
int heatMapHeight = (maxNodeHeight * nodes.size() / atomarNodeHeight) * 5;
|
||||
|
||||
MatrixDynamicBase<unsigned int> heatMap(heatMapWidth, heatMapHeight);
|
||||
|
||||
for (const DummyNode& node : nodes)
|
||||
{
|
||||
int left = node.position.x / atomarNodeSize + heatMapWidth / 2;
|
||||
int up = node.position.y / atomarNodeSize + heatMapHeight / 2;
|
||||
|
||||
int left = node.position.x / atomarNodeWidth + heatMapWidth/2;
|
||||
int up = node.position.y / atomarNodeHeight + heatMapHeight/2;
|
||||
Vec2i size = calculateRasterNodeSize(node);
|
||||
int width = size.x;
|
||||
int height = size.y;
|
||||
@@ -193,8 +193,8 @@ MatrixDynamicBase<unsigned int> GraphPostprocessor::buildHeatMap(
|
||||
}
|
||||
|
||||
void GraphPostprocessor::resolveOverlap(
|
||||
std::vector<DummyNode>& nodes, MatrixDynamicBase<unsigned int>& heatMap, const int divisor
|
||||
){
|
||||
std::vector<DummyNode>& nodes, MatrixDynamicBase<unsigned int>& heatMap, const int divisorWidth, const int divisorHeight)
|
||||
{
|
||||
int heatMapWidth = heatMap.getColumnsCount();
|
||||
int heatMapHeight = heatMap.getRowsCount();
|
||||
|
||||
@@ -211,9 +211,9 @@ void GraphPostprocessor::resolveOverlap(
|
||||
|
||||
for (DummyNode& node : nodes)
|
||||
{
|
||||
Vec2i nodePos;
|
||||
nodePos.x = node.position.x / divisor + heatMapWidth / 2;
|
||||
nodePos.y = node.position.y / divisor + heatMapHeight / 2;
|
||||
Vec2i nodePos(0, 0);
|
||||
nodePos.x = node.position.x / divisorWidth + heatMapWidth/2;
|
||||
nodePos.y = node.position.y / divisorHeight + heatMapHeight/2;
|
||||
Vec2i nodeSize = calculateRasterNodeSize(node);
|
||||
|
||||
if (nodePos.x + nodeSize.x > heatMapWidth || nodePos.x < 0)
|
||||
@@ -254,28 +254,29 @@ void GraphPostprocessor::resolveOverlap(
|
||||
modifyHeatmapArea(heatMap, nodePos, nodeSize, -1);
|
||||
|
||||
// move node to new position
|
||||
int xOffset = grad.x * divisor;
|
||||
int yOffset = grad.y * divisor;
|
||||
int xOffset = grad.x * divisorWidth;
|
||||
int yOffset = grad.y * divisorHeight;
|
||||
|
||||
|
||||
int maxOffset = 2 * divisor;
|
||||
int maxXOffset = 2*divisorWidth;
|
||||
int maxYOffset = 2*divisorHeight;
|
||||
|
||||
// prevent the graph from "exploding" again...
|
||||
if (xOffset > maxOffset)
|
||||
if (xOffset > maxXOffset)
|
||||
{
|
||||
xOffset = maxOffset;
|
||||
xOffset = maxXOffset;
|
||||
}
|
||||
else if (xOffset < -maxOffset)
|
||||
else if (xOffset < -maxXOffset)
|
||||
{
|
||||
xOffset = -maxOffset;
|
||||
xOffset = -maxXOffset;
|
||||
}
|
||||
|
||||
if (yOffset > maxOffset)
|
||||
if (yOffset > maxYOffset)
|
||||
{
|
||||
yOffset = maxOffset;
|
||||
yOffset = maxYOffset;
|
||||
}
|
||||
else if (yOffset < -maxOffset)
|
||||
else if (yOffset < -maxYOffset)
|
||||
{
|
||||
yOffset = -maxOffset;
|
||||
yOffset = -maxYOffset;
|
||||
}
|
||||
|
||||
node.position += Vec2i(xOffset, yOffset);
|
||||
@@ -283,8 +284,8 @@ void GraphPostprocessor::resolveOverlap(
|
||||
alignNodeOnRaster(node);
|
||||
|
||||
// re-add node to heat map at new position
|
||||
nodePos.x = node.position.x / divisor + heatMapWidth / 2;
|
||||
nodePos.y = node.position.y / divisor + heatMapHeight / 2;
|
||||
nodePos.x = node.position.x / divisorWidth + heatMapWidth/2;
|
||||
nodePos.y = node.position.y / divisorHeight + heatMapHeight/2;
|
||||
|
||||
modifyHeatmapArea(heatMap, nodePos, nodeSize, 1);
|
||||
|
||||
@@ -442,8 +443,8 @@ Vec2i GraphPostprocessor::calculateRasterNodeSize(const DummyNode& node)
|
||||
|
||||
while (size.x > 0)
|
||||
{
|
||||
size.x = size.x - s_cellSize;
|
||||
if (size.x > 0)
|
||||
size.x = size.x - s_cellWidth;
|
||||
if(size.x > 0)
|
||||
{
|
||||
size.x = size.x - s_cellPadding;
|
||||
}
|
||||
@@ -453,8 +454,8 @@ Vec2i GraphPostprocessor::calculateRasterNodeSize(const DummyNode& node)
|
||||
|
||||
while (size.y > 0)
|
||||
{
|
||||
size.y = size.y - s_cellSize;
|
||||
if (size.y > 0)
|
||||
size.y = size.y - s_cellHeight;
|
||||
if(size.y > 0)
|
||||
{
|
||||
size.y = size.y - s_cellPadding;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ public:
|
||||
static Vec2i alignOnRaster(Vec2i position);
|
||||
|
||||
private:
|
||||
static unsigned int s_cellSize;
|
||||
static unsigned int s_cellWidth;
|
||||
static unsigned int s_cellHeight;
|
||||
static unsigned int s_cellPadding;
|
||||
|
||||
static MatrixDynamicBase<unsigned int> buildHeatMap(const std::vector<DummyNode>& nodes, const int atomarNodeSize, const int maxNodeSize);
|
||||
static MatrixDynamicBase<unsigned int> buildHeatMap(const std::vector<DummyNode>& nodes, const int atomarNodeWidth, const int atomarNodeHeight, const int maxNodeWidth, const int maxNodeHeight);
|
||||
static void resolveOutliers(std::vector<DummyNode>& nodes, const Vec2i& centerPoint);
|
||||
static void resolveOverlap(std::vector<DummyNode>& nodes, MatrixDynamicBase<unsigned int>& heatMap, const int divisor);
|
||||
static void resolveOverlap(std::vector<DummyNode>& nodes, MatrixDynamicBase<unsigned int>& heatMap, const int divisorWidth, const int divisorHeight);
|
||||
|
||||
static void modifyHeatmapArea(MatrixDynamicBase<unsigned int>& heatMap, const Vec2i& leftUpperCorner, const Vec2i& size, const int modifier);
|
||||
static bool getHeatmapGradient(Vec2f& outGradient, const MatrixDynamicBase<unsigned int>& heatMap, const Vec2i& leftUpperCorner, const Vec2i& size);
|
||||
static Vec2f heatMapRayCast(const MatrixDynamicBase<unsigned int>& heatMap, const Vec2f& startPosition, const Vec2f& direction, unsigned int minValue);
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "NetworkProtocolHelper.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
std::string NetworkProtocolHelper::m_divider = ">>";
|
||||
std::string NetworkProtocolHelper::m_setActiveTokenPrefix = "setActiveToken";
|
||||
std::string NetworkProtocolHelper::m_moveCursorPrefix = "moveCursor";
|
||||
std::string NetworkProtocolHelper::m_endOfMessageToken = "<EOM>";
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage NetworkProtocolHelper::parseMessage(const std::string& message)
|
||||
{
|
||||
NetworkMessage networkMessage;
|
||||
|
||||
std::string tmpMessage = removeEndOfMessageToken(message);
|
||||
|
||||
size_t pos = tmpMessage.find(m_setActiveTokenPrefix);
|
||||
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
tmpMessage = "";
|
||||
getSubstringAfterString(message, m_divider, tmpMessage); // just get rid of message type
|
||||
|
||||
std::string fileLocation = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string row = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string column = tmpMessage; // getSubstringAfterString(tmpMessage, "", tmpMessage); // there should be nothing left in the message but the column number
|
||||
|
||||
if(fileLocation.length() <= 0
|
||||
|| row.length() <= 0
|
||||
|| column.length() <= 0
|
||||
|| isDigits(row) == false
|
||||
|| isDigits(column) == false)
|
||||
{
|
||||
return networkMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
networkMessage.fileLocation = fileLocation;
|
||||
networkMessage.row = std::stoi(row);
|
||||
networkMessage.column = std::stoi(column);
|
||||
networkMessage.valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
return networkMessage;
|
||||
}
|
||||
|
||||
std::string NetworkProtocolHelper::buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column)
|
||||
{
|
||||
std::stringstream messageStream;
|
||||
|
||||
messageStream << m_moveCursorPrefix;
|
||||
messageStream << m_divider;
|
||||
messageStream << fileLocation;
|
||||
messageStream << m_divider;
|
||||
messageStream << row;
|
||||
messageStream << m_divider;
|
||||
messageStream << column;
|
||||
messageStream << m_endOfMessageToken;
|
||||
|
||||
return messageStream.str();
|
||||
}
|
||||
|
||||
std::string NetworkProtocolHelper::removeEndOfMessageToken(const std::string& message)
|
||||
{
|
||||
size_t pos = message.find(m_endOfMessageToken);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return message.substr(0, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
std::string NetworkProtocolHelper::getSubstringAfterString(const std::string& message, const std::string& searchString, std::string& subMessage)
|
||||
{
|
||||
std::string result = "";
|
||||
|
||||
size_t pos = message.find(searchString);
|
||||
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
result = message.substr(0, pos);
|
||||
subMessage = message.substr(pos + searchString.length());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NetworkProtocolHelper::isDigits(const std::string& text)
|
||||
{
|
||||
return (text.find_first_not_of("0123456789") == std::string::npos);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef NETWORK_PROTOCOL_HELPER_H
|
||||
#define NETWORK_PROTOCOL_HELPER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class NetworkProtocolHelper
|
||||
{
|
||||
public:
|
||||
struct NetworkMessage
|
||||
{
|
||||
public:
|
||||
NetworkMessage()
|
||||
: fileLocation("")
|
||||
, row(0)
|
||||
, column(0)
|
||||
, valid(false)
|
||||
{}
|
||||
|
||||
std::string fileLocation;
|
||||
unsigned int row;
|
||||
unsigned int column;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
static NetworkMessage parseMessage(const std::string& message);
|
||||
static std::string buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column);
|
||||
|
||||
private:
|
||||
static std::string removeEndOfMessageToken(const std::string& message);
|
||||
|
||||
static std::string getSubstringAfterString(const std::string& message, const std::string& searchString, std::string& subMessage);
|
||||
static bool isDigits(const std::string& text);
|
||||
|
||||
static std::string m_divider;
|
||||
static std::string m_setActiveTokenPrefix;
|
||||
static std::string m_moveCursorPrefix;
|
||||
static std::string m_endOfMessageToken;
|
||||
};
|
||||
|
||||
#endif // NETWORK_PROTOCOL_HELPER_H
|
||||
Reference in New Issue
Block a user