diff --git a/plugins/circuits/src/visuals/ElectronicCircuitNode.cpp b/plugins/circuits/src/visuals/ElectronicCircuitNode.cpp index 1ef4608..8a3dfad 100644 --- a/plugins/circuits/src/visuals/ElectronicCircuitNode.cpp +++ b/plugins/circuits/src/visuals/ElectronicCircuitNode.cpp @@ -4,6 +4,8 @@ #include "WireNode.h" #include "LogicGateNode.h" +#include "LineNode.h" + #include "FileLogger.h" ElectronicCircuitNode::ElectronicCircuitNode(const Transform& transform) diff --git a/plugins/quantum_computing/src/QuantumCircuitReader.cpp b/plugins/quantum_computing/src/QuantumCircuitReader.cpp index f857d12..ae30274 100644 --- a/plugins/quantum_computing/src/QuantumCircuitReader.cpp +++ b/plugins/quantum_computing/src/QuantumCircuitReader.cpp @@ -12,194 +12,194 @@ std::unique_ptr QuantumCircuitReader::read(const Path& path) { - File file(path); - return read(file.readText()); + File file(path); + return read(file.readText()); } std::unique_ptr QuantumCircuitReader::read(const std::string& content) { - auto circuit = std::make_unique(); - mWorkingCircuit = circuit.get(); + auto circuit = std::make_unique(); + mWorkingCircuit = circuit.get(); - std::size_t cursor = 0; - for (const auto& line : StringUtils::toLines(content)) - { - onLine(line, cursor); - cursor++; - } - circuit->buildWireConnections(); - return circuit; + std::size_t cursor = 0; + for (const auto& line : StringUtils::toLines(content)) + { + onLine(line, cursor); + cursor++; + } + circuit->buildWireConnections(); + return circuit; } void QuantumCircuitReader::onLine(const std::string& line, std::size_t jdx) { - mWorkingString.clear(); - std::size_t cursor = 0; + mWorkingString.clear(); + std::size_t cursor = 0; - while (cursor < line.size()) - { - const auto c = line[cursor]; - MLOG_INFO("Working char: " << std::string(1, c)); + while (cursor < line.size()) + { + const auto c = line[cursor]; + MLOG_INFO("Working char: " << std::string(1, c)); - if (c == '|') - { - if (cursor + 1 < line.size()) - { - if (line[cursor + 1] == '-') - { - onVertialQuantumWire({ cursor, jdx }); - } - else if (auto ket = checkForKet(line.substr(cursor + 1, line.size() - cursor)); !ket.empty()) - { - onKet({ cursor, jdx }, ket); - cursor += ket.size() + 1; - } - } - else - { - mWorkingString += c; - } - } - else if (c == '-') - { - if (cursor + 1 < line.size()) - { - const auto end_id = getWireEnd(line.substr(cursor, line.size() - cursor)); - MLOG_INFO("Wire: " << cursor << " with length " << end_id); - cursor += end_id - 1; - } - else - { - mWorkingString += c; - } - } - else - { - if (cursor + 1 < line.size()) - { - auto gate = checkForGate(line.substr(cursor, line.size() - cursor)); - onGate({ cursor, jdx }, gate); - cursor += gate.size() - 1; - } - else - { - mWorkingString += c; - } - } - cursor++; - } - onLineEnd(); + if (c == '|') + { + if (cursor + 1 < line.size()) + { + if (line[cursor + 1] == '-') + { + onVertialQuantumWire({ cursor, jdx }); + } + else if (auto ket = checkForKet(line.substr(cursor + 1, line.size() - cursor)); !ket.empty()) + { + onKet({ cursor, jdx }, ket); + cursor += ket.size() + 1; + } + } + else + { + mWorkingString += c; + } + } + else if (c == '-') + { + if (cursor + 1 < line.size()) + { + const auto end_id = getWireEnd(line.substr(cursor, line.size() - cursor)); + MLOG_INFO("Wire: " << cursor << " with length " << end_id); + cursor += end_id - 1; + } + else + { + mWorkingString += c; + } + } + else + { + if (cursor + 1 < line.size()) + { + auto gate = checkForGate(line.substr(cursor, line.size() - cursor)); + onGate({ cursor, jdx }, gate); + cursor += gate.size() - 1; + } + else + { + mWorkingString += c; + } + } + cursor++; + } + onLineEnd(); } void QuantumCircuitReader::onLineEnd() { - auto output_terminal = std::make_unique(QuantumTerminal::TerminalType::OUTPUT); + auto output_terminal = std::make_unique(QuantumTerminal::TerminalType::OUTPUT); - auto wire = std::make_unique(mWorkingElement, output_terminal.get()); - mWorkingCircuit->addQuantumWire(std::move(wire)); + auto wire = std::make_unique(mWorkingElement, output_terminal.get()); + mWorkingCircuit->addQuantumWire(std::move(wire)); - mWorkingCircuit->addOutputTerminal(std::move(output_terminal)); + mWorkingCircuit->addOutputTerminal(std::move(output_terminal)); - mWorkingElement = nullptr; + mWorkingElement = nullptr; } -void QuantumCircuitReader::onGate(Location loc, const std::string value) +void QuantumCircuitReader::onGate(Location, const std::string value) { - MLOG_INFO("Got gate: " << value); + MLOG_INFO("Got gate: " << value); - QuantumGatePtr gate; + QuantumGatePtr gate; - if (value == "X") - { - gate = std::make_unique(); - } - else if (value == "Z") - { - gate = std::make_unique(); - } + if (value == "X") + { + gate = std::make_unique(); + } + else if (value == "Z") + { + gate = std::make_unique(); + } - if (gate) - { - auto wire = std::make_unique(mWorkingElement, gate.get()); - mWorkingCircuit->addQuantumWire(std::move(wire)); + if (gate) + { + auto wire = std::make_unique(mWorkingElement, gate.get()); + mWorkingCircuit->addQuantumWire(std::move(wire)); - mWorkingElement = gate.get(); - mWorkingCircuit->addLogicGate(std::move(gate)); - } + mWorkingElement = gate.get(); + mWorkingCircuit->addLogicGate(std::move(gate)); + } } std::string QuantumCircuitReader::checkForGate(const std::string& segment) { - std::string working_string; - for (const auto c : segment) - { - if (c == '-') - { - break; - } - working_string += c; - } - return working_string; + std::string working_string; + for (const auto c : segment) + { + if (c == '-') + { + break; + } + working_string += c; + } + return working_string; } -void QuantumCircuitReader::onKet(Location loc, const std::string value) +void QuantumCircuitReader::onKet(Location, const std::string value) { - MLOG_INFO("Got input state: " << value); - Qubit qubit; - if (value == "1") - { - qubit = Qubit({ 0.0, 0.0 }, { 1.0, 0.0 }); - } + MLOG_INFO("Got input state: " << value); + Qubit qubit; + if (value == "1") + { + qubit = Qubit({ 0.0, 0.0 }, { 1.0, 0.0 }); + } - auto input_terminal = std::make_unique(QuantumTerminal::TerminalType::INPUT); + auto input_terminal = std::make_unique(QuantumTerminal::TerminalType::INPUT); - mWorkingElement = input_terminal.get(); - mWorkingCircuit->addInputTerminal(std::move(input_terminal)); + mWorkingElement = input_terminal.get(); + mWorkingCircuit->addInputTerminal(std::move(input_terminal)); } std::size_t QuantumCircuitReader::getWireEnd(const std::string& segment) { - std::size_t idx = 0; - for (const auto c : segment) - { - if (c != '-') - { - break; - } - idx++; - } - return idx; + std::size_t idx = 0; + for (const auto c : segment) + { + if (c != '-') + { + break; + } + idx++; + } + return idx; } std::string QuantumCircuitReader::checkForKet(const std::string& segment) { - std::string working_string; - bool found{ false }; + std::string working_string; + bool found{ false }; - for (const auto c : segment) - { - if (c == '>') - { - found = true; - break; - } - else - { - working_string += c; - } - } + for (const auto c : segment) + { + if (c == '>') + { + found = true; + break; + } + else + { + working_string += c; + } + } - if (found) - { - return working_string; - } - else - { - return {}; - } + if (found) + { + return working_string; + } + else + { + return {}; + } } -void QuantumCircuitReader::onVertialQuantumWire(Location loc) +void QuantumCircuitReader::onVertialQuantumWire(Location) { -} \ No newline at end of file +} diff --git a/plugins/quantum_computing/src/QuantumState.cpp b/plugins/quantum_computing/src/QuantumState.cpp index bd869c4..aaafbc7 100644 --- a/plugins/quantum_computing/src/QuantumState.cpp +++ b/plugins/quantum_computing/src/QuantumState.cpp @@ -2,16 +2,15 @@ const std::vector& QuantumState::getData() const { - return mState; + return mState; } std::string QuantumState::toString() const { - std::string out; - std::size_t count{ 0 }; - for (const auto& qubit : mState) - { - out += "|" + qubit.toString() + "\n"; - } - return out; -} \ No newline at end of file + std::string out; + for (const auto& qubit : mState) + { + out += "|" + qubit.toString() + "\n"; + } + return out; +} diff --git a/plugins/quantum_computing/src/QuantumState.h b/plugins/quantum_computing/src/QuantumState.h index ee96847..a50c5ed 100644 --- a/plugins/quantum_computing/src/QuantumState.h +++ b/plugins/quantum_computing/src/QuantumState.h @@ -8,15 +8,15 @@ class QuantumState { public: - void addValue(const Qubit& data) - { - mState.push_back(data); - } + void addValue(const Qubit& data) + { + mState.push_back(data); + } - const std::vector& getData() const; + const std::vector& getData() const; - std::string toString() const; + std::string toString() const; private: - std::vector mState; -}; \ No newline at end of file + std::vector mState; +}; diff --git a/plugins/quantum_computing/src/visuals/QuantumCircuitNode.cpp b/plugins/quantum_computing/src/visuals/QuantumCircuitNode.cpp index 5489b6c..e7044bb 100644 --- a/plugins/quantum_computing/src/visuals/QuantumCircuitNode.cpp +++ b/plugins/quantum_computing/src/visuals/QuantumCircuitNode.cpp @@ -9,6 +9,9 @@ #include "QuantumWireNode.h" #include "QuantumGateNode.h" +#include "LatexMathExpression.h" +#include "EquationNode.h" + QuantumCircuitNode::QuantumCircuitNode(const Transform& t) : AbstractVisualNode(t) { @@ -17,8 +20,8 @@ QuantumCircuitNode::QuantumCircuitNode(const Transform& t) void QuantumCircuitNode::setContent(QuantumCircuit* circuit) { - mContent = circuit; - mContentDirty = true; + mContent = circuit; + mContentDirty = true; } void QuantumCircuitNode::update(SceneInfo* sceneInfo) @@ -127,4 +130,4 @@ void QuantumCircuitNode::createOrUpdateGeometry(SceneInfo*) mWireNodes.push_back(std::move(wire_node)); } -} \ No newline at end of file +} diff --git a/plugins/quantum_computing/src/visuals/QuantumGateNode.cpp b/plugins/quantum_computing/src/visuals/QuantumGateNode.cpp index 835b042..1e18d72 100644 --- a/plugins/quantum_computing/src/visuals/QuantumGateNode.cpp +++ b/plugins/quantum_computing/src/visuals/QuantumGateNode.cpp @@ -7,7 +7,7 @@ #include "LatexMathExpression.h" QuantumGateNode::QuantumGateNode(const Transform& t) - : QuantumCircuitElementNode(t) + : QuantumCircuitElementNode(t) { } @@ -19,93 +19,93 @@ QuantumGateNode::~QuantumGateNode() void QuantumGateNode::setContent(QuantumGate* gate) { - mContent = gate; - mContentDirty = true; + mContent = gate; + mContentDirty = true; } void QuantumGateNode::update(SceneInfo* sceneInfo) { - if (mContentDirty) - { - createOrUpdateGeometry(sceneInfo); - mContentDirty = false; - } + if (mContentDirty) + { + createOrUpdateGeometry(sceneInfo); + mContentDirty = false; + } } -void QuantumGateNode::createOrUpdateGeometry(SceneInfo* sceneInfo) +void QuantumGateNode::createOrUpdateGeometry(SceneInfo*) { - if (!mBody) - { - mBody = std::make_unique(Point(0, 0), mBodyWidth, mBodyHeight); - addChild(mBody.get()); - } + if (!mBody) + { + mBody = std::make_unique(Point(0, 0), mBodyWidth, mBodyHeight); + addChild(mBody.get()); + } - if (!mLabel) - { - mLabel = std::make_unique(Point(mBodyWidth /3.0, mBodyHeight / 3.0)); + if (!mLabel) + { + mLabel = std::make_unique(Point(mBodyWidth /3.0, mBodyHeight / 3.0)); - std::string label_content; - if (mContent->getGateType() == QuantumGate::GateType::X) - { - label_content = "X"; - } - else if (mContent->getGateType() == QuantumGate::GateType::Y) - { - label_content = "Y"; - } - else if (mContent->getGateType() == QuantumGate::GateType::Z) - { - label_content = "Z"; - } - else if (mContent->getGateType() == QuantumGate::GateType::H) - { - label_content = "H"; - } - else - { - label_content = "U"; - } + std::string label_content; + if (mContent->getGateType() == QuantumGate::GateType::X) + { + label_content = "X"; + } + else if (mContent->getGateType() == QuantumGate::GateType::Y) + { + label_content = "Y"; + } + else if (mContent->getGateType() == QuantumGate::GateType::Z) + { + label_content = "Z"; + } + else if (mContent->getGateType() == QuantumGate::GateType::H) + { + label_content = "H"; + } + else + { + label_content = "U"; + } - mLabelExpression = std::make_unique(label_content); - mLabel->setContent(mLabelExpression.get()); - addChild(mLabel.get()); - } + mLabelExpression = std::make_unique(label_content); + mLabel->setContent(mLabelExpression.get()); + addChild(mLabel.get()); + } } Point QuantumGateNode::getConnectionLocation(AbstractQuantumWire* wire) const { - bool is_input{ false }; - std::size_t connection_id{ 0 }; + bool is_input{ false }; + //std::size_t connection_id{ 0 }; - for (std::size_t idx = 0; idx < mContent->getNumInputs(); idx++) - { - if (mContent->getInput(idx) == wire) - { - is_input = true; - connection_id = idx; - break; - } - } + for (std::size_t idx = 0; idx < mContent->getNumInputs(); idx++) + { + if (mContent->getInput(idx) == wire) + { + is_input = true; + //connection_id = idx; + break; + } + } - for (std::size_t idx = 0; idx < mContent->getNumOutputs(); idx++) - { - if (mContent->getOutput(idx) == wire) - { - connection_id = idx; - break; - } - } + for (std::size_t idx = 0; idx < mContent->getNumOutputs(); idx++) + { + if (mContent->getOutput(idx) == wire) + { + //connection_id = idx; + break; + } + } - Point loc; - if (is_input) - { - loc = Point(0.0, mBodyHeight/2.0); - } - else - { - loc = Point(mBodyWidth, mBodyHeight / 2.0); - } + Point loc; + if (is_input) + { + loc = Point(0.0, mBodyHeight/2.0); + } + else + { + loc = Point(mBodyWidth, mBodyHeight / 2.0); + } - loc.move(mTransform.getLocation().getX(), mTransform.getLocation().getY()); - return loc; -} \ No newline at end of file + loc.move(mTransform.getLocation().getX(), mTransform.getLocation().getY()); + return loc; +} diff --git a/plugins/quantum_computing/src/visuals/QuantumTerminalNode.cpp b/plugins/quantum_computing/src/visuals/QuantumTerminalNode.cpp index 09ad094..9a2f165 100644 --- a/plugins/quantum_computing/src/visuals/QuantumTerminalNode.cpp +++ b/plugins/quantum_computing/src/visuals/QuantumTerminalNode.cpp @@ -5,56 +5,56 @@ #include "LatexMathExpression.h" QuantumTerminalNode::QuantumTerminalNode(const Transform& transform) - : QuantumCircuitElementNode(transform) + : QuantumCircuitElementNode(transform) { } void QuantumTerminalNode::setContent(QuantumTerminal* terminal) { - mContent = terminal; - mContentDirty = true; + mContent = terminal; + mContentDirty = true; } void QuantumTerminalNode::update(SceneInfo* sceneInfo) { - if (mContentDirty) - { - createOrUpdateGeometry(sceneInfo); - mContentDirty = false; - } + if (mContentDirty) + { + createOrUpdateGeometry(sceneInfo); + mContentDirty = false; + } } -void QuantumTerminalNode::createOrUpdateGeometry(SceneInfo* sceneInfo) +void QuantumTerminalNode::createOrUpdateGeometry(SceneInfo*) { - if (!mLabel && mContent->getTerminalType() != QuantumTerminal::TerminalType::OUTPUT) - { - const auto value = mContent->getValue(); - std::string label; - if (value.isIn0State()) - { - label = "\\ket{0}"; - } - else if(value.isIn1State()) - { - label = "\\ket{1}"; - } - else - { - label = "\\Psi"; - } + if (!mLabel && mContent->getTerminalType() != QuantumTerminal::TerminalType::OUTPUT) + { + const auto value = mContent->getValue(); + std::string label; + if (value.isIn0State()) + { + label = "\\ket{0}"; + } + else if(value.isIn1State()) + { + label = "\\ket{1}"; + } + else + { + label = "\\Psi"; + } - mLabelExpression = std::make_unique(label); - mLabel = std::make_unique(); - mLabel->setContent(mLabelExpression.get()); + mLabelExpression = std::make_unique(label); + mLabel = std::make_unique(); + mLabel->setContent(mLabelExpression.get()); - addChild(mLabel.get()); - } + addChild(mLabel.get()); + } } Point QuantumTerminalNode::getConnectionLocation(AbstractQuantumWire*) const { - auto left = mTransform.getLocation(); - left.move(mWidth, mHeight/2.0); - return left; + auto left = mTransform.getLocation(); + left.move(mWidth, mHeight/2.0); + return left; } diff --git a/plugins/quantum_computing/src/visuals/QuantumWireNode.cpp b/plugins/quantum_computing/src/visuals/QuantumWireNode.cpp index 2729cb5..182b0fd 100644 --- a/plugins/quantum_computing/src/visuals/QuantumWireNode.cpp +++ b/plugins/quantum_computing/src/visuals/QuantumWireNode.cpp @@ -4,6 +4,7 @@ #include "LineNode.h" QuantumWireNode::QuantumWireNode(const Transform& t) + : AbstractVisualNode(t) { } @@ -46,7 +47,7 @@ void QuantumWireNode::update(SceneInfo* sceneInfo) } } -void QuantumWireNode::createOrUpdateGeometry(SceneInfo* sceneInfo) +void QuantumWireNode::createOrUpdateGeometry(SceneInfo*) { if (!mLine) { @@ -70,4 +71,4 @@ void QuantumWireNode::createOrUpdateGeometry(SceneInfo* sceneInfo) addChild(mLine.get()); } -} \ No newline at end of file +} diff --git a/plugins/quantum_computing/test/TestQuantumCircuitParsing.cpp b/plugins/quantum_computing/test/TestQuantumCircuitParsing.cpp index 1ecd7f4..70b2a0f 100644 --- a/plugins/quantum_computing/test/TestQuantumCircuitParsing.cpp +++ b/plugins/quantum_computing/test/TestQuantumCircuitParsing.cpp @@ -6,6 +6,12 @@ #include "QuantumCircuitNode.h" #include "QuantumCircuit.h" +#include "QuantumWireNode.h" +#include "QuantumGateNode.h" +#include "QuantumTerminalNode.h" +#include "EquationNode.h" +#include "LatexMathExpression.h" + TEST_CASE(TestQuantumCircuitParsing, "quantum_computing") { @@ -21,4 +27,4 @@ TEST_CASE(TestQuantumCircuitParsing, "quantum_computing") renderer.getScene()->addNode(node.get()); renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "circuit.svg"); -} \ No newline at end of file +} diff --git a/src/base/geometry/CMakeLists.txt b/src/base/geometry/CMakeLists.txt index 6b0ec53..385631c 100644 --- a/src/base/geometry/CMakeLists.txt +++ b/src/base/geometry/CMakeLists.txt @@ -3,6 +3,8 @@ set(MODULE_NAME geometry) list(APPEND HEADERS AbstractGeometricItem.h Bounds.h + Transform.h + Rotation.h grid/AbstractGrid.h grid/TypedGrid.h grid/Grid.h @@ -30,6 +32,7 @@ list(APPEND HEADERS ) list(APPEND SOURCES + Rotation.cpp Transform.cpp grid/AbstractGrid.cpp math/Linalg.cpp diff --git a/src/base/geometry/Rotation.cpp b/src/base/geometry/Rotation.cpp new file mode 100644 index 0000000..2dfd754 --- /dev/null +++ b/src/base/geometry/Rotation.cpp @@ -0,0 +1,31 @@ +#include "Rotation.h" + +Rotation::Rotation(double angle, Axis axis, const Point& loc, const Vector& customAxis) + : mAngle(angle), + mAxis(axis), + mPoint(loc), + mCustomAxis(customAxis), + mMatrix(3, 3) +{ + updateMatrix(); +} + +const Matrix& Rotation::getMatrix() const +{ + return mMatrix; +} + +bool Rotation::isIdentity() const +{ + return mMatrix.isIdentity(); +} + +bool Rotation::isEqual(const Rotation& rotation) const +{ + return mMatrix == rotation.mMatrix; +} + +void Rotation::updateMatrix() +{ + +} diff --git a/src/base/geometry/Rotation.h b/src/base/geometry/Rotation.h new file mode 100644 index 0000000..bef1948 --- /dev/null +++ b/src/base/geometry/Rotation.h @@ -0,0 +1,45 @@ +#pragma once + +#include "Point.h" +#include "Vector.h" +#include "Matrix.h" + +class Rotation +{ +public: + enum class Axis + { + X, + Y, + Z, + USER + }; + + Rotation(double angle = 0.0, Axis axis = Axis::Z, const Point& loc = {}, const Vector& customAxis = {}); + + const Matrix& getMatrix() const; + + bool isIdentity() const; + + bool isEqual(const Rotation& rotation) const; + + bool operator==(const Rotation& rhs) const + { + return isEqual(rhs); + } + + bool operator!=(const Rotation& rhs) const + { + return !operator==(rhs); + } + +private: + void updateMatrix(); + + double mAngle{ 0 }; + Axis mAxis{ Axis::Z }; + Point mPoint; + Vector mCustomAxis; + + Matrix mMatrix; +}; diff --git a/src/base/geometry/Transform.cpp b/src/base/geometry/Transform.cpp index 8eb9585..9b200bb 100644 --- a/src/base/geometry/Transform.cpp +++ b/src/base/geometry/Transform.cpp @@ -1,43 +1,92 @@ #include "Transform.h" -Transform::Transform(const Point& location, double scaleX, double scaleY, double scaleZ) - : mLocation(location), - mScaleX(scaleX), - mScaleY(scaleY), - mScaleZ(scaleZ) +Scale::Scale(double x, double y, double z) + : mX(x), + mY(y), + mZ(z) { } +bool Scale::isIdentity() const +{ + return mX == 1.0 && mY == 1.0 && mZ == 1.0; +} + +bool Scale::isEqual(const Scale& scale) const +{ + return mX == scale.mX && mY == scale.mY && mZ == scale.mZ; +} + +Transform::Transform(const Point& location, const Scale& scale, const Rotation& rotation) + : mLocation(location), + mScale(scale), + mRotation(rotation), + mMatrix(4, 4) +{ + +} + +void Transform::applyPre(const Transform& transform) +{ + mLocation.move(transform.getLocation().getX(), transform.getLocation().getY(), transform.getLocation().getZ()); + mScale *= transform.getScale(); +} + const Point& Transform::getLocation() const { return mLocation; } -double Transform::getScaleX() const +const Scale& Transform::getScale() const { - return mScaleX; + return mScale; } -double Transform::getScaleY() const +const Rotation& Transform::getRotation() const { - return mScaleY; + return mRotation; } -double Transform::getScaleZ() const +bool Transform::isEqual(const Transform& transform) const { - return mScaleZ; + return (mLocation == transform.mLocation) && (mScale == transform.mScale) && (mRotation == transform.mRotation); +} + +bool Transform::isIdentityTransform() const +{ + return mLocation.isAtOrigin() && mScale.isIdentity(); } void Transform::setLocation(const Point& loc) { - mLocation = loc; + if (mLocation != loc) + { + mLocation = loc; + updateMatrix(); + } } -void Transform::setScale(double scaleX, double scaleY, double scaleZ) +void Transform::setScale(const Scale& scale) { - mScaleX = scaleX; - mScaleY = scaleY; - mScaleZ = scaleZ; + if (mScale != scale) + { + mScale = scale; + updateMatrix(); + } +} + +void Transform::setRotation(const Rotation& rotation) +{ + if (mRotation != rotation) + { + mRotation = rotation; + updateMatrix(); + } +} + +void Transform::updateMatrix() +{ + +} -} \ No newline at end of file diff --git a/src/base/geometry/Transform.h b/src/base/geometry/Transform.h index 8a7143a..9940342 100644 --- a/src/base/geometry/Transform.h +++ b/src/base/geometry/Transform.h @@ -1,68 +1,65 @@ #pragma once -#include "Point.h" -#include "Vector.h" - -class Rotation -{ -public: - enum class Axis - { - X, - Y, - Z, - USER - }; - - - Rotation(double angle = 0.0, Axis axis = Axis::Z, const Point& loc = {}, const Vector& customAxis = {}) - { - - } - -private: - double mAngle{ 0 }; - Axis mAxis{ Axis::Z }; - Point mPoint; - Vector mCustomAxis; -}; +#include "Rotation.h" struct Scale { + Scale(double x = 1.0, double y = 1.0, double z = 1.0); + bool isIdentity() const; + + bool isEqual(const Scale& scale) const; + + void operator*=(const Scale& rhs) + { + mX *= rhs.mX; + mY *= rhs.mY; + mZ *= rhs.mZ; + } + + bool operator==(const Scale& rhs) const + { + return isEqual(rhs); + } + + bool operator!=(const Scale& rhs) const + { + return !operator==(rhs); + } + + double mX{1.0}; + double mY{1.0}; + double mZ{1.0}; }; class Transform { public: - Transform(const Point& location = {}, double scaleX = 1.0, double scaleY = 1.0, double scaleZ = 1.0); + Transform(const Point& location = {}, const Scale& scale = {}, const Rotation& rotation = {}); - void applyPre(const Transform& transform) - { - mLocation.move(transform.getLocation().getX(), transform.getLocation().getY(), transform.getLocation().getZ()); - mScaleX *= transform.getScaleX(); - mScaleY *= transform.getScaleY(); - mScaleZ *= transform.getScaleZ(); - } - - void setLocation(const Point& loc); - - void setScale(double scaleX, double scaleY = 1.0, double scaleZ = 1.0); + void applyPre(const Transform& transform); const Point& getLocation() const; - double getScaleX() const; + const Scale& getScale() const; - double getScaleY() const; + const Rotation& getRotation() const; - double getScaleZ() const; + const Matrix& getMatrix() const; + + bool isEqual(const Transform& transform) const; + + bool isIdentityTransform() const; + + void setLocation(const Point& loc); + + void setScale(const Scale& scale); + + void setRotation(const Rotation& rotation); bool operator==(const Transform& rhs) const { - return (mLocation == rhs.mLocation) - && (mScaleX == rhs.mScaleX) - && (mScaleY == rhs.mScaleY) - && (mScaleZ == rhs.mScaleZ); + return isEqual(rhs); } bool operator!=(const Transform& rhs) const @@ -70,24 +67,11 @@ public: return !operator==(rhs); } - bool hasDefaultLocation() const - { - return mLocation.getX() == 0.0 && mLocation.getY() == 0.0 && mLocation.getZ() == 0.0; - } - - bool hasDefaultScale() const - { - return mScaleX == 1.0 && mScaleY == 1.0 && mScaleZ == 1.0; - } - - bool isDefaultTransform() const - { - return hasDefaultLocation() && hasDefaultScale(); - } - private: + void updateMatrix(); + Point mLocation; - double mScaleX{1}; - double mScaleY{1}; - double mScaleZ{1}; + Scale mScale; + Rotation mRotation; + Matrix mMatrix; }; diff --git a/src/base/geometry/math/Matrix.cpp b/src/base/geometry/math/Matrix.cpp index e69de29..642a013 100644 --- a/src/base/geometry/math/Matrix.cpp +++ b/src/base/geometry/math/Matrix.cpp @@ -0,0 +1,66 @@ +#include "Matrix.h" + +#include +#include + +Matrix::Matrix(std::size_t numRows, std::size_t numColumns) + : mNumRows(numRows), + mNumColumns(numColumns) +{ + mData = std::vector(numRows * numColumns, 0.0); +} + +bool Matrix::isIdentity() const +{ + if (!isSquare()) + { + return false; + } + + for(std::size_t idx=0; idx= mData.size()) + { + throw std::range_error("Out of bounds array access: " + std::to_string(index) + " for size " + std::to_string(mData.size())); + } + return mData[getFlatIndex(rowId, columnId)]; +} + +bool Matrix::isSquare() const +{ + return mNumRows == mNumColumns; +} + +bool Matrix::isEqual(const Matrix& matrix) const +{ + return mData == matrix.mData; +} + +std::size_t Matrix::getFlatIndex(std::size_t rowId, std::size_t columnId) const +{ + return columnId + rowId*mNumColumns; +} diff --git a/src/base/geometry/math/Matrix.h b/src/base/geometry/math/Matrix.h index 96e247f..a308115 100644 --- a/src/base/geometry/math/Matrix.h +++ b/src/base/geometry/math/Matrix.h @@ -5,10 +5,30 @@ class Matrix { public: - Matrix(unsigned numRows, unsigned numColumns) - { - mData = std::vector(numRows * numColumns, 0.0); - } + Matrix(std::size_t numRows, std::size_t numColumns); + + std::size_t getFlatIndex(std::size_t rowId, std::size_t columnId) const; + + double getItem(std::size_t rowId, std::size_t columnId) const; + + bool isIdentity() const; + + bool isSquare() const; + + bool isEqual(const Matrix& matrix) const; + + bool operator==(const Matrix& rhs) const + { + return isEqual(rhs); + } + + bool operator!=(const Matrix& rhs) const + { + return !operator==(rhs); + } + private: - std::vector mData; -}; \ No newline at end of file + std::size_t mNumRows{0}; + std::size_t mNumColumns{0}; + std::vector mData; +}; diff --git a/src/base/geometry/points/Point.cpp b/src/base/geometry/points/Point.cpp index ad63b11..2ced173 100644 --- a/src/base/geometry/points/Point.cpp +++ b/src/base/geometry/points/Point.cpp @@ -79,15 +79,20 @@ double Point::getDeltaZ(const Point& point) const return point.getZ() - mZ; } +bool Point::isAtOrigin() const +{ + return mX == 0.0 && mY == 0.0 && mZ == 0.0; +} + void Point::apply(const Transform& transform) { mX -= transform.getLocation().getX(); mY -= transform.getLocation().getY(); mZ -= transform.getLocation().getZ(); - mX *= transform.getScaleX(); - mY *= transform.getScaleY(); - mZ *= transform.getScaleZ(); + mX *= transform.getScale().mX; + mY *= transform.getScale().mY; + mZ *= transform.getScale().mZ; } void Point::move(double x, double y, double z) diff --git a/src/base/geometry/points/Point.h b/src/base/geometry/points/Point.h index cd66be4..c5c2ffb 100644 --- a/src/base/geometry/points/Point.h +++ b/src/base/geometry/points/Point.h @@ -22,6 +22,8 @@ public: void apply(const Transform& transform); + bool isAtOrigin() const; + void move(double x, double y, double z = 0); double getX() const; diff --git a/src/base/network/CMakeLists.txt b/src/base/network/CMakeLists.txt index fcf5ad6..7cb13e4 100644 --- a/src/base/network/CMakeLists.txt +++ b/src/base/network/CMakeLists.txt @@ -7,10 +7,8 @@ if(UNIX) list(APPEND platform_INCLUDES sockets/BerkeleySocket.h sockets/BerkeleySocket.cpp - sockets/UnixSocketInterface.h - sockets/UnixSocketInterface.cpp - server/UnixSockerServer.h - server/UnixSockerServer.cpp + server/UnixSocketServer.h + server/UnixSocketServer.cpp client/unix/UnixSocketClient.h client/unix/UnixSocketClient.cpp ) @@ -45,7 +43,6 @@ list(APPEND HEADERS server/HttpServer.h server/PlatformSocketServer.h sockets/Socket.h - sockets/SocketInterface.h sockets/IPlatformSocket.h ) @@ -70,4 +67,4 @@ target_include_directories(${MODULE_NAME} PUBLIC set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) target_link_libraries( ${MODULE_NAME} PUBLIC core ${platform_LIBS}) -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base) \ No newline at end of file +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base) diff --git a/src/base/network/client/HttpClient.cpp b/src/base/network/client/HttpClient.cpp index e37eb26..7ea5de3 100644 --- a/src/base/network/client/HttpClient.cpp +++ b/src/base/network/client/HttpClient.cpp @@ -11,38 +11,38 @@ HttpClient::HttpClient() { #ifdef _WIN32 - mSocketClient = std::make_unique(); + mSocketClient = std::make_unique(); #else - mSocketClient = std::make_unique(); + mSocketClient = std::make_unique(); #endif } HttpResponse HttpClient::makeRequest(const HttpRequest& request, const Address& address) { - PlatformSocketClient::Address socket_address; - socket_address.mHost = address.mHost; - socket_address.mPort = address.mPort; - socket_address.mPrefix = address.mPrefix; + PlatformSocketClient::Address socket_address; + socket_address.mHost = address.mHost; + socket_address.mPort = address.mPort; + socket_address.mPrefix = address.mPrefix; - const auto message = request.toString(address.mHost); + const auto message = request.toString(address.mHost); - MLOG_INFO("Output http request: " << message); + MLOG_INFO("Output http request: " << message); - auto socket_response = mSocketClient->request(socket_address, message); + auto socket_response = mSocketClient->request(socket_address, message); - HttpResponse response; - if (socket_response.mStatus == PlatformSocketClient::Result::Status::OK) - { - response.fromMessage(socket_response.mBody); - } - else - { - MLOG_ERROR("Http request client error: " << socket_response.mErrorMessage << " | with code: " << socket_response.mErrorCode); + HttpResponse response; + if (socket_response.mStatus == PlatformSocketClient::Result::Status::OK) + { + response.fromMessage(socket_response.mBody); + } + else + { + MLOG_ERROR("Http request client error: " << socket_response.mErrorMessage << " | with code: " << socket_response.mErrorCode); - HttpResponse::ClientError error; - error.mMessage = socket_response.mErrorMessage; - error.mCode = socket_response.mErrorCode; - response.setClientError(error); - } - return response; -} \ No newline at end of file + HttpResponse::ClientError error; + error.mMessage = socket_response.mErrorMessage; + error.mCode = socket_response.mErrorCode; + response.setClientError(error); + } + return response; +} diff --git a/src/base/network/client/HttpClient.h b/src/base/network/client/HttpClient.h index eadfd6c..b689aca 100644 --- a/src/base/network/client/HttpClient.h +++ b/src/base/network/client/HttpClient.h @@ -9,16 +9,16 @@ class HttpClient { public: - struct Address - { - std::string mPrefix; - std::string mHost; - unsigned int mPort{ 8000 }; - }; + struct Address + { + std::string mPrefix; + std::string mHost; + unsigned int mPort{ 8000 }; + }; - HttpClient(); - HttpResponse makeRequest(const HttpRequest& request, const Address& address); + HttpClient(); + HttpResponse makeRequest(const HttpRequest& request, const Address& address); private: - std::unique_ptr mSocketClient; -}; \ No newline at end of file + std::unique_ptr mSocketClient; +}; diff --git a/src/base/network/client/unix/UnixSocketClient.cpp b/src/base/network/client/unix/UnixSocketClient.cpp index e69de29..32a3231 100644 --- a/src/base/network/client/unix/UnixSocketClient.cpp +++ b/src/base/network/client/unix/UnixSocketClient.cpp @@ -0,0 +1,32 @@ +#include "UnixSocketClient.h" + +UnixSocketClient::UnixSocketClient() +{ + +} + +UnixSocketClient::~UnixSocketClient() +{ + +} + +UnixSocketClient::Result UnixSocketClient::request(const Address& address, const std::string& message) +{ + UnixSocketClient::Result result; + + auto socket = std::make_unique(address.mHost, address.mPort); + auto response = socket->send(message); + + if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED) + { + result.mStatus = UnixSocketClient::Result::Status::OK; + result.mBody = response; + } + else + { + result.mStatus = UnixSocketClient::Result::Status::FAILED; + result.mErrorCode = socket->getState().mErrorCode; + result.mErrorMessage = socket->getState().mErrorMessage; + } + return result; +} diff --git a/src/base/network/client/unix/UnixSocketClient.h b/src/base/network/client/unix/UnixSocketClient.h index e69de29..0451d87 100644 --- a/src/base/network/client/unix/UnixSocketClient.h +++ b/src/base/network/client/unix/UnixSocketClient.h @@ -0,0 +1,17 @@ +#pragma once + +#include "BerkeleySocket.h" + +#include "PlatformSocketClient.h" + +#include + +class UnixSocketClient : public PlatformSocketClient +{ +public: + UnixSocketClient(); + + virtual ~UnixSocketClient(); + + Result request(const Address& address, const std::string& message); +}; diff --git a/src/base/network/client/win32/WinsockClient.cpp b/src/base/network/client/win32/WinsockClient.cpp index 29cac5f..088bc37 100644 --- a/src/base/network/client/win32/WinsockClient.cpp +++ b/src/base/network/client/win32/WinsockClient.cpp @@ -1,28 +1,28 @@ #include "WinsockClient.h" WinsockClient::WinsockClient() - : mSocketInterface(std::make_unique()) + : mSocketInterface(std::make_unique()) { - mSocketInterface->initializeWinsock(); + mSocketInterface->initializeWinsock(); } WinsockClient::Result WinsockClient::request(const Address& address, const std::string& message) { - WinsockClient::Result result; + WinsockClient::Result result; - auto socket = std::make_unique(address.mHost, address.mPort); - auto response = socket->send(message); + auto socket = std::make_unique(address.mHost, address.mPort); + auto response = socket->send(message); - if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED) - { - result.mStatus = WinsockClient::Result::Status::OK; - result.mBody = response; - } - else - { - result.mStatus = WinsockClient::Result::Status::FAILED; - result.mErrorCode = socket->getState().mErrorCode; - result.mErrorMessage = socket->getState().mErrorMessage; - } - return result; -} \ No newline at end of file + if (socket->getState().mConnectStatus != Socket::State::ConnectStatus::FAILED) + { + result.mStatus = WinsockClient::Result::Status::OK; + result.mBody = response; + } + else + { + result.mStatus = WinsockClient::Result::Status::FAILED; + result.mErrorCode = socket->getState().mErrorCode; + result.mErrorMessage = socket->getState().mErrorMessage; + } + return result; +} diff --git a/src/base/network/client/win32/WinsockClient.h b/src/base/network/client/win32/WinsockClient.h index a15601d..6d57c4f 100644 --- a/src/base/network/client/win32/WinsockClient.h +++ b/src/base/network/client/win32/WinsockClient.h @@ -10,10 +10,10 @@ class WinsockClient : public PlatformSocketClient { public: - WinsockClient(); + WinsockClient(); - Result request(const Address& address, const std::string& message); + Result request(const Address& address, const std::string& message); private: - std::unique_ptr mSocketInterface; -}; \ No newline at end of file + std::unique_ptr mSocketInterface; +}; diff --git a/src/base/network/server/UnixSocketServer.cpp b/src/base/network/server/UnixSocketServer.cpp index e69de29..05ba2cb 100644 --- a/src/base/network/server/UnixSocketServer.cpp +++ b/src/base/network/server/UnixSocketServer.cpp @@ -0,0 +1,70 @@ +#include "UnixSocketServer.h" + +#include "BerkeleySocket.h" + +#include "FileLogger.h" + +#include + +UnixSocketServer::~UnixSocketServer() +{ + +} + +void UnixSocketServer::listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) +{ + mConnectionCallback = connectionSuccessFunc; + mFailedCallback = connectionFailedFunc; + + auto server_socket = std::make_unique(address.mHost, address.mPort); + + auto on_connection = [this](int handle) + { + auto socket = std::make_unique(handle); + this->onConnection(std::move(socket)); + }; + server_socket->doListen(on_connection); + + if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED) + { + UnixSocketServer::Result result; + result.mStatus = UnixSocketServer::Result::Status::FAILED; + result.mErrorCode = server_socket->getState().mErrorCode; + result.mErrorMessage = server_socket->getState().mErrorMessage; + mFailedCallback(result); + } +} + +void UnixSocketServer::shutDown() +{ + mThreads.removeMarked(); + mThreads.joinAndClearAll(); +} + +void UnixSocketServer::onConnection(std::unique_ptr s) +{ + // House-keeping first - clean up any finished threads + MLOG_INFO("Before thread cleanup: " << mThreads.size()); + + mThreads.removeMarked(); + + MLOG_INFO("After thread cleanup: " << mThreads.size()); + + auto worker_func = [this](std::unique_ptr s) + { + MLOG_INFO("Spawned thread for new connection"); + + mConnectionCallback(s.get()); + + MLOG_INFO("Finished thread for new connection"); + this->onThreadComplete(std::this_thread::get_id()); + }; + + auto worker = std::make_unique(worker_func, std::move(s)); + mThreads.add(std::move(worker)); +}; + +void UnixSocketServer::onThreadComplete(std::thread::id id) +{ + mThreads.markForRemoval(id); +} diff --git a/src/base/network/server/UnixSocketServer.h b/src/base/network/server/UnixSocketServer.h index e69de29..e4b1d8a 100644 --- a/src/base/network/server/UnixSocketServer.h +++ b/src/base/network/server/UnixSocketServer.h @@ -0,0 +1,27 @@ +#pragma once + +#include "PlatformSocketServer.h" +#include "ThreadCollection.h" + +#include + +class BerkeleySocket; + +class UnixSocketServer : public PlatformSocketServer +{ +public: + virtual ~UnixSocketServer(); + + void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override; + + void shutDown() override; + +private: + void onConnection(std::unique_ptr clientHandle); + + void onThreadComplete(std::thread::id id); + + ThreadCollection mThreads; + onConnectionSuccessFunc mConnectionCallback; + onConnectionFailedFunc mFailedCallback; +}; diff --git a/src/base/network/server/WinsockServer.cpp b/src/base/network/server/WinsockServer.cpp index 67f30b1..0ebc81d 100644 --- a/src/base/network/server/WinsockServer.cpp +++ b/src/base/network/server/WinsockServer.cpp @@ -14,64 +14,64 @@ WinsockServer::~WinsockServer() void WinsockServer::listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) { - if (!mWinsockInterface) - { - mWinsockInterface = std::make_unique(); - mWinsockInterface->initializeWinsock(); - } + if (!mWinsockInterface) + { + mWinsockInterface = std::make_unique(); + mWinsockInterface->initializeWinsock(); + } - mConnectionCallback = connectionSuccessFunc; - mFailedCallback = connectionFailedFunc; + mConnectionCallback = connectionSuccessFunc; + mFailedCallback = connectionFailedFunc; - auto server_socket = std::make_unique(address.mHost, address.mPort); + auto server_socket = std::make_unique(address.mHost, address.mPort); - auto on_connection = [this](SOCKET handle) - { - auto socket = std::make_unique(handle); - this->onConnection(std::move(socket)); - }; - server_socket->doListen(on_connection); + auto on_connection = [this](SOCKET handle) + { + auto socket = std::make_unique(handle); + this->onConnection(std::move(socket)); + }; + server_socket->doListen(on_connection); - if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED) - { - WinsockServer::Result result; - result.mStatus = WinsockServer::Result::Status::FAILED; - result.mErrorCode = server_socket->getState().mErrorCode; - result.mErrorMessage = server_socket->getState().mErrorMessage; - mFailedCallback(result); - } + if (server_socket->getState().mBindStatus == Socket::State::BindStatus::FAILED) + { + WinsockServer::Result result; + result.mStatus = WinsockServer::Result::Status::FAILED; + result.mErrorCode = server_socket->getState().mErrorCode; + result.mErrorMessage = server_socket->getState().mErrorMessage; + mFailedCallback(result); + } } void WinsockServer::shutDown() { - mThreads.removeMarked(); - mThreads.joinAndClearAll(); + mThreads.removeMarked(); + mThreads.joinAndClearAll(); } void WinsockServer::onConnection(std::unique_ptr s) { - // House-keeping first - clean up any finished threads - MLOG_INFO("Before thread cleanup: " << mThreads.size()); + // House-keeping first - clean up any finished threads + MLOG_INFO("Before thread cleanup: " << mThreads.size()); - mThreads.removeMarked(); + mThreads.removeMarked(); - MLOG_INFO("After thread cleanup: " << mThreads.size()); + MLOG_INFO("After thread cleanup: " << mThreads.size()); - auto worker_func = [this](std::unique_ptr s) - { - MLOG_INFO("Spawned thread for new connection"); + auto worker_func = [this](std::unique_ptr s) + { + MLOG_INFO("Spawned thread for new connection"); - mConnectionCallback(s.get()); + mConnectionCallback(s.get()); - MLOG_INFO("Finished thread for new connection"); - this->onThreadComplete(std::this_thread::get_id()); - }; + MLOG_INFO("Finished thread for new connection"); + this->onThreadComplete(std::this_thread::get_id()); + }; - auto worker = std::make_unique(worker_func, std::move(s)); - mThreads.add(std::move(worker)); + auto worker = std::make_unique(worker_func, std::move(s)); + mThreads.add(std::move(worker)); }; void WinsockServer::onThreadComplete(std::thread::id id) { - mThreads.markForRemoval(id); -} \ No newline at end of file + mThreads.markForRemoval(id); +} diff --git a/src/base/network/server/WinsockServer.h b/src/base/network/server/WinsockServer.h index 0fe7ced..974a23b 100644 --- a/src/base/network/server/WinsockServer.h +++ b/src/base/network/server/WinsockServer.h @@ -12,20 +12,20 @@ class WinsockInterface; class WinsockServer : public PlatformSocketServer { public: - virtual ~WinsockServer(); + virtual ~WinsockServer(); - void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override; + void listen(const Address& address, onConnectionSuccessFunc connectionSuccessFunc, onConnectionFailedFunc connectionFailedFunc) override; - void shutDown() override; + void shutDown() override; private: - void onConnection(std::unique_ptr clientHandle); + void onConnection(std::unique_ptr clientHandle); - void onThreadComplete(std::thread::id id); + void onThreadComplete(std::thread::id id); - ThreadCollection mThreads; - onConnectionSuccessFunc mConnectionCallback; - onConnectionFailedFunc mFailedCallback; + ThreadCollection mThreads; + onConnectionSuccessFunc mConnectionCallback; + onConnectionFailedFunc mFailedCallback; - std::unique_ptr mWinsockInterface; -}; \ No newline at end of file + std::unique_ptr mWinsockInterface; +}; diff --git a/src/base/network/sockets/BerkeleySocket.cpp b/src/base/network/sockets/BerkeleySocket.cpp index e69de29..6e661e0 100644 --- a/src/base/network/sockets/BerkeleySocket.cpp +++ b/src/base/network/sockets/BerkeleySocket.cpp @@ -0,0 +1,184 @@ +#include "BerkeleySocket.h" + +#include "FileLogger.h" + +#include +#include +#include +#include +#include +#include + +BerkeleySocket::BerkeleySocket(const std::string& address, unsigned port) + : Socket(address, port) +{ + +} + +BerkeleySocket::BerkeleySocket(int handle) + : Socket("", 0), + mHandle(handle) +{ + mState.mConnectStatus = State::ConnectStatus::OK; +} + +BerkeleySocket::~BerkeleySocket() +{ + MLOG_INFO("Socket being destroyed"); +} + +void BerkeleySocket::initialize() +{ + mHandle = ::socket(AF_INET, SOCK_STREAM, 0); +} + +void BerkeleySocket::initializeForBind() +{ + +} + +void BerkeleySocket::doConnect() +{ + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + + ::inet_aton(mAddress.c_str(), &serv_addr.sin_addr); + serv_addr.sin_port = ::htons(mPort); + + int result = ::connect(mHandle, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + if( result < 0) + { + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + mState.mErrorCode = result; + mState.mErrorMessage = "Socket: Unable to connect to server."; + return; + } + mState.mConnectStatus = Socket::State::ConnectStatus::OK; +} + +void BerkeleySocket::doBind() +{ + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(mPort); + + int result = ::bind(mHandle, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + if (result< 0) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = result; + mState.mErrorMessage = "Socket: Unable to bind socket"; + return; + } + mState.mBindStatus = Socket::State::BindStatus::OK; +} + +void BerkeleySocket::doListen(onIncomingConnectionFunc connectionFunc) +{ + initializeForBind(); + if (mState.mBindStatus == Socket::State::BindStatus::FAILED) + { + return; + } + + doBind(); + if (mState.mBindStatus == Socket::State::BindStatus::FAILED) + { + return; + } + + ::listen(mHandle, 5); + + struct sockaddr_in cli_addr; + socklen_t clilen = sizeof(cli_addr); + while(true) + { + const auto new_socket_handle = ::accept(mHandle, (struct sockaddr *) &cli_addr, &clilen); + if (new_socket_handle < 0) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = new_socket_handle; + mState.mErrorMessage = "Socket: Accept failed"; + ::close(mHandle); + return; + } + connectionFunc(new_socket_handle); + } +} + +std::string BerkeleySocket::send(const std::string& message) +{ + if (mState.mConnectStatus != Socket::State::ConnectStatus::OK) + { + initialize(); + if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) + { + return {}; + } + + doConnect(); + if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) + { + return {}; + } + } + + auto n = ::write(mHandle, message.c_str(), message.length()); + if (n < 0) + { + onSockerError("Socket: Send failed."); + return{}; + } + + std::string response; + while (mState.mConnectStatus == Socket::State::ConnectStatus::OK) + { + response += recieve(); + } + ::close(mHandle); + + return response; +} + +void BerkeleySocket::respond(const std::string& message) +{ + auto result = ::write(mHandle, message.c_str(), static_cast(message.size())); + (void)result; +} + +void BerkeleySocket::onSockerError(const std::string& message) +{ + mState.mErrorCode = -1; + mState.mErrorMessage = message; + + if (mState.mConnectStatus == Socket::State::ConnectStatus::OK) + { + ::close(mHandle); + } + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; +} + +std::string BerkeleySocket::recieve() +{ + const int BUFFER_SIZE = 512; + char buffer[BUFFER_SIZE]; + auto result = ::read(mHandle, buffer, BUFFER_SIZE); + if (result > 0) + { + return std::string(buffer); + } + else if (result == 0) + { + mState.mConnectStatus = Socket::State::ConnectStatus::UNSET; + } + else + { + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + mState.mErrorCode = result; + mState.mErrorMessage = "Socket: read failed."; + } + return {}; +} diff --git a/src/base/network/sockets/BerkeleySocket.h b/src/base/network/sockets/BerkeleySocket.h index e69de29..da27037 100644 --- a/src/base/network/sockets/BerkeleySocket.h +++ b/src/base/network/sockets/BerkeleySocket.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Socket.h" + +#include +#include + +class BerkeleySocket : public Socket +{ +public: + BerkeleySocket(const std::string& address, unsigned port); + + BerkeleySocket(int handle); + + ~BerkeleySocket(); + + std::string recieve() override; + + void respond(const std::string& message) override; + + std::string send(const std::string& message) override; + + using onIncomingConnectionFunc = std::function; + void doListen(onIncomingConnectionFunc connectionFunc); + +private: + void initialize() override; + void initializeForBind() override; + + void doConnect() override; + + void doBind() override; + + void onSockerError(const std::string& message); + + int mHandle{ 0 }; +}; diff --git a/src/base/network/sockets/SocketInterface.h b/src/base/network/sockets/SocketInterface.h deleted file mode 100644 index ccd31c3..0000000 --- a/src/base/network/sockets/SocketInterface.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -class Socket; -using SocketPtr = std::unique_ptr; - -class ISocketInterface -{ -public: - ISocketInterface() = default; - - virtual ~ISocketInterface() = default; -}; - -using ISocketInterfaceUPtr = std::unique_ptr; diff --git a/src/base/network/sockets/UnixSocketInterface.cpp b/src/base/network/sockets/UnixSocketInterface.cpp deleted file mode 100644 index 016a8c8..0000000 --- a/src/base/network/sockets/UnixSocketInterface.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "UnixSocketInterface.h" - -#include "HttpResponse.h" -#include "HttpMessageHandler.h" - -#include "FileLogger.h" - -#include -#include -#include -#include -#include -#include -#include - -UnixSocketInterface::UnixSocketInterface() -{ - mMessageHandler = std::make_unique(); -} - -std::unique_ptr UnixSocketInterface::Create() -{ - return std::make_unique(); -} - -UnixSocketInterface::~UnixSocketInterface() -{ - -} - -void UnixSocketInterface::initializeSocket(const SocketPtr& socketPtr, const std::string& address) -{ - auto handle = ::socket(AF_INET, SOCK_STREAM, 0); - socketPtr->setHandle(handle); - - if (!address.empty()) - { - socketPtr->setAddress(address); - } -} - -void UnixSocketInterface::socketWrite(const SocketPtr& socket, const std::string& message) -{ - if(socket->getHandle() < 0) - { - MLOG_ERROR("Error opening socket" ); - return; - } - - const auto port = static_cast(socket->getPort()); - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - - inet_aton(socket->getAddress().c_str(), &serv_addr.sin_addr); - serv_addr.sin_port = htons(port); - - int result = connect(socket->getHandle(), (struct sockaddr *)&serv_addr, sizeof(serv_addr)); - if(result< 0) - { - MLOG_ERROR("Error connecting to socket" ); - return; - } - - auto n = write(socket->getHandle(), message.c_str(), message.length()); - if (n < 0) - { - std::cerr << "Error on write" << std::endl; - return; - } - - char buffer[BUFFER_SIZE] = {0}; - int res = read(socket->getHandle(), buffer, BUFFER_SIZE); - if (res < 0) - { - std::cerr << "Error on read" << std::endl; - return; - } - socket->setMessage(buffer); - std::cout << "Here is the message: " << buffer << std::endl; -} - -void UnixSocketInterface::socketListen(const SocketPtr& socket) -{ - if(socket->getHandle() < 0) - { - std::cerr << "Error opening socket" << std::endl; - return; - } - - const auto port = static_cast(socket->getPort()); - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(port); - - int result = bind(socket->getHandle(), (struct sockaddr *)&serv_addr, sizeof(serv_addr)); - if(result< 0) - { - std::cerr << "Error binding socket" << std::endl; - return; - } - - listen(socket->getHandle(), 5); -} - -void UnixSocketInterface::run(const SocketPtr& socket) -{ - if(socket->getHandle() < 0) - { - std::cerr << "Error opening socket" << std::endl; - return; - } - - struct sockaddr_in cli_addr; - socklen_t clilen = sizeof(cli_addr); - while(true) - { - const auto new_socket_handle = accept(socket->getHandle(), (struct sockaddr *) &cli_addr, &clilen); - if (new_socket_handle < 0) - { - std::cerr << "Error on accept" << std::endl; - return; - } - - char buffer[BUFFER_SIZE] = {0}; - int n = read(new_socket_handle, buffer, BUFFER_SIZE); - if (n < 0) - { - std::cerr << "Error on read" << std::endl; - return; - } - socket->setMessage(buffer); - std::cout << "Here is the message: " << buffer << std::endl; - - const auto response = mMessageHandler->onMessage(buffer); - n = write(new_socket_handle, response.c_str(), response.length()); - if (n < 0) - { - std::cerr << "Error on write" << std::endl; - return; - } - close(new_socket_handle); - } -} diff --git a/src/base/network/sockets/UnixSocketInterface.h b/src/base/network/sockets/UnixSocketInterface.h deleted file mode 100644 index 3204006..0000000 --- a/src/base/network/sockets/UnixSocketInterface.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "Socket.h" -#include "SocketInterface.h" - -#include -#include - -class ISocketMessageHandler; - -class UnixSocketInterface : public ISocketInterface -{ -public: - UnixSocketInterface(); - - virtual ~UnixSocketInterface(); - - static std::unique_ptr Create(); - - void initializeSocket(const SocketPtr& socket, const std::string& address = {}) override; - - void socketListen(const SocketPtr& socket) override; - - void socketWrite(const SocketPtr& socket, const std::string& message) override; - - void run(const SocketPtr& socket) override; - -private: - static constexpr unsigned BUFFER_SIZE{1024}; - std::unique_ptr mMessageHandler; -}; - -using UnixSocketInterfacePtr = std::unique_ptr; diff --git a/src/base/network/sockets/WinsockInterface.h b/src/base/network/sockets/WinsockInterface.h index ce64a00..492223b 100644 --- a/src/base/network/sockets/WinsockInterface.h +++ b/src/base/network/sockets/WinsockInterface.h @@ -1,8 +1,6 @@ #pragma once -#include "SocketInterface.h" - -class WinsockInterface : public ISocketInterface +class WinsockInterface { public: ~WinsockInterface(); @@ -10,4 +8,4 @@ public: bool initializeWinsock(); void closeWinsock(); -}; \ No newline at end of file +}; diff --git a/src/base/network/sockets/WinsockSocket.cpp b/src/base/network/sockets/WinsockSocket.cpp index 7cb0a68..e53e6c9 100644 --- a/src/base/network/sockets/WinsockSocket.cpp +++ b/src/base/network/sockets/WinsockSocket.cpp @@ -6,240 +6,240 @@ #include "FileLogger.h" WinsockSocket::WinsockSocket(const std::string& address, unsigned port) - : Socket(address, port) + : Socket(address, port) { } WinsockSocket::WinsockSocket(SOCKET handle) - : Socket("", 0), - mHandle(handle) + : Socket("", 0), + mHandle(handle) { - mState.mConnectStatus = State::ConnectStatus::OK; + mState.mConnectStatus = State::ConnectStatus::OK; } WinsockSocket::~WinsockSocket() { - MLOG_INFO("Socket being destroyed"); + MLOG_INFO("Socket being destroyed"); } void WinsockSocket::initialize() { - addrinfo hints; - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; + addrinfo hints; + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - auto result = ::getaddrinfo(mAddress.c_str(), std::to_string(mPort).c_str(), &hints, &mAddressInfo); - if (result != 0) - { - mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; - mState.mErrorCode = result; - mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for connect"; - return; - } + auto result = ::getaddrinfo(mAddress.c_str(), std::to_string(mPort).c_str(), &hints, &mAddressInfo); + if (result != 0) + { + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + mState.mErrorCode = result; + mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for connect"; + return; + } - mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol); - if (mHandle == INVALID_SOCKET) - { - onSockerError("WinsockSocket: Error at socket()"); - ::freeaddrinfo(mAddressInfo); - return; - } + mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol); + if (mHandle == INVALID_SOCKET) + { + onSockerError("WinsockSocket: Error at socket()"); + ::freeaddrinfo(mAddressInfo); + return; + } } void WinsockSocket::initializeForBind() { - addrinfo hints; - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; + addrinfo hints; + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; - // https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 - auto result = ::getaddrinfo(nullptr, std::to_string(mPort).c_str(), &hints, &mAddressInfo); - if (result != 0) - { - mState.mBindStatus = Socket::State::BindStatus::FAILED; - mState.mErrorCode = result; - mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for bind"; - return; - } + // https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 + auto result = ::getaddrinfo(nullptr, std::to_string(mPort).c_str(), &hints, &mAddressInfo); + if (result != 0) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = result; + mState.mErrorMessage = "WinsockSocket: getaddrinfo failed for bind"; + return; + } - mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol); - if (mHandle == INVALID_SOCKET) - { - onSockerError("WinsockSocket: Error at socket()"); - ::freeaddrinfo(mAddressInfo); - return; - } + mHandle = ::socket(mAddressInfo->ai_family, mAddressInfo->ai_socktype, mAddressInfo->ai_protocol); + if (mHandle == INVALID_SOCKET) + { + onSockerError("WinsockSocket: Error at socket()"); + ::freeaddrinfo(mAddressInfo); + return; + } } void WinsockSocket::doConnect() { - auto result = ::connect(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen); - if (result == SOCKET_ERROR) - { - ::closesocket(mHandle); - mHandle = INVALID_SOCKET; - } + auto result = ::connect(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen); + if (result == SOCKET_ERROR) + { + ::closesocket(mHandle); + mHandle = INVALID_SOCKET; + } - ::freeaddrinfo(mAddressInfo); + ::freeaddrinfo(mAddressInfo); - if (mHandle == INVALID_SOCKET) - { - mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; - mState.mErrorCode = SOCKET_ERROR; - mState.mErrorMessage = "WinsockSocket: Unable to connect to server."; - return; - } - mState.mConnectStatus = Socket::State::ConnectStatus::OK; + if (mHandle == INVALID_SOCKET) + { + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + mState.mErrorCode = SOCKET_ERROR; + mState.mErrorMessage = "WinsockSocket: Unable to connect to server."; + return; + } + mState.mConnectStatus = Socket::State::ConnectStatus::OK; } void WinsockSocket::doBind() { - auto result = ::bind(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen); - if (result == SOCKET_ERROR) - { - ::closesocket(mHandle); - mHandle = INVALID_SOCKET; - } + auto result = ::bind(mHandle, mAddressInfo->ai_addr, (int)mAddressInfo->ai_addrlen); + if (result == SOCKET_ERROR) + { + ::closesocket(mHandle); + mHandle = INVALID_SOCKET; + } - ::freeaddrinfo(mAddressInfo); + ::freeaddrinfo(mAddressInfo); - if (mHandle == INVALID_SOCKET) - { - mState.mBindStatus = Socket::State::BindStatus::FAILED; - mState.mErrorCode = ::WSAGetLastError(); - mState.mErrorMessage = "WinsockSocket: Unable to bind socket"; - return; - } - mState.mBindStatus = Socket::State::BindStatus::OK; + if (mHandle == INVALID_SOCKET) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = ::WSAGetLastError(); + mState.mErrorMessage = "WinsockSocket: Unable to bind socket"; + return; + } + mState.mBindStatus = Socket::State::BindStatus::OK; } void WinsockSocket::doListen(onIncomingConnectionFunc connectionFunc) { - initializeForBind(); - if (mState.mBindStatus == Socket::State::BindStatus::FAILED) - { - return; - } + initializeForBind(); + if (mState.mBindStatus == Socket::State::BindStatus::FAILED) + { + return; + } - doBind(); - if (mState.mBindStatus == Socket::State::BindStatus::FAILED) - { - return; - } + doBind(); + if (mState.mBindStatus == Socket::State::BindStatus::FAILED) + { + return; + } - if (::listen(mHandle, SOMAXCONN) == SOCKET_ERROR) - { - mState.mBindStatus = Socket::State::BindStatus::FAILED; - mState.mErrorCode = ::WSAGetLastError(); - mState.mErrorMessage = "WinsockSocket: Listen failed"; - ::closesocket(mHandle); - return; - } + if (::listen(mHandle, SOMAXCONN) == SOCKET_ERROR) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = ::WSAGetLastError(); + mState.mErrorMessage = "WinsockSocket: Listen failed"; + ::closesocket(mHandle); + return; + } - while (true) - { - auto client_handle = ::accept(mHandle, NULL, NULL); - if (client_handle == INVALID_SOCKET) - { - mState.mBindStatus = Socket::State::BindStatus::FAILED; - mState.mErrorCode = ::WSAGetLastError(); - mState.mErrorMessage = "WinsockSocket: Accept failed"; - ::closesocket(mHandle); - break; - } - else - { - connectionFunc(client_handle); - } - } + while (true) + { + auto client_handle = ::accept(mHandle, NULL, NULL); + if (client_handle == INVALID_SOCKET) + { + mState.mBindStatus = Socket::State::BindStatus::FAILED; + mState.mErrorCode = ::WSAGetLastError(); + mState.mErrorMessage = "WinsockSocket: Accept failed"; + ::closesocket(mHandle); + break; + } + else + { + connectionFunc(client_handle); + } + } } std::string WinsockSocket::send(const std::string& message) { - if (mState.mConnectStatus != Socket::State::ConnectStatus::OK) - { - initialize(); - if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) - { - return {}; - } + if (mState.mConnectStatus != Socket::State::ConnectStatus::OK) + { + initialize(); + if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) + { + return {}; + } - doConnect(); - if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) - { - return {}; - } - } + doConnect(); + if (mState.mConnectStatus == Socket::State::ConnectStatus::FAILED) + { + return {}; + } + } - auto result = ::send(mHandle, message.c_str(), static_cast(message.size()), 0); - if (result == SOCKET_ERROR) - { - onSockerError("WinsockSocket: Send failed."); - return {}; - } + auto result = ::send(mHandle, message.c_str(), static_cast(message.size()), 0); + if (result == SOCKET_ERROR) + { + onSockerError("WinsockSocket: Send failed."); + return {}; + } - result = ::shutdown(mHandle, SD_SEND); - if (result == SOCKET_ERROR) - { - onSockerError("WinsockSocket: Post send shutdown failed."); - return {}; - } + result = ::shutdown(mHandle, SD_SEND); + if (result == SOCKET_ERROR) + { + onSockerError("WinsockSocket: Post send shutdown failed."); + return {}; + } - std::string response; - while (mState.mConnectStatus == Socket::State::ConnectStatus::OK) - { - response += recieve(); - } - ::closesocket(mHandle); + std::string response; + while (mState.mConnectStatus == Socket::State::ConnectStatus::OK) + { + response += recieve(); + } + ::closesocket(mHandle); - return response; + return response; } void WinsockSocket::respond(const std::string& message) { - auto result = ::send(mHandle, message.c_str(), static_cast(message.size()), 0); - if (result == SOCKET_ERROR) - { - onSockerError("WinsockSocket: Respond failed."); - } + auto result = ::send(mHandle, message.c_str(), static_cast(message.size()), 0); + if (result == SOCKET_ERROR) + { + onSockerError("WinsockSocket: Respond failed."); + } } void WinsockSocket::onSockerError(const std::string& message) { - mState.mErrorCode = ::WSAGetLastError(); - mState.mErrorMessage = message; + mState.mErrorCode = ::WSAGetLastError(); + mState.mErrorMessage = message; - if (mState.mConnectStatus == Socket::State::ConnectStatus::OK) - { - ::closesocket(mHandle); - } - mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + if (mState.mConnectStatus == Socket::State::ConnectStatus::OK) + { + ::closesocket(mHandle); + } + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; } std::string WinsockSocket::recieve() { - const int BUFFER_SIZE = 512; - char buffer[BUFFER_SIZE]; - auto result = ::recv(mHandle, buffer, BUFFER_SIZE, 0); - if (result > 0) - { - return std::string(buffer); - } - else if (result == 0) - { - mState.mConnectStatus = Socket::State::ConnectStatus::UNSET; - } - else - { - mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; - mState.mErrorCode = ::WSAGetLastError(); - mState.mErrorMessage = "WinsockSocket: recv failed."; - } - return {}; + const int BUFFER_SIZE = 512; + char buffer[BUFFER_SIZE]; + auto result = ::recv(mHandle, buffer, BUFFER_SIZE, 0); + if (result > 0) + { + return std::string(buffer); + } + else if (result == 0) + { + mState.mConnectStatus = Socket::State::ConnectStatus::UNSET; + } + else + { + mState.mConnectStatus = Socket::State::ConnectStatus::FAILED; + mState.mErrorCode = ::WSAGetLastError(); + mState.mErrorMessage = "WinsockSocket: recv failed."; + } + return {}; } diff --git a/src/base/network/sockets/WinsockSocket.h b/src/base/network/sockets/WinsockSocket.h index d23fc3b..df92c6d 100644 --- a/src/base/network/sockets/WinsockSocket.h +++ b/src/base/network/sockets/WinsockSocket.h @@ -9,32 +9,32 @@ class WinsockSocket : public Socket { public: - WinsockSocket(const std::string& address, unsigned port); + WinsockSocket(const std::string& address, unsigned port); - WinsockSocket(SOCKET handle); + WinsockSocket(SOCKET handle); - ~WinsockSocket(); + ~WinsockSocket(); - std::string recieve() override; + std::string recieve() override; - void respond(const std::string& message) override; + void respond(const std::string& message) override; - std::string send(const std::string& message) override; + std::string send(const std::string& message) override; - using onIncomingConnectionFunc = std::function; - void doListen(onIncomingConnectionFunc connectionFunc); + using onIncomingConnectionFunc = std::function; + void doListen(onIncomingConnectionFunc connectionFunc); private: - void initialize() override; - void initializeForBind() override; + void initialize() override; + void initializeForBind() override; - void doConnect() override; + void doConnect() override; - void doBind() override; + void doBind() override; - void onSockerError(const std::string& message); + void onSockerError(const std::string& message); - SOCKET mHandle{ INVALID_SOCKET }; + SOCKET mHandle{ INVALID_SOCKET }; - addrinfo* mAddressInfo{ nullptr }; -}; \ No newline at end of file + addrinfo* mAddressInfo{ nullptr }; +}; diff --git a/src/publishing/latex/LatexMathExpression.cpp b/src/publishing/latex/LatexMathExpression.cpp index 949bf60..d80f484 100644 --- a/src/publishing/latex/LatexMathExpression.cpp +++ b/src/publishing/latex/LatexMathExpression.cpp @@ -3,15 +3,15 @@ #include "FileLogger.h" LatexMathExpression::LatexMathExpression(const std::string& expression) - : mRawBody(expression), - mType(Type::LINEAR) + : mRawBody(expression), + mType(Type::LINEAR) { - MLOG_INFO("Adding expression with content: " << expression); - parse(); + MLOG_INFO("Adding expression with content: " << expression); + parse(); } LatexMathExpression::LatexMathExpression(Type type) - : mType(type) + : mType(type) { } @@ -23,150 +23,150 @@ LatexMathExpression::~LatexMathExpression() const LatexMathSymbol& LatexMathExpression::getLeftSymbol() const { - return mLeftSymbol; + return mLeftSymbol; } const LatexMathSymbol& LatexMathExpression::getRightSymbol() const { - return mRightSymbol; + return mRightSymbol; } void LatexMathExpression::setLeftSymbol(const LatexMathSymbol& symbol) { - mLeftSymbol = symbol; + mLeftSymbol = symbol; } void LatexMathExpression::setRightSymbol(const LatexMathSymbol& symbol) { - mRightSymbol = symbol; + mRightSymbol = symbol; } void LatexMathExpression::onTagBodyChar(char c) { - if (c == '}') - { - onRBrace(); - } - else - { - mWorkingString += c; - } + if (c == '}') + { + onRBrace(); + } + else + { + mWorkingString += c; + } } void LatexMathExpression::onFreeChar(char c) { - if (c == '\\') - { - mLineState = LineState::IN_TAG_NAME; - } - else if (c == '{') - { - onLBrace(); - } - else if (c == '}') - { - onRBrace(); - } - else if (c == '^') - { - onSuperscript(); - } - else if (c == '_') - { - onSubscript(); - } - else if (std::isblank(c)) - { - onSpace(); - } - else - { - mWorkingString += c; - } + if (c == '\\') + { + mLineState = LineState::IN_TAG_NAME; + } + else if (c == '{') + { + onLBrace(); + } + else if (c == '}') + { + onRBrace(); + } + else if (c == '^') + { + onSuperscript(); + } + else if (c == '_') + { + onSubscript(); + } + else if (std::isblank(c)) + { + onSpace(); + } + else + { + mWorkingString += c; + } } void LatexMathExpression::parse() { - mLineState = LineState::NONE; - mWorkingString.clear(); + mLineState = LineState::NONE; + mWorkingString.clear(); - for (auto c : mRawBody) - { - if (mLineState == LineState::IN_TAG_BODY) - { - onTagBodyChar(c); - } - else - { - onFreeChar(c); - } - } - onSpace(); - onCloseExpression(); + for (auto c : mRawBody) + { + if (mLineState == LineState::IN_TAG_BODY) + { + onTagBodyChar(c); + } + else + { + onFreeChar(c); + } + } + onSpace(); + onCloseExpression(); } void LatexMathExpression::onSpace() { - if (mLineState == LineState::IN_TAG_NAME) - { - onFinishedTagName(); - } - else - { - onLiteral(); - } - mWorkingString.clear(); + if (mLineState == LineState::IN_TAG_NAME) + { + onFinishedTagName(); + } + else + { + onLiteral(); + } + mWorkingString.clear(); } void LatexMathExpression::onLBrace() { - if (mLineState == LineState::IN_TAG_NAME) - { - onFinishedTagName(); - } - else if (mLineState == LineState::AWAITING_LBRACE) - { - mLineState = LineState::IN_TAG_BODY; - } - else if (mLineState == LineState::IN_TAG_BODY) - { - mOpenBraceCount++; - } - else - { - mWorkingString += "{"; - } + if (mLineState == LineState::IN_TAG_NAME) + { + onFinishedTagName(); + } + else if (mLineState == LineState::AWAITING_LBRACE) + { + mLineState = LineState::IN_TAG_BODY; + } + else if (mLineState == LineState::IN_TAG_BODY) + { + mOpenBraceCount++; + } + else + { + mWorkingString += "{"; + } } void LatexMathExpression::onRBrace() { - if (mLineState == LineState::IN_TAG_BODY) - { - if (mOpenBraceCount == 0) - { - onTagBody(); - } - else - { - mOpenBraceCount--; - mWorkingString += "}"; - } - } - else - { - mWorkingString += "}"; - } + if (mLineState == LineState::IN_TAG_BODY) + { + if (mOpenBraceCount == 0) + { + onTagBody(); + } + else + { + mOpenBraceCount--; + mWorkingString += "}"; + } + } + else + { + mWorkingString += "}"; + } } void LatexMathExpression::setRawContent(const std::string& content) { - auto expression = std::make_unique(content); - mExpressions.push_back(std::move(expression)); + auto expression = std::make_unique(content); + mExpressions.push_back(std::move(expression)); } void LatexMathExpression::onTagBody() { - onCloseExpression(); + onCloseExpression(); } void LatexMathExpression::onSuperscript() @@ -181,127 +181,127 @@ void LatexMathExpression::onSubscript() void LatexMathExpression::onLiteral() { - LatexMathSymbol symbol{ LatexMathSymbol::Type::RAW, mWorkingString, mWorkingString }; - mWorkingSymbols.push_back(symbol); + LatexMathSymbol symbol{ LatexMathSymbol::Type::RAW, mWorkingString, mWorkingString }; + mWorkingSymbols.push_back(symbol); } void LatexMathExpression::onFinishedTagName() { - if (auto lookup = LatexSymbolLookup::getKnownTag(mWorkingString); lookup) - { - if (mLineState == LineState::AWAITING_LBRACE || mLineState == LineState::IN_TAG_NAME) - { - onCloseExpression(); + if (auto lookup = LatexSymbolLookup::getKnownTag(mWorkingString); lookup) + { + if (mLineState == LineState::AWAITING_LBRACE || mLineState == LineState::IN_TAG_NAME) + { + onCloseExpression(); - if (*lookup == LatexMathSymbol::Tag::FRAC) - { - onFracTag(); - mWorkingString.clear(); - } - else if (auto tag_type = LatexSymbolLookup::getTagType(*lookup); tag_type == LatexMathSymbol::Type::ENCLOSING_TAG) - { - onEnclosingTag(*lookup); - } - mLineState = LineState::IN_TAG_BODY; - } - } - else if (auto lookup = LatexSymbolLookup::getSymbolUtf8(mWorkingString); lookup) - { - LatexMathSymbol symbol{ LatexMathSymbol::Type::TAG, mWorkingString, *lookup }; - mWorkingSymbols.push_back(symbol); - mLineState = LineState::NONE; - } + if (*lookup == LatexMathSymbol::Tag::FRAC) + { + onFracTag(); + mWorkingString.clear(); + } + else if (auto tag_type = LatexSymbolLookup::getTagType(*lookup); tag_type == LatexMathSymbol::Type::ENCLOSING_TAG) + { + onEnclosingTag(*lookup); + } + mLineState = LineState::IN_TAG_BODY; + } + } + else if (auto lookup = LatexSymbolLookup::getSymbolUtf8(mWorkingString); lookup) + { + LatexMathSymbol symbol{ LatexMathSymbol::Type::TAG, mWorkingString, *lookup }; + mWorkingSymbols.push_back(symbol); + mLineState = LineState::NONE; + } } void LatexMathExpression::onFracTag() { - mWorkingType = Type::FRACTION; - auto expression = std::make_unique(mWorkingType); - mWorkingExpression = expression.get(); - mExpressions.push_back(std::move(expression)); + mWorkingType = Type::FRACTION; + auto expression = std::make_unique(mWorkingType); + mWorkingExpression = expression.get(); + mExpressions.push_back(std::move(expression)); } void LatexMathExpression::onEnclosingTag(LatexMathSymbol::Tag tag) { - mWorkingType = Type::ENCLOSING; - auto expression = std::make_unique(mWorkingType); + mWorkingType = Type::ENCLOSING; + auto expression = std::make_unique(mWorkingType); - auto left_symbol_value = LatexSymbolLookup::getLeftSymbolUtf8(tag); - auto right_symbol_value = LatexSymbolLookup::getRightSymbolUtf8(tag); + auto left_symbol_value = LatexSymbolLookup::getLeftSymbolUtf8(tag); + auto right_symbol_value = LatexSymbolLookup::getRightSymbolUtf8(tag); - MLOG_INFO("Adding enclosing tag"); + MLOG_INFO("Adding enclosing tag"); - expression->setLeftSymbol({ LatexMathSymbol::Type::ENCLOSING_TAG, "left", *left_symbol_value }); - expression->setRightSymbol({ LatexMathSymbol::Type::ENCLOSING_TAG, "right", *right_symbol_value }); + expression->setLeftSymbol({ LatexMathSymbol::Type::ENCLOSING_TAG, "left", *left_symbol_value }); + expression->setRightSymbol({ LatexMathSymbol::Type::ENCLOSING_TAG, "right", *right_symbol_value }); - mWorkingExpression = expression.get(); - mExpressions.push_back(std::move(expression)); + mWorkingExpression = expression.get(); + mExpressions.push_back(std::move(expression)); } void LatexMathExpression::onCloseExpression() { - if (mWorkingType == Type::LEAF) - { - MLOG_INFO("onCloseExpression LEAF"); - if (!mWorkingSymbols.empty()) - { - MLOG_INFO("Has working symbols"); - auto expression = std::make_unique(mWorkingType); - expression->setContent(mWorkingSymbols); - mExpressions.push_back(std::move(expression)); - } - } - else if (mWorkingType == Type::FRACTION) - { - MLOG_INFO("onCloseExpression FRACTION"); - mWorkingExpression->setRawContent(mWorkingString); + if (mWorkingType == Type::LEAF) + { + MLOG_INFO("onCloseExpression LEAF"); + if (!mWorkingSymbols.empty()) + { + MLOG_INFO("Has working symbols"); + auto expression = std::make_unique(mWorkingType); + expression->setContent(mWorkingSymbols); + mExpressions.push_back(std::move(expression)); + } + } + else if (mWorkingType == Type::FRACTION) + { + MLOG_INFO("onCloseExpression FRACTION"); + mWorkingExpression->setRawContent(mWorkingString); - if (mWorkingExpression->getExpressions().size() == 2) - { - mWorkingType = Type::LEAF; - mLineState = LineState::NONE; - } - else - { - mLineState = LineState::AWAITING_LBRACE; - mOpenBraceCount = 0; - } - } - else if (mWorkingType == Type::ENCLOSING) - { - MLOG_INFO("onCloseExpression ENCLOSING"); - if (!mWorkingString.empty()) - { - mWorkingExpression->setRawContent(mWorkingString); + if (mWorkingExpression->getExpressions().size() == 2) + { + mWorkingType = Type::LEAF; + mLineState = LineState::NONE; + } + else + { + mLineState = LineState::AWAITING_LBRACE; + mOpenBraceCount = 0; + } + } + else if (mWorkingType == Type::ENCLOSING) + { + MLOG_INFO("onCloseExpression ENCLOSING"); + if (!mWorkingString.empty()) + { + mWorkingExpression->setRawContent(mWorkingString); - if (mWorkingExpression->getExpressions().size() == 1) - { - mWorkingType = Type::LEAF; - mLineState = LineState::NONE; - } - } - } + if (mWorkingExpression->getExpressions().size() == 1) + { + mWorkingType = Type::LEAF; + mLineState = LineState::NONE; + } + } + } - mWorkingString.clear(); - mWorkingSymbols.clear(); + mWorkingString.clear(); + mWorkingSymbols.clear(); } void LatexMathExpression::setContent(std::vector& symbols) { - mSymbols = symbols; + mSymbols = symbols; } const std::vector& LatexMathExpression::getSymbols() const { - return mSymbols; + return mSymbols; } -const LatexMathExpression::Type LatexMathExpression::getType() const +LatexMathExpression::Type LatexMathExpression::getType() const { - return mType; + return mType; } const std::vector& LatexMathExpression::getExpressions() const { - return mExpressions; -} \ No newline at end of file + return mExpressions; +} diff --git a/src/publishing/latex/LatexMathExpression.h b/src/publishing/latex/LatexMathExpression.h index b1525d4..0ca30ef 100644 --- a/src/publishing/latex/LatexMathExpression.h +++ b/src/publishing/latex/LatexMathExpression.h @@ -12,91 +12,91 @@ using LatexMathExpressionPtr = std::unique_ptr; class LatexMathExpression { public: - enum class Type - { - LINEAR, - LEAF, - FRACTION, - ENCLOSING, - SUBSCRIPT, - SUPERSCRIPT - }; + enum class Type + { + LINEAR, + LEAF, + FRACTION, + ENCLOSING, + SUBSCRIPT, + SUPERSCRIPT + }; - enum class LineState - { - NONE, - IN_TAG_NAME, - AWAITING_LBRACE, - IN_TAG_BODY - }; + enum class LineState + { + NONE, + IN_TAG_NAME, + AWAITING_LBRACE, + IN_TAG_BODY + }; - LatexMathExpression(const std::string& expression); + LatexMathExpression(const std::string& expression); - LatexMathExpression(Type type); + LatexMathExpression(Type type); - ~LatexMathExpression(); + ~LatexMathExpression(); - const std::vector& getSymbols() const; + const std::vector& getSymbols() const; - const std::vector& getExpressions() const; + const std::vector& getExpressions() const; - const LatexMathSymbol& getLeftSymbol() const; + const LatexMathSymbol& getLeftSymbol() const; - const LatexMathSymbol& getRightSymbol() const; + const LatexMathSymbol& getRightSymbol() const; - const Type getType() const; + Type getType() const; - void setLeftSymbol(const LatexMathSymbol& symbol); + void setLeftSymbol(const LatexMathSymbol& symbol); - void setRightSymbol(const LatexMathSymbol& symbol); + void setRightSymbol(const LatexMathSymbol& symbol); - void setContent(std::vector& symbols); + void setContent(std::vector& symbols); - void setRawContent(const std::string& content); + void setRawContent(const std::string& content); - void onTagBodyChar(char c); + void onTagBodyChar(char c); - void onFreeChar(char c); + void onFreeChar(char c); - void onSpace(); + void onSpace(); - void onLBrace(); + void onLBrace(); - void onRBrace(); + void onRBrace(); - void onSuperscript(); + void onSuperscript(); - void onSubscript(); + void onSubscript(); - void onLiteral(); + void onLiteral(); - void onTagBody(); + void onTagBody(); - void onFinishedTagName(); + void onFinishedTagName(); - void onCloseExpression(); + void onCloseExpression(); - void onFracTag(); + void onFracTag(); - void onEnclosingTag(LatexMathSymbol::Tag tag); + void onEnclosingTag(LatexMathSymbol::Tag tag); - void parse(); + void parse(); private: - std::size_t mOpenBraceCount{ 0 }; + std::size_t mOpenBraceCount{ 0 }; - LineState mLineState{ LineState::NONE }; - std::string mWorkingString; - std::string mRawBody; + LineState mLineState{ LineState::NONE }; + std::string mWorkingString; + std::string mRawBody; - Type mWorkingType{ Type::LEAF }; - LatexMathExpression* mWorkingExpression{ nullptr }; - Type mType{ Type::LEAF }; - std::vector mWorkingSymbols; + Type mWorkingType{ Type::LEAF }; + LatexMathExpression* mWorkingExpression{ nullptr }; + Type mType{ Type::LEAF }; + std::vector mWorkingSymbols; - LatexMathSymbol mLeftSymbol; - LatexMathSymbol mRightSymbol; + LatexMathSymbol mLeftSymbol; + LatexMathSymbol mRightSymbol; - std::vector mSymbols; - std::vector mExpressions; -}; \ No newline at end of file + std::vector mSymbols; + std::vector mExpressions; +}; diff --git a/src/publishing/plotting/PlotNode.cpp b/src/publishing/plotting/PlotNode.cpp index 249f586..2ce9da4 100644 --- a/src/publishing/plotting/PlotNode.cpp +++ b/src/publishing/plotting/PlotNode.cpp @@ -4,18 +4,20 @@ #include "PlotSeriesNode.h" #include "LineNode.h" +#include "EquationNode.h" +#include "TextNode.h" PlotNode::PlotNode(const Transform& transform) - : AbstractVisualNode(transform) + : AbstractVisualNode(transform) { } void PlotNode::setContent(Plot* content) { - mContent = content; - mContentDirty = true; + mContent = content; + mContentDirty = true; } void PlotNode::update(SceneInfo* sceneInfo) @@ -36,7 +38,7 @@ void PlotNode::setAxisEndStyle(LineEndNode::Style style) } } -void PlotNode::createOrUpdateGeometry(SceneInfo* sceneInfo) +void PlotNode::createOrUpdateGeometry(SceneInfo*) { const double height = 100.0; const double width = 100.0; diff --git a/src/publishing/plotting/PlotNode.h b/src/publishing/plotting/PlotNode.h index 910b4e2..be07269 100644 --- a/src/publishing/plotting/PlotNode.h +++ b/src/publishing/plotting/PlotNode.h @@ -9,32 +9,31 @@ class LineNode; class PlotCaptionNode; class PlotSeriesNode; - class PlotNode : public AbstractVisualNode { public: - PlotNode(const Transform& transform = {}); + PlotNode(const Transform& transform = {}); - void setContent(Plot* content); + void setContent(Plot* content); - void setAxisEndStyle(LineEndNode::Style style); + void setAxisEndStyle(LineEndNode::Style style); - void update(SceneInfo* sceneInfo) override; + void update(SceneInfo* sceneInfo) override; protected: - void createOrUpdateGeometry(SceneInfo* sceneInfo); + void createOrUpdateGeometry(SceneInfo* sceneInfo); - Plot* mContent{ nullptr }; - bool mContentDirty = true; + Plot* mContent{ nullptr }; + bool mContentDirty = true; - std::unique_ptr mXAxis; - std::unique_ptr mYAxis; - LineEndNode::Style mAxisEndStyle{ LineEndNode::Style::NONE }; + std::unique_ptr mXAxis; + std::unique_ptr mYAxis; + LineEndNode::Style mAxisEndStyle{ LineEndNode::Style::NONE }; - std::unique_ptr mXAxisCaption; - std::unique_ptr mYAxisCaption; + std::unique_ptr mXAxisCaption; + std::unique_ptr mYAxisCaption; - std::vector > mSeries; + std::vector > mSeries; }; diff --git a/src/rendering/fonts/FreeTypeFontEngine.h b/src/rendering/fonts/FreeTypeFontEngine.h index 5c77d08..9e198d7 100644 --- a/src/rendering/fonts/FreeTypeFontEngine.h +++ b/src/rendering/fonts/FreeTypeFontEngine.h @@ -20,6 +20,11 @@ public: std::unique_ptr loadGlyph(uint32_t charCode) override; + double getHorizontalAdvance(const FontItem&, const std::string&) override + { + return 0.0; + } + private: std::filesystem::path mSystemFontLocation{"/usr/share/fonts/"}; diff --git a/src/rendering/graphics/opengl/OpenGlMeshPainter.cpp b/src/rendering/graphics/opengl/OpenGlMeshPainter.cpp index 20de4b8..f466a42 100644 --- a/src/rendering/graphics/opengl/OpenGlMeshPainter.cpp +++ b/src/rendering/graphics/opengl/OpenGlMeshPainter.cpp @@ -102,12 +102,12 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context) { if (idx % 3 == 0) { - auto x = vertices[idx]*transform.getScaleX() + transform.getLocation().getX(); + auto x = vertices[idx]*transform.getScale().mX + transform.getLocation().getX(); vertices[idx] = 2*x/width - 1.0; } else if(idx%3 == 1) { - auto y = vertices[idx]*transform.getScaleY() + transform.getLocation().getY(); + auto y = vertices[idx]*transform.getScale().mY + transform.getLocation().getY(); vertices[idx] = 1.0 - 2*y/height; } @@ -124,7 +124,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context) indices = dynamic_cast(model->getMesh())->getFaceNodeIds(); } - auto model_color = model->getFillColor().getAsVectorDouble(); + auto model_color = model->getSolidMaterial().getFillColor().getAsVectorDouble(); std::vector color = {float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3])}; paint(vertices, indices, color, line_mesh); diff --git a/src/rendering/visual_elements/nodes/LineEndNode.cpp b/src/rendering/visual_elements/nodes/LineEndNode.cpp index 6a518e4..ec16888 100644 --- a/src/rendering/visual_elements/nodes/LineEndNode.cpp +++ b/src/rendering/visual_elements/nodes/LineEndNode.cpp @@ -4,60 +4,60 @@ #include "PolygonNode.h" LineEndNode::LineEndNode(const Transform& t) - : MaterialNode(t) + : MaterialNode(t) { } void LineEndNode::setStyle(LineEndNode::Style style) { - if (mStyle != style) - { - mStyle = style; - mContentDirty = true; - } + if (mStyle != style) + { + mStyle = style; + mContentDirty = true; + } } void LineEndNode::setSize(double size) { - if (mSize != size) - { - mSize = size; - mContentDirty = true; - } + if (mSize != size) + { + mSize = size; + mContentDirty = true; + } } -void LineEndNode::createOrUpdateGeometry(SceneInfo* sceneInfo) +void LineEndNode::createOrUpdateGeometry(SceneInfo*) { - if (!mContentNode) - { - if (mStyle == Style::CLOSED_ARROW) - { - auto polygon = std::make_unique(); - auto p0 = Point(0.0, -mSize / 2.0); - auto p1 = Point(mSize, 0.0); - auto p2 = Point(0.0, mSize / 2.0); - polygon->setPoints({ p0, p1, p2 }); - polygon->setFillColor({ 0, 0, 0 }); + if (!mContentNode) + { + if (mStyle == Style::CLOSED_ARROW) + { + auto polygon = std::make_unique(); + auto p0 = Point(0.0, -mSize / 2.0); + auto p1 = Point(mSize, 0.0); + auto p2 = Point(0.0, mSize / 2.0); + polygon->setPoints({ p0, p1, p2 }); + polygon->setFillColor({ 0, 0, 0 }); - mContentNode = std::move(polygon); - addChild(mContentNode.get()); - } - } + mContentNode = std::move(polygon); + addChild(mContentNode.get()); + } + } } void LineEndNode::update(SceneInfo* sceneInfo) { - if (mContentDirty) - { - createOrUpdateGeometry(sceneInfo); - mContentDirty = false; - } + if (mContentDirty) + { + createOrUpdateGeometry(sceneInfo); + mContentDirty = false; + } - if (mMaterialIsDirty) - { - //updateMaterial(); - mMaterialIsDirty = false; - } -} \ No newline at end of file + if (mMaterialIsDirty) + { + //updateMaterial(); + mMaterialIsDirty = false; + } +} diff --git a/src/rendering/visual_elements/nodes/TextNode.cpp b/src/rendering/visual_elements/nodes/TextNode.cpp index 494f0e4..86f30ec 100644 --- a/src/rendering/visual_elements/nodes/TextNode.cpp +++ b/src/rendering/visual_elements/nodes/TextNode.cpp @@ -63,7 +63,7 @@ double TextNode::getContentWidth(SceneInfo* sceneInfo) return mContentWidth; } -double TextNode::getContentHeight(SceneInfo* sceneInfo) +double TextNode::getContentHeight(SceneInfo*) { if (mContentHeight == 1.0) { diff --git a/src/rendering/visual_elements/svg/SvgNode.cpp b/src/rendering/visual_elements/svg/SvgNode.cpp index b232608..64dc86c 100644 --- a/src/rendering/visual_elements/svg/SvgNode.cpp +++ b/src/rendering/visual_elements/svg/SvgNode.cpp @@ -126,8 +126,8 @@ void SvgNode::onCircle(XmlElement* element, std::unique_ptr& node) { const auto transform = svg_circle->getTransform(); loc.move(transform.getLocation().getX(), transform.getLocation().getY()); - radius *= transform.getScaleX(); - minor_radius *= transform.getScaleY(); + radius *= transform.getScale().mX; + minor_radius *= transform.getScale().mY; } auto circle_node = std::make_unique(loc, radius); diff --git a/src/rendering/visual_elements/svg/SvgPainter.cpp b/src/rendering/visual_elements/svg/SvgPainter.cpp index b7ce451..9f8a730 100644 --- a/src/rendering/visual_elements/svg/SvgPainter.cpp +++ b/src/rendering/visual_elements/svg/SvgPainter.cpp @@ -71,8 +71,8 @@ void SvgPainter::paintMesh(SvgDocument* document, SceneModel* model, bool showOu auto face_locs = face->getNodeLocations(); for (const auto& loc : face_locs) { - const auto x = loc.getX() * transform.getScaleX() + transform.getLocation().getX(); - const auto y = loc.getY() * transform.getScaleY() + transform.getLocation().getY(); + const auto x = loc.getX() * transform.getScale().mX + transform.getLocation().getX(); + const auto y = loc.getY() * transform.getScale().mY + transform.getLocation().getY(); points[count] = { x, y }; count++; } @@ -122,7 +122,7 @@ void SvgPainter::setStyle(SceneModel* model, SvgShapeElement* element) const element->setNoStroke(); } - if (!transform.isDefaultTransform()) + if (!transform.isIdentityTransform()) { element->addAttribute(toTransform(transform)); } @@ -249,7 +249,7 @@ void SvgPainter::paintText(SvgDocument* document, SceneText* text) const svg_text->setFontSize(text->getTextData().mFont.getSize()); const auto transform = text->getTransform(); - if (!transform.isDefaultTransform()) + if (!transform.isIdentityTransform()) { svg_text->addAttribute(toTransform(transform)); } @@ -262,13 +262,13 @@ std::unique_ptr SvgPainter::toTransform(const Transform& transform auto svg_transform = std::make_unique("transform"); std::string ops; - if (!transform.hasDefaultLocation()) + if (!transform.isIdentityTransform()) { ops += "translate(" + std::to_string(transform.getLocation().getX()) + " " + std::to_string(transform.getLocation().getY()) + ") "; } - if (!transform.hasDefaultScale()) + if (!transform.getScale().isIdentity()) { - ops += "scale(" + std::to_string(transform.getScaleX()) + " " + std::to_string(transform.getScaleY()) + ") "; + ops += "scale(" + std::to_string(transform.getScale().mX) + " " + std::to_string(transform.getScale().mY) + ") "; } svg_transform->setValue(ops); diff --git a/src/rendering/visual_elements/svg/SvgShapeElement.cpp b/src/rendering/visual_elements/svg/SvgShapeElement.cpp index fd92e85..f648253 100644 --- a/src/rendering/visual_elements/svg/SvgShapeElement.cpp +++ b/src/rendering/visual_elements/svg/SvgShapeElement.cpp @@ -53,7 +53,8 @@ Transform SvgShapeElement::getTransform() const else if (in_scale) { const auto loc = parsePoint(working_string, 1.0); - transform.setScale(loc.getX(), loc.getY(), loc.getZ()); + Scale scale(loc.getX(), loc.getY(), loc.getZ()); + transform.setScale(scale); in_scale = false; } working_string.clear(); diff --git a/src/ui/windows/ui_interfaces/x11/XcbTextInterface.cpp b/src/ui/windows/ui_interfaces/x11/XcbTextInterface.cpp index b426c2a..b9b6959 100644 --- a/src/ui/windows/ui_interfaces/x11/XcbTextInterface.cpp +++ b/src/ui/windows/ui_interfaces/x11/XcbTextInterface.cpp @@ -14,7 +14,7 @@ xcb_gcontext_t XcbTextInterface::GetFontGC(xcb_connection_t *connection, /* create graphics context */ xcb_gcontext_t gc = xcb_generate_id(connection); uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - auto fillColor = textElement->getFillColor().getAsUInt32(); + auto fillColor = textElement->getMaterial()->getFillColor().getAsUInt32(); uint32_t value_list[3] = {screen->black_pixel, fillColor, font }; xcb_create_gc(connection, gc, window, mask, value_list); diff --git a/test/publishing/TestPlotting.cpp b/test/publishing/TestPlotting.cpp index 66a3c7a..ccaba17 100644 --- a/test/publishing/TestPlotting.cpp +++ b/test/publishing/TestPlotting.cpp @@ -4,30 +4,35 @@ #include "Plot.h" #include "PlotNode.h" +#include "PlotSeriesNode.h" +#include "PlotCaptionNode.h" +#include "EquationNode.h" +#include "TextNode.h" +#include "LineNode.h" TEST_CASE(TestPlotting, "[publishing]") { - auto plot = std::make_unique(); - plot->setXAxisCaption("X Axis"); - plot->setYAxisCaption("Y Axis"); + auto plot = std::make_unique(); + plot->setXAxisCaption("X Axis"); + plot->setYAxisCaption("Y Axis"); - PlotSeries series("Series-1"); + PlotSeries series("Series-1"); - std::vector data{ {0.0, 0.0}, {10.0, 40.0}, {20.0, 80.0} }; - series.setData(data); - plot->addSeries(series); + std::vector data{ {0.0, 0.0}, {10.0, 40.0}, {20.0, 80.0} }; + series.setData(data); + plot->addSeries(series); - Point loc(10, 10); - auto plot_node = std::make_unique(Transform(loc)); - plot_node->setAxisEndStyle(LineEndNode::Style::CLOSED_ARROW); + Point loc(10, 10); + auto plot_node = std::make_unique(Transform(loc)); + plot_node->setAxisEndStyle(LineEndNode::Style::CLOSED_ARROW); - plot_node->setContent(plot.get()); + plot_node->setContent(plot.get()); - TestRenderer renderer(800, 800); + TestRenderer renderer(800, 800); - auto scene = renderer.getScene(); - scene->addNode(plot_node.get()); + auto scene = renderer.getScene(); + scene->addNode(plot_node.get()); - renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "plot.svg"); - renderer.write(TestUtils::getTestOutputDir(__FILE__) / "plot.png"); -} \ No newline at end of file + renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "plot.svg"); + renderer.write(TestUtils::getTestOutputDir(__FILE__) / "plot.png"); +}