<commit_before>/**
 Copyright 2016 Udey Rishi

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

#include <catch.hpp>
#include <core/TruthTable.hpp>
#include <sstream>

using namespace Logic;

SCENARIO("TruthTableVariablesUInt behaves like a uint with range 0 <= x <= 64", "[TruthTableVariablesUInt]") {
    GIVEN("A TruthTableVariablesUInt with some value") {
        REQUIRE(TruthTableVariablesUInt(23) == 23);
        REQUIRE((uint8_t) TruthTableVariablesUInt(0) == 0);
        REQUIRE((uint8_t) TruthTableVariablesUInt() == 0);
        REQUIRE((uint8_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((uint32_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((uint64_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int8_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int32_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int64_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int64_t) TruthTableVariablesUInt(64) == 64);
        REQUIRE(TruthTableVariablesUInt(45) >= -52);
        REQUIRE(TruthTableVariablesUInt(45) > -52);
        REQUIRE(TruthTableVariablesUInt(45) > 0);
        REQUIRE(TruthTableVariablesUInt(45) >= 0);
        REQUIRE(TruthTableVariablesUInt(45) < 46);
        REQUIRE(TruthTableVariablesUInt(45) <= 46);
        REQUIRE(TruthTableVariablesUInt(45) < 123);
        REQUIRE(TruthTableVariablesUInt(45) <= 123);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(65); }, out_of_range);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(100); }, out_of_range);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(255); }, out_of_range);

        TruthTableVariablesUInt x = 34;
        WHEN("The pre-increment operator is used") {
            THEN("Both the variable and the return value increase") {
                TruthTableVariablesUInt y = ++x;
                REQUIRE(y == 35);
                REQUIRE(x == 35);
            }

            THEN("overflow_error is thrown if the value was 64") {
                TruthTableVariablesUInt z(64);
                CHECK_THROWS_AS({ ++z; }, overflow_error);
            }
        }

        WHEN("The post-increment operator is used") {
            THEN("Only the variable and NOT the return value increases") {
                TruthTableVariablesUInt y = x++;
                REQUIRE(y == 34);
                REQUIRE(x == 35);
            }

            THEN("overflow_error is thrown if the value was 64") {
                TruthTableVariablesUInt z(64);
                CHECK_THROWS_AS({ z++; }, overflow_error);
            }
        }

        WHEN("The pre-decrement operator is used") {
            THEN("Both the variable's and the return value decrease") {
                TruthTableVariablesUInt y = --x;
                REQUIRE(y == 33);
                REQUIRE(x == 33);
            }

            THEN("underflow_error is thrown if the value was 0") {
                TruthTableVariablesUInt z(0);
                CHECK_THROWS_AS({ --z; }, underflow_error);
            }
        }

        WHEN("The post-decrement operator is used") {
            THEN("Only the variable and NOT the return value decreases") {
                TruthTableVariablesUInt y = x--;
                REQUIRE(y == 34);
                REQUIRE(x == 33);
            }

            THEN("underflow_error is thrown if the value was 0") {
                TruthTableVariablesUInt z(0);
                CHECK_THROWS_AS({ z--; }, underflow_error);
            }
        }

        WHEN("The plus-equals operator is used") {
            THEN("The value increments by the specified amount") {
                x += 5;
                REQUIRE(x == 39);
            }

            THEN("overflow_error is thrown if the resulting value > 64") {
                CHECK_THROWS_AS({ x += 31; }, overflow_error);
            }
        }

        WHEN("The minus-equals operator is used") {
            THEN("The value decrements by the specified amount") {
                x -= 5;
                REQUIRE(x == 29);
            }

            THEN("underflow_error is thrown if the resulting value < 0") {
                CHECK_THROWS_AS({ x -= 35; }, underflow_error);
            }
        }

        WHEN("The plus operator is used") {
            THEN("The value increments by the specified amount") {
                REQUIRE(x + 5 == 39);
            }

            THEN("overflow_error is thrown if the resulting value > 64") {
                CHECK_THROWS_AS({ x + 31; }, overflow_error);
            }
        }

        WHEN("The minus operator is used") {
            THEN("The value decrements by the specified amount") {
                REQUIRE(x - 5 == 29);
            }

            THEN("underflow_error is thrown if the resulting value < 0") {
                CHECK_THROWS_AS({ x - 35; }, underflow_error);
            }
        }

        WHEN("The istream is used") {
            THEN("The resulting object is created") {
                TruthTableVariablesUInt y;
                istringstream("12") >> y;
                REQUIRE(y == 12);
            }

            THEN("out_of_range error is thrown when the number is not between 0 and 64") {
                TruthTableVariablesUInt y;
                CHECK_THROWS_AS({ istringstream("-1") >> y; }, out_of_range);
                CHECK_THROWS_AS({ istringstream("65") >> y; }, out_of_range);
            }
        }

        WHEN("The ostream is used") {
            THEN("The resulting object is printed") {
                TruthTableVariablesUInt y(12);
                ostringstream oss;
                oss << y;
                REQUIRE(oss.str() == "12");
            }
        }
    }
}<commit_msg>Added tests for TruthTable<commit_after>/**
 Copyright 2016 Udey Rishi

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

#include <catch.hpp>
#include <core/TruthTable.hpp>
#include <sstream>
#include <Exceptions.hpp>

using namespace Logic;

SCENARIO("TruthTableVariablesUInt behaves like a uint with range 0 <= x <= 64", "[TruthTableVariablesUInt]") {
    GIVEN("A TruthTableVariablesUInt with some value") {
        REQUIRE(TruthTableVariablesUInt(23) == 23);
        REQUIRE((uint8_t) TruthTableVariablesUInt(0) == 0);
        REQUIRE((uint8_t) TruthTableVariablesUInt() == 0);
        REQUIRE((uint8_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((uint32_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((uint64_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int8_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int32_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int64_t) TruthTableVariablesUInt(45) == 45);
        REQUIRE((int64_t) TruthTableVariablesUInt(64) == 64);
        REQUIRE(TruthTableVariablesUInt(45) >= -52);
        REQUIRE(TruthTableVariablesUInt(45) > -52);
        REQUIRE(TruthTableVariablesUInt(45) > 0);
        REQUIRE(TruthTableVariablesUInt(45) >= 0);
        REQUIRE(TruthTableVariablesUInt(45) < 46);
        REQUIRE(TruthTableVariablesUInt(45) <= 46);
        REQUIRE(TruthTableVariablesUInt(45) < 123);
        REQUIRE(TruthTableVariablesUInt(45) <= 123);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(65); }, out_of_range);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(100); }, out_of_range);
        CHECK_THROWS_AS({ TruthTableVariablesUInt x(255); }, out_of_range);

        TruthTableVariablesUInt x = 34;
        WHEN("The pre-increment operator is used") {
            THEN("Both the variable and the return value increase") {
                TruthTableVariablesUInt y = ++x;
                REQUIRE(y == 35);
                REQUIRE(x == 35);
            }

            THEN("overflow_error is thrown if the value was 64") {
                TruthTableVariablesUInt z(64);
                CHECK_THROWS_AS({ ++z; }, overflow_error);
            }
        }

        WHEN("The post-increment operator is used") {
            THEN("Only the variable and NOT the return value increases") {
                TruthTableVariablesUInt y = x++;
                REQUIRE(y == 34);
                REQUIRE(x == 35);
            }

            THEN("overflow_error is thrown if the value was 64") {
                TruthTableVariablesUInt z(64);
                CHECK_THROWS_AS({ z++; }, overflow_error);
            }
        }

        WHEN("The pre-decrement operator is used") {
            THEN("Both the variable's and the return value decrease") {
                TruthTableVariablesUInt y = --x;
                REQUIRE(y == 33);
                REQUIRE(x == 33);
            }

            THEN("underflow_error is thrown if the value was 0") {
                TruthTableVariablesUInt z(0);
                CHECK_THROWS_AS({ --z; }, underflow_error);
            }
        }

        WHEN("The post-decrement operator is used") {
            THEN("Only the variable and NOT the return value decreases") {
                TruthTableVariablesUInt y = x--;
                REQUIRE(y == 34);
                REQUIRE(x == 33);
            }

            THEN("underflow_error is thrown if the value was 0") {
                TruthTableVariablesUInt z(0);
                CHECK_THROWS_AS({ z--; }, underflow_error);
            }
        }

        WHEN("The plus-equals operator is used") {
            THEN("The value increments by the specified amount") {
                x += 5;
                REQUIRE(x == 39);
            }

            THEN("overflow_error is thrown if the resulting value > 64") {
                CHECK_THROWS_AS({ x += 31; }, overflow_error);
            }
        }

        WHEN("The minus-equals operator is used") {
            THEN("The value decrements by the specified amount") {
                x -= 5;
                REQUIRE(x == 29);
            }

            THEN("underflow_error is thrown if the resulting value < 0") {
                CHECK_THROWS_AS({ x -= 35; }, underflow_error);
            }
        }

        WHEN("The plus operator is used") {
            THEN("The value increments by the specified amount") {
                REQUIRE(x + 5 == 39);
            }

            THEN("overflow_error is thrown if the resulting value > 64") {
                CHECK_THROWS_AS({ x + 31; }, overflow_error);
            }
        }

        WHEN("The minus operator is used") {
            THEN("The value decrements by the specified amount") {
                REQUIRE(x - 5 == 29);
            }

            THEN("underflow_error is thrown if the resulting value < 0") {
                CHECK_THROWS_AS({ x - 35; }, underflow_error);
            }
        }

        WHEN("The istream is used") {
            THEN("The resulting object is created") {
                TruthTableVariablesUInt y;
                istringstream("12") >> y;
                REQUIRE(y == 12);
            }

            THEN("out_of_range error is thrown when the number is not between 0 and 64") {
                TruthTableVariablesUInt y;
                CHECK_THROWS_AS({ istringstream("-1") >> y; }, out_of_range);
                CHECK_THROWS_AS({ istringstream("65") >> y; }, out_of_range);
            }
        }

        WHEN("The ostream is used") {
            THEN("The resulting object is printed") {
                TruthTableVariablesUInt y(12);
                ostringstream oss;
                oss << y;
                REQUIRE(oss.str() == "12");
            }
        }
    }
}

// TruthTableUInt is just a typedef right now, so tests is an overkill. Add if this is not true in the future

SCENARIO("A TruthTable stores the variable and data properly", "[TruthTable]") {
    GIVEN("A 3-variable TruthTable") {
        TruthTable table({"a", "ball", "cat"});

        REQUIRE(table.size() == 8);
        REQUIRE(table.getVariables().size() == 3);
        REQUIRE(table.getVariables()[0] == "a");
        REQUIRE(table.getVariables()[1] == "ball");
        REQUIRE(table.getVariables()[2] == "cat");

        REQUIRE(TruthTable::getVariableValueInLine(0, 0) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(1, 0) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(2, 0) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(3, 0) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(4, 0) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(0, 1) == 1);
        REQUIRE(TruthTable::getVariableValueInLine(1, 1) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(2, 1) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(3, 1) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(4, 1) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(0, 2) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(1, 2) == 1);
        REQUIRE(TruthTable::getVariableValueInLine(2, 2) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(3, 2) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(4, 2) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(0, 6) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(1, 6) == 1);
        REQUIRE(TruthTable::getVariableValueInLine(2, 6) == 1);
        REQUIRE(TruthTable::getVariableValueInLine(3, 6) == 0);
        REQUIRE(TruthTable::getVariableValueInLine(4, 6) == 0);

        WHEN("The [] operator is used within table's range") {
            THEN("The table's value can be set and retrieved at that index") {
                for (TruthTableUInt i = 0; i < table.size(); ++i) {
                    REQUIRE(!table[i]);
                }
                table[5] = !table[5];
                for (TruthTableUInt i = 0; i < table.size(); ++i) {
                    if (i == 5) {
                        REQUIRE(table[i]);
                    } else {
                        REQUIRE(!table[i]);
                    }
                }
                table[4] = !table[5];
                for (TruthTableUInt i = 0; i < table.size(); ++i) {
                    if (i == 5) {
                        REQUIRE(table[i]);
                    } else {
                        REQUIRE(!table[i]);
                    }
                }
            }
        }

        WHEN("The [] operator is used outside of table's range") {
            THEN("out_of_range exception is thrown") {
                CHECK_THROWS_AS({ table[8]; }, out_of_range);
                CHECK_THROWS_AS({ table[52]; }, out_of_range);
                CHECK_THROWS_AS({ table[8] = true; }, out_of_range);
            }
        }

        WHEN("You apply a condition on a variable") {
            THEN("The correct resulting table is generated") {
                // a & b;
                table[3] = true;
                table[7] = true;

                TruthTableCondition condition = table.conditionBuilder();
                condition.when("a", true);
                condition.when("ball", true);
                TruthTable result = condition.then();

                REQUIRE(result.size() == 2);
                REQUIRE(result.getVariables().size() == 1);
                REQUIRE(result.getVariables()[0] == "cat");
                REQUIRE(result[0] == true);
                REQUIRE(result[1] == true);
            }
        }

        WHEN("You apply a condition on a variable that does not exist") {
            THEN("invalid_argument exception is thrown") {
                CHECK_THROWS_AS({ table.conditionBuilder().when("b", true); }, invalid_argument);
            }
        }

        WHEN("You apply a condition on a variable multiple times") {
            THEN("The values overwrite, and the last one is kept") {
                TruthTableCondition condition = table.conditionBuilder();
                condition.when("a", true);
                condition.when("a", false);
                TruthTable result = condition.then();
                REQUIRE(result.size() == 4);
                REQUIRE(result.getVariables().size() == 2);
                REQUIRE(result.getVariables()[0] == "ball");
                REQUIRE(result.getVariables()[1] == "cat");
                REQUIRE(result[0] == false);
                REQUIRE(result[1] == false);
                REQUIRE(result[2] == false);
                REQUIRE(result[3] == false);
            }
        }

        // TODO: This is the current behaviour. Maybe this can be better?
        WHEN("You apply a condition to all the variables") {
            THEN("IllegalTruthTableException is thrown when creating the resulting table") {
                TruthTableCondition condition = table.conditionBuilder();
                condition.when("a", true);
                condition.when("ball", true);
                condition.when("cat", false);
                CHECK_THROWS_AS({ condition.then(); }, IllegalTruthTableException);
            }
        }
    }

    WHEN("You try to create a truthtable with no variables") {
        THEN("invalid_argument exception is thrown") {
            CHECK_THROWS_AS({ TruthTable({}); }, invalid_argument);
        }
    }

    WHEN("You try to create a truthtable with > 64 variables") {
        THEN("invalid_argument exception is thrown") {
            vector<string> vars;
            for (int i = 0; i < 65; ++i) {
                vars.push_back(string(1, 'a' + (char)i));
            }
            CHECK_THROWS_AS({ TruthTable x(vars); }, invalid_argument);
            vars.push_back("hello");
            CHECK_THROWS_AS({ TruthTable x(vars); }, invalid_argument);
        }
    }

    WHEN("You try to create a truthtable with duplicate variables") {
        THEN("invalid_argument exception is thrown") {
            CHECK_THROWS_AS({ TruthTable({"x", "hello", "x"}); }, invalid_argument);
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014 Kajetan Swierk <k0zmo@outlook.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "Logic/NodeType.h"
#include "Logic/NodeFactory.h"

#include <opencv2/imgproc/imgproc.hpp>

class BinarizationNodeType : public NodeType
{
public:
    BinarizationNodeType()
        : _threshold(128)
        , _inv(false)
    {
    }

    bool setProperty(PropertyID propId, const NodeProperty& newValue) override
    {
        switch(static_cast<pid>(propId))
        {
        case pid::Threshold:
            _threshold = newValue.toInt();
            return true;
        case pid::Invert:
            _inv = newValue.toBool();
            return true;
        }

        return false;
    }

    NodeProperty property(PropertyID propId) const override
    {
        switch(static_cast<pid>(propId))
        {
        case pid::Threshold: return _threshold;
        case pid::Invert: return _inv;
        }

        return NodeProperty();
    }

    ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
    {
        // Read input sockets
        const cv::Mat& src = reader.readSocket(0).getImageMono();
        // Acquire output sockets
        cv::Mat& dst = writer.acquireSocket(0).getImageMono();

        // Validate inputs
        if(src.empty())
            return ExecutionStatus(EStatus::Ok);
        if(_threshold < 0 || _threshold > 255)
            return ExecutionStatus(EStatus::Error, "Bad threshold value");

        // Do stuff
        int type = _inv ? cv::THRESH_BINARY_INV : cv::THRESH_BINARY;
        cv::threshold(src, dst, (double) _threshold, 255, type);

        return ExecutionStatus(EStatus::Ok);
    }

    void configuration(NodeConfig& nodeConfig) const override
    {
        static const InputSocketConfig in_config[] = {
            { ENodeFlowDataType::ImageMono, "source", "Source", "" },
            { ENodeFlowDataType::Invalid, "", "", "" }
        };
        static const OutputSocketConfig out_config[] = {
            { ENodeFlowDataType::ImageMono, "output", "Output", "" },
            { ENodeFlowDataType::Invalid, "", "", "" }
        };
        static const PropertyConfig prop_config[] = {
            { EPropertyType::Integer, "Threshold", "min:0, max:255" },
            { EPropertyType::Boolean, "Inverted", "" },
            { EPropertyType::Unknown, "", "" }
        };

        nodeConfig.description = "Applies a fixed-level threshold to each pixel element.";
        nodeConfig.pInputSockets = in_config;
        nodeConfig.pOutputSockets = out_config;
        nodeConfig.pProperties = prop_config;
    }

private:
    enum class pid
    {
        Threshold,
        Invert
    };

    int _threshold;
    bool _inv;
};

class OtsuThresholdingNodeType : public NodeType
{
public:
    ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
    {
        // Read input sockets
        const cv::Mat& src = reader.readSocket(0).getImageMono();
        // Acquire output sockets
        cv::Mat& dst = writer.acquireSocket(0).getImageMono();

        // Validate inputs
        if(src.empty() || src.type() != CV_8U)
            return ExecutionStatus(EStatus::Ok);

        // Do stuff
        cv::threshold(src, dst, 0, 255, cv::THRESH_OTSU);

        return ExecutionStatus(EStatus::Ok);
    }

    void configuration(NodeConfig& nodeConfig) const override
    {
        static const InputSocketConfig in_config[] = {
            { ENodeFlowDataType::ImageMono, "source", "Source", "" },
            { ENodeFlowDataType::Invalid, "", "", "" }
        };
        static const OutputSocketConfig out_config[] = {
            { ENodeFlowDataType::ImageMono, "output", "Output", "" },
            { ENodeFlowDataType::Invalid, "", "", "" }
        };

        nodeConfig.description = "Applies optimal threshold value using Otsu's algorithm to each pixel element.";
        nodeConfig.pInputSockets = in_config;
        nodeConfig.pOutputSockets = out_config;
    }
};

REGISTER_NODE("Segmentation/Otsu's thresholding", OtsuThresholdingNodeType)
REGISTER_NODE("Segmentation/Binarization", BinarizationNodeType)
<commit_msg>updated image segmenting nodes for new node conf. interface [WIP]<commit_after>/*
 * Copyright (c) 2013-2014 Kajetan Swierk <k0zmo@outlook.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "Logic/NodeType.h"
#include "Logic/NodeFactory.h"

#include <opencv2/imgproc/imgproc.hpp>

class BinarizationNodeType : public NodeType
{
public:
    BinarizationNodeType()
        : _threshold(128)
        , _inv(false)
    {
        addInput("Source", ENodeFlowDataType::ImageMono);
        addOutput("Output", ENodeFlowDataType::ImageMono);
        addProperty("Threshold", _threshold)
            .setValidator(make_validator<InclRangePropertyValidator<int>>(0, 255))
            .setUiHints("min:0, max:255");
        addProperty("Inverted", _inv);
        setDescription("Applies a fixed-level threshold to each pixel element.");
    }

    ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
    {
        // Read input sockets
        const cv::Mat& src = reader.readSocket(0).getImageMono();
        // Acquire output sockets
        cv::Mat& dst = writer.acquireSocket(0).getImageMono();

        // Validate inputs
        if(src.empty())
            return ExecutionStatus(EStatus::Ok);
        if(_threshold < 0 || _threshold > 255)
            return ExecutionStatus(EStatus::Error, "Bad threshold value");

        // Do stuff
        int type = _inv ? cv::THRESH_BINARY_INV : cv::THRESH_BINARY;
        cv::threshold(src, dst, (double) _threshold, 255, type);

        return ExecutionStatus(EStatus::Ok);
    }

private:
    TypedNodeProperty<int> _threshold;
    TypedNodeProperty<bool> _inv;
};

class OtsuThresholdingNodeType : public NodeType
{
public:
    OtsuThresholdingNodeType()
    {
        addInput("Source", ENodeFlowDataType::ImageMono);
        addOutput("Output", ENodeFlowDataType::ImageMono);
        setDescription("Applies optimal threshold value using Otsu's algorithm to each pixel element.");
    }

    ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
    {
        // Read input sockets
        const cv::Mat& src = reader.readSocket(0).getImageMono();
        // Acquire output sockets
        cv::Mat& dst = writer.acquireSocket(0).getImageMono();

        // Validate inputs
        if(src.empty() || src.type() != CV_8U)
            return ExecutionStatus(EStatus::Ok);

        // Do stuff
        cv::threshold(src, dst, 0, 255, cv::THRESH_OTSU);

        return ExecutionStatus(EStatus::Ok);
    }
};

REGISTER_NODE("Segmentation/Otsu's thresholding", OtsuThresholdingNodeType)
REGISTER_NODE("Segmentation/Binarization", BinarizationNodeType)
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "cameracontrollercomponent.h"

#include <QtCore/QSizeF>
#include <QtGui/QMatrix4x4>

#include <core/debughelper.h>
#include <graphics/camera.h>
#include <graphics/engine.h>
#include <graphics/frustrum.h>
#include <graphics/viewport.h>
#include <graphics/rendertarget.h>
#include <graphics/materialinstance.h>
#include <engine/gameobject.h>
#include <engine/asset.h>

REGISTER_OBJECTTYPE( GluonEngine, CameraControllerComponent )

using namespace GluonEngine;

class CameraControllerComponent::CameraControllerComponentPrivate
{
    public:
        CameraControllerComponentPrivate()
        {
            camera = 0;
            active = true;
            visibleArea = QSizeF( 100.0f, 100.0f );
            nearPlane = 1.0f;
            farPlane = 100.0f;
            material = 0;
        }

        GluonGraphics::Camera* camera;
        bool active;

        QSizeF visibleArea;
        float nearPlane;
        float farPlane;

        GluonGraphics::MaterialInstance* material;

        static GluonGraphics::Camera* activeCamera;
};

GluonGraphics::Camera* CameraControllerComponent::CameraControllerComponentPrivate::activeCamera = 0;

CameraControllerComponent::CameraControllerComponent( QObject* parent )
    : Component( parent )
    , d( new CameraControllerComponentPrivate )
{

}

CameraControllerComponent::CameraControllerComponent( const CameraControllerComponent& other )
    : Component( other )
    , d( other.d )
{
}

CameraControllerComponent::~CameraControllerComponent()
{
    delete d;
}

QString CameraControllerComponent::category() const
{
    return QString( "Graphics" );
}

void CameraControllerComponent::initialize()
{
    if( !d->camera )
        d->camera = new GluonGraphics::Camera();

    if( d->active )
    {
        GluonGraphics::Engine::instance()->setActiveCamera( d->camera );
    }

    if(!d->material)
    {
        d->material = GluonGraphics::Engine::instance()->mainRenderTarget()->materialInstance();
    }
    else
    {
        Asset* materialAsset = qobject_cast<Asset*>( d->material->parent() );
        if( materialAsset )
            materialAsset->load();
        GluonGraphics::Engine::instance()->mainRenderTarget()->setMaterialInstance(d->material);
    }

    d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::start()
{
}

void CameraControllerComponent::draw( int timeLapse )
{
    Q_UNUSED( timeLapse )

    if( d->camera )
        d->camera->setViewMatrix( gameObject()->transform().inverted() );
}

void CameraControllerComponent::cleanup()
{
    CameraControllerComponentPrivate::activeCamera = 0;
    GluonGraphics::Engine::instance()->setActiveCamera( 0 );

    delete d->camera;
    d->camera = 0;
}

bool CameraControllerComponent::isActive()
{
    return d->active;
}

void CameraControllerComponent::setActive( bool active )
{
    d->active = active;
    if( active && d->camera )
    {
        CameraControllerComponentPrivate::activeCamera = d->camera;
        GluonGraphics::Engine::instance()->setActiveCamera( d->camera );
    }
}

void CameraControllerComponent::setVisibleArea( const QSizeF& area )
{
    d->visibleArea = area;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

QSizeF CameraControllerComponent::visibleArea()
{
    return d->visibleArea;
}

float CameraControllerComponent::nearPlane()
{
    return d->nearPlane;
}

float CameraControllerComponent::farPlane()
{
    return d->farPlane;
}

GluonGraphics::MaterialInstance* CameraControllerComponent::renderTargetMaterial()
{
    return d->material;
}

void CameraControllerComponent::setNearPlane( float near )
{
    d->nearPlane = near;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::setFarPlane( float far )
{
    d->farPlane = far;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::setRenderTargetMaterial( GluonGraphics::MaterialInstance* material )
{
    d->material = material;

    GluonGraphics::Engine::instance()->mainRenderTarget()->setMaterialInstance(material);
}

Q_EXPORT_PLUGIN2( gluon_component_cameracontroller, GluonEngine::CameraControllerComponent );

#include "cameracontrollercomponent.moc"
<commit_msg>Check if the render target was created before setting its material.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "cameracontrollercomponent.h"

#include <QtCore/QSizeF>
#include <QtGui/QMatrix4x4>

#include <core/debughelper.h>
#include <graphics/camera.h>
#include <graphics/engine.h>
#include <graphics/frustrum.h>
#include <graphics/viewport.h>
#include <graphics/rendertarget.h>
#include <graphics/materialinstance.h>
#include <engine/gameobject.h>
#include <engine/asset.h>

REGISTER_OBJECTTYPE( GluonEngine, CameraControllerComponent )

using namespace GluonEngine;

class CameraControllerComponent::CameraControllerComponentPrivate
{
    public:
        CameraControllerComponentPrivate()
        {
            camera = 0;
            active = true;
            visibleArea = QSizeF( 100.0f, 100.0f );
            nearPlane = 1.0f;
            farPlane = 100.0f;
            material = 0;
        }

        GluonGraphics::Camera* camera;
        bool active;

        QSizeF visibleArea;
        float nearPlane;
        float farPlane;

        GluonGraphics::MaterialInstance* material;

        static GluonGraphics::Camera* activeCamera;
};

GluonGraphics::Camera* CameraControllerComponent::CameraControllerComponentPrivate::activeCamera = 0;

CameraControllerComponent::CameraControllerComponent( QObject* parent )
    : Component( parent )
    , d( new CameraControllerComponentPrivate )
{

}

CameraControllerComponent::CameraControllerComponent( const CameraControllerComponent& other )
    : Component( other )
    , d( other.d )
{
}

CameraControllerComponent::~CameraControllerComponent()
{
    delete d;
}

QString CameraControllerComponent::category() const
{
    return QString( "Graphics" );
}

void CameraControllerComponent::initialize()
{
    if( !d->camera )
        d->camera = new GluonGraphics::Camera();

    if( d->active )
    {
        GluonGraphics::Engine::instance()->setActiveCamera( d->camera );
    }

    if(!d->material)
    {
        d->material = GluonGraphics::Engine::instance()->mainRenderTarget()->materialInstance();
    }
    else
    {
        Asset* materialAsset = qobject_cast<Asset*>( d->material->parent() );
        if( materialAsset )
            materialAsset->load();
        GluonGraphics::Engine::instance()->mainRenderTarget()->setMaterialInstance(d->material);
    }

    d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::start()
{
}

void CameraControllerComponent::draw( int timeLapse )
{
    Q_UNUSED( timeLapse )

    if( d->camera )
        d->camera->setViewMatrix( gameObject()->transform().inverted() );
}

void CameraControllerComponent::cleanup()
{
    CameraControllerComponentPrivate::activeCamera = 0;
    GluonGraphics::Engine::instance()->setActiveCamera( 0 );

    delete d->camera;
    d->camera = 0;
}

bool CameraControllerComponent::isActive()
{
    return d->active;
}

void CameraControllerComponent::setActive( bool active )
{
    d->active = active;
    if( active && d->camera )
    {
        CameraControllerComponentPrivate::activeCamera = d->camera;
        GluonGraphics::Engine::instance()->setActiveCamera( d->camera );
    }
}

void CameraControllerComponent::setVisibleArea( const QSizeF& area )
{
    d->visibleArea = area;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

QSizeF CameraControllerComponent::visibleArea()
{
    return d->visibleArea;
}

float CameraControllerComponent::nearPlane()
{
    return d->nearPlane;
}

float CameraControllerComponent::farPlane()
{
    return d->farPlane;
}

GluonGraphics::MaterialInstance* CameraControllerComponent::renderTargetMaterial()
{
    return d->material;
}

void CameraControllerComponent::setNearPlane( float near )
{
    d->nearPlane = near;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::setFarPlane( float far )
{
    d->farPlane = far;

    if( d->camera )
        d->camera->frustrum()->setOrthoAdjusted( d->visibleArea, GluonGraphics::Engine::instance()->currentViewport()->aspectRatio(), d->nearPlane, d->farPlane );
}

void CameraControllerComponent::setRenderTargetMaterial( GluonGraphics::MaterialInstance* material )
{
    d->material = material;

    GluonGraphics::RenderTarget *target = GluonGraphics::Engine::instance()->mainRenderTarget();
    if( target )
        target->setMaterialInstance(material);
}

Q_EXPORT_PLUGIN2( gluon_component_cameracontroller, GluonEngine::CameraControllerComponent );

#include "cameracontrollercomponent.moc"
<|endoftext|>


<commit_before>#include "ExtendedInventoryScreen.h"

#include "InventoryTransitions.h"
#include "../../creative/CreativeTab.h"

#include "com/mojang/minecraftpe/client/MinecraftClient.h"
#include "com/mojang/minecraftpe/client/gui/NinePatchLayer.h"
#include "com/mojang/minecraftpe/client/gui/IntRectangle.h"
#include "com/mojang/minecraftpe/client/gui/ImageWithBackground.h"
#include "com/mojang/minecraftpe/client/gui/InventoryTab.h"
#include "com/mojang/minecraftpe/client/settings/Options.h"
#include "com/mojang/minecraftpe/client/renderer/Tessellator.h"
#include "com/mojang/minecraftpe/client/renderer/texture/TextureGroup.h"
#include "com/mojang/minecraftpe/client/renderer/entity/ItemRenderer.h"
#include "com/mojang/minecraftpe/client/renderer/ShaderColor.h"
#include "com/mojang/minecraftpe/world/item/ItemInstance.h"

ExtendedInventoryScreen::ExtendedInventoryScreen(MinecraftClient& client, std::vector<CreativeTab*> creativeTabs)
	: Screen(client)
{
	closeButton = NULL;
	backgroundLayer = NULL;
	leftButtonLayer = NULL;
	rightButtonLayer = NULL;
	ownedTabs = creativeTabs;
	testPane = NULL;
}

bool ExtendedInventoryScreen::renderGameBehind() const
{
	return mcClient->getOptions()->getFancyGraphics();
}

bool ExtendedInventoryScreen::closeOnPlayerHurt() const
{
	return true;
}

void ExtendedInventoryScreen::init()
{
	if(!closeButton)
	{
		InventoryTransitions::init(this);

		NinePatchFactory factory (mcClient->getTextures(), "gui/spritesheet.png");

		backgroundLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({34, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		leftButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({49, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		rightButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({65, 55, 14, 14}, 3, 3, 14.0F, 14.0F));

		closeButton = std::make_shared<ImageWithBackground>(2);
		closeButton->init(mcClient->getTextures(), 28, 28, {49, 43, 14, 14}, {49, 43, 14, 14}, 2, 2, "gui/spritesheet.png");
		closeButton->setImageDef({mcClient->getTextures()->getTexture("gui/spritesheet.png", TextureLocation::Default), 0, 1, 18.0F, 18.0F, {60, 0, 18, 18}, true}, true);

		for(int tab = 0; tab < ownedTabs.size(); tab++)
		{
			renderedTabs.emplace_back(createInventoryTab(tab + 3, ((tab < 4) ? false : true)));
		}

		selectedTabIndex = 0;

		buttonList.emplace_back(closeButton);
	}
}

void ExtendedInventoryScreen::render(int i1, int i2, float f1)
{
	if(renderGameBehind())
		renderBackground(1);
	else
		renderDirtBackground();

	renderToolBar(f1, 1.0F, false);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex)
		{
			renderedTabs[tab]->renderBg(mcClient, i1, i2);
			drawTabIcon(ownedTabs[tab], renderedTabs[tab], renderedTabs[tab]->pressed, false);
		}
	}

	backgroundLayer->draw(Tessellator::instance, backgroundLayer->xPosition, backgroundLayer->yPosition);

	renderedTabs[selectedTabIndex]->renderBg(mcClient, i1, i2);
	drawTabIcon(ownedTabs[selectedTabIndex], renderedTabs[selectedTabIndex], renderedTabs[selectedTabIndex]->pressed, true);

	InventoryTransitions::render(this, i1, i2, f1);

	Screen::render(i1, i2, f1);

	currentShaderColor.setColor(Color::WHITE);

	fill(backgroundLayer->xPosition + 5, backgroundLayer->yPosition + 4, width - 38, height - 27, {0.2F, 0.2F, 0.2F, 1.0F});

	testPane->render(i1, i2, f1, mcClient);

	renderOnSelectItemNameText(width, mcClient->getFont(), height - 41);
}

void ExtendedInventoryScreen::setupPositions()
{
	backgroundLayer->xPosition = 31;
	backgroundLayer->yPosition = 2;
	backgroundLayer->setSize((float)(width - 26 - 28) - 4.0F - 6.0F, (float)height - 25.0F);

	closeButton->xPosition = backgroundLayer->xPosition - 26;
	closeButton->yPosition = backgroundLayer->yPosition;

	closeButton->setSize(29, 28);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(!renderedTabs[tab]->isRight)
		{
			renderedTabs[tab]->xPosition = backgroundLayer->xPosition - 26;
			renderedTabs[tab]->yPosition = height - 25 - 29 - (tab * 31);
		}
		else
		{
			renderedTabs[tab]->xPosition = width - 6 - 29;
			renderedTabs[tab]->yPosition = height - 25 - 29 - ((tab - 4) * 31);
		}
		renderedTabs[tab]->width = 29;
		renderedTabs[tab]->height = 29;
	}

	testPane->xPosition = backgroundLayer->xPosition + 11;
	testPane->yPosition = backgroundLayer->yPosition + 8;

	InventoryTransitions::setupPositions(this);
}

void ExtendedInventoryScreen::_buttonClicked(Button& button)
{
	InventoryTransitions::_buttonClicked(this, button);

	if(button.id == closeButton->id)
		InventoryTransitions::pushPreviousScreen(this);
}

void ExtendedInventoryScreen::_pointerReleased(int x, int y)
{
	Screen::_pointerReleased(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex && renderedTabs[tab]->isInside(x, y) && renderedTabs[tab]->pressed)
			selectedTabIndex = tab;

		renderedTabs[tab]->pressed = false;
	}
}

void ExtendedInventoryScreen::_pointerPressed(int x, int y)
{
	Screen::_pointerPressed(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(renderedTabs[tab]->isInside(x, y))
		{
			renderedTabs[tab]->pressed = true;
			return;
		}
	}
}

void ExtendedInventoryScreen::handleBackEvent(bool b1)
{
	if(!b1)
		InventoryTransitions::pushPreviousScreen(this);
}

bool ExtendedInventoryScreen::isModal() const
{
	return true;
}

void ExtendedInventoryScreen::tick()
{

}

std::string ExtendedInventoryScreen::getScreenName()
{
	return "extended_creative_screen";
}

std::shared_ptr<InventoryTab> ExtendedInventoryScreen::createInventoryTab(int id, bool isRight)
{
	NinePatchLayer* buttonLayer = isRight ? rightButtonLayer.get() : leftButtonLayer.get();
	std::shared_ptr<InventoryTab> button = std::make_shared<InventoryTab>(id, "", buttonLayer, isRight);
	button->setOverrideScreenRendering(true);
	return button;
}

void ExtendedInventoryScreen::drawTabIcon(CreativeTab* ownedTab, std::shared_ptr<InventoryTab> imageButton, bool isPressed, bool isSelected)
{
	ItemRenderer::getInstance()->renderGuiItemNew(ownedTab->getTabIcon(), 0, ((float)imageButton->xPosition + (float)((imageButton->width / 2) - 8) + (isPressed ? 1.0F : 0.7F)), ((float)imageButton->yPosition + (float)((imageButton->height / 2) - 8)), 1.0F, (isSelected ? 1.0F : 0.7F), (((float)imageButton->width) - (isPressed ? 2.0F : 0.0F)) * 0.04F, false);
}

bool ExtendedInventoryScreen::addItem(Touch::InventoryPane& pane, int slot)
{
	return true;
}

bool ExtendedInventoryScreen::isAllowed(int slot)
{
	return true;
}

std::vector<const ItemInstance*> ExtendedInventoryScreen::getItems(const Touch::InventoryPane& pane)
{
	return itemVector;
}<commit_msg>woops I need this<commit_after>#include "ExtendedInventoryScreen.h"

#include "InventoryTransitions.h"
#include "../../creative/CreativeTab.h"

#include "com/mojang/minecraftpe/client/MinecraftClient.h"
#include "com/mojang/minecraftpe/client/gui/NinePatchLayer.h"
#include "com/mojang/minecraftpe/client/gui/IntRectangle.h"
#include "com/mojang/minecraftpe/client/gui/ImageWithBackground.h"
#include "com/mojang/minecraftpe/client/gui/InventoryTab.h"
#include "com/mojang/minecraftpe/client/settings/Options.h"
#include "com/mojang/minecraftpe/client/renderer/Tessellator.h"
#include "com/mojang/minecraftpe/client/renderer/texture/TextureGroup.h"
#include "com/mojang/minecraftpe/client/renderer/entity/ItemRenderer.h"
#include "com/mojang/minecraftpe/client/renderer/ShaderColor.h"
#include "com/mojang/minecraftpe/world/item/ItemInstance.h"

ExtendedInventoryScreen::ExtendedInventoryScreen(MinecraftClient& client, std::vector<CreativeTab*> creativeTabs)
	: Screen(client)
{
	closeButton = NULL;
	backgroundLayer = NULL;
	leftButtonLayer = NULL;
	rightButtonLayer = NULL;
	ownedTabs = creativeTabs;
	testPane = NULL;
}

bool ExtendedInventoryScreen::renderGameBehind() const
{
	return mcClient->getOptions()->getFancyGraphics();
}

bool ExtendedInventoryScreen::closeOnPlayerHurt() const
{
	return true;
}

void ExtendedInventoryScreen::init()
{
	if(!closeButton)
	{
		InventoryTransitions::init(this);

		NinePatchFactory factory (mcClient->getTextures(), "gui/spritesheet.png");

		backgroundLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({34, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		leftButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({49, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		rightButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({65, 55, 14, 14}, 3, 3, 14.0F, 14.0F));

		closeButton = std::make_shared<ImageWithBackground>(2);
		closeButton->init(mcClient->getTextures(), 28, 28, {49, 43, 14, 14}, {49, 43, 14, 14}, 2, 2, "gui/spritesheet.png");
		closeButton->setImageDef({mcClient->getTextures()->getTexture("gui/spritesheet.png", TextureLocation::Default), 0, 1, 18.0F, 18.0F, {60, 0, 18, 18}, true}, true);

		for(int tab = 0; tab < ownedTabs.size(); tab++)
		{
			renderedTabs.emplace_back(createInventoryTab(tab + 3, ((tab < 4) ? false : true)));
		}

		selectedTabIndex = 0;

		buttonList.emplace_back(closeButton);
	}
}

void ExtendedInventoryScreen::render(int i1, int i2, float f1)
{
	if(renderGameBehind())
		renderBackground(1);
	else
		renderDirtBackground();

	renderToolBar(f1, 1.0F, false);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex)
		{
			renderedTabs[tab]->renderBg(mcClient, i1, i2);
			drawTabIcon(ownedTabs[tab], renderedTabs[tab], renderedTabs[tab]->pressed, false);
		}
	}

	backgroundLayer->draw(Tessellator::instance, backgroundLayer->xPosition, backgroundLayer->yPosition);

	renderedTabs[selectedTabIndex]->renderBg(mcClient, i1, i2);
	drawTabIcon(ownedTabs[selectedTabIndex], renderedTabs[selectedTabIndex], renderedTabs[selectedTabIndex]->pressed, true);

	InventoryTransitions::render(this, i1, i2, f1);

	Screen::render(i1, i2, f1);

	currentShaderColor.setColor(Color::WHITE);

	fill(backgroundLayer->xPosition + 5, backgroundLayer->yPosition + 4, width - 38, height - 27, {0.2F, 0.2F, 0.2F, 1.0F});

	testPane->render(i1, i2, f1, mcClient);

	renderOnSelectItemNameText(width, mcClient->getFont(), height - 41);
}

void ExtendedInventoryScreen::setupPositions()
{
	backgroundLayer->xPosition = 31;
	backgroundLayer->yPosition = 2;
	backgroundLayer->setSize((float)(width - 26 - 28) - 4.0F - 6.0F, (float)height - 25.0F);

	closeButton->xPosition = backgroundLayer->xPosition - 26;
	closeButton->yPosition = backgroundLayer->yPosition;

	closeButton->setSize(29, 28);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(!renderedTabs[tab]->isRight)
		{
			renderedTabs[tab]->xPosition = backgroundLayer->xPosition - 26;
			renderedTabs[tab]->yPosition = height - 25 - 29 - (tab * 31);
		}
		else
		{
			renderedTabs[tab]->xPosition = width - 6 - 29;
			renderedTabs[tab]->yPosition = height - 25 - 29 - ((tab - 4) * 31);
		}
		renderedTabs[tab]->width = 29;
		renderedTabs[tab]->height = 29;
	}

	testPane = std::shared_ptr<Touch::InventoryPane>(new Touch::InventoryPane(this, *mcClient, {backgroundLayer->xPosition + 11, backgroundLayer->yPosition + 8, width - backgroundLayer->xPosition - 53, height - 41}, 1, 1.0F, 5, 26, 1, false, true, false));

	testPane->xPosition = backgroundLayer->xPosition + 11;
	testPane->yPosition = backgroundLayer->yPosition + 8;
	testPane->width = width - backgroundLayer->xPosition - 53;
	testPane->height = height - 41;

	InventoryTransitions::setupPositions(this);
}

void ExtendedInventoryScreen::_buttonClicked(Button& button)
{
	InventoryTransitions::_buttonClicked(this, button);

	if(button.id == closeButton->id)
		InventoryTransitions::pushPreviousScreen(this);
}

void ExtendedInventoryScreen::_pointerReleased(int x, int y)
{
	Screen::_pointerReleased(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex && renderedTabs[tab]->isInside(x, y) && renderedTabs[tab]->pressed)
			selectedTabIndex = tab;

		renderedTabs[tab]->pressed = false;
	}
}

void ExtendedInventoryScreen::_pointerPressed(int x, int y)
{
	Screen::_pointerPressed(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(renderedTabs[tab]->isInside(x, y))
		{
			renderedTabs[tab]->pressed = true;
			return;
		}
	}
}

void ExtendedInventoryScreen::handleBackEvent(bool b1)
{
	if(!b1)
		InventoryTransitions::pushPreviousScreen(this);
}

bool ExtendedInventoryScreen::isModal() const
{
	return true;
}

void ExtendedInventoryScreen::tick()
{

}

std::string ExtendedInventoryScreen::getScreenName()
{
	return "extended_creative_screen";
}

std::shared_ptr<InventoryTab> ExtendedInventoryScreen::createInventoryTab(int id, bool isRight)
{
	NinePatchLayer* buttonLayer = isRight ? rightButtonLayer.get() : leftButtonLayer.get();
	std::shared_ptr<InventoryTab> button = std::make_shared<InventoryTab>(id, "", buttonLayer, isRight);
	button->setOverrideScreenRendering(true);
	return button;
}

void ExtendedInventoryScreen::drawTabIcon(CreativeTab* ownedTab, std::shared_ptr<InventoryTab> imageButton, bool isPressed, bool isSelected)
{
	ItemRenderer::getInstance()->renderGuiItemNew(ownedTab->getTabIcon(), 0, ((float)imageButton->xPosition + (float)((imageButton->width / 2) - 8) + (isPressed ? 1.0F : 0.7F)), ((float)imageButton->yPosition + (float)((imageButton->height / 2) - 8)), 1.0F, (isSelected ? 1.0F : 0.7F), (((float)imageButton->width) - (isPressed ? 2.0F : 0.0F)) * 0.04F, false);
}

bool ExtendedInventoryScreen::addItem(Touch::InventoryPane& pane, int slot)
{
	return true;
}

bool ExtendedInventoryScreen::isAllowed(int slot)
{
	return true;
}

std::vector<const ItemInstance*> ExtendedInventoryScreen::getItems(const Touch::InventoryPane& pane)
{
	std::vector<const ItemInstance*> itemVector = {new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1), new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1)};
	return itemVector;
}<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2019-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#ifdef _MSC_VER
#pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#ifdef IVW_ENABLE_MSVC_MEM_LEAK_TEST
#include <vld.h>
#endif
#endif

#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/util/logcentral.h>
#include <inviwo/core/util/consolelogger.h>
#include <inviwo/core/common/coremodulesharedlibrary.h>
#include <modules/base/basemodulesharedlibrary.h>
#include <inviwo/dataframe/dataframemodulesharedlibrary.h>
#include <modules/json/jsonmodulesharedlibrary.h>
#include <modules/python3/python3modulesharedlibrary.h>
#include <inviwo/dataframepython/dataframepythonmodulesharedlibrary.h>

#include <inviwo/testutil/configurablegtesteventlistener.h>

#include <warn/push>
#include <warn/ignore/all>
#include <gtest/gtest.h>
#include <warn/pop>

int main(int argc, char** argv) {
    using namespace inviwo;
    LogCentral::init();
    auto logger = std::make_shared<ConsoleLogger>();
    LogCentral::getPtr()->setVerbosity(LogVerbosity::Error);
    LogCentral::getPtr()->registerLogger(logger);
    InviwoApplication app(argc, argv, "Inviwo-Unittests-DataFramePython");

    {
        std::vector<std::unique_ptr<InviwoModuleFactoryObject>> modules;
        modules.emplace_back(createInviwoCore());
        modules.emplace_back(createBaseModule());
        modules.emplace_back(createJSONModule());
        modules.emplace_back(createDataFrameModule());
        modules.emplace_back(createPython3Module());
        modules.emplace_back(createDataFramePythonModule());
        app.registerModules(std::move(modules));
    }

    app.processFront();

    int ret = -1;
    {
#ifdef IVW_ENABLE_MSVC_MEM_LEAK_TEST
        VLDDisable();
        ::testing::InitGoogleTest(&argc, argv);
        VLDEnable();
#else
        ::testing::InitGoogleTest(&argc, argv);
#endif
        inviwo::ConfigurableGTestEventListener::setup();
        ret = RUN_ALL_TESTS();
    }
    return ret;
}
<commit_msg>Testing: dependency fix in DataFramePython unit test<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2019-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#ifdef _MSC_VER
#pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#ifdef IVW_ENABLE_MSVC_MEM_LEAK_TEST
#include <vld.h>
#endif
#endif

#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/util/logcentral.h>
#include <inviwo/core/util/consolelogger.h>
#include <inviwo/core/common/coremodulesharedlibrary.h>
#include <modules/base/basemodulesharedlibrary.h>
#include <inviwo/dataframe/dataframemodulesharedlibrary.h>
#include <modules/json/jsonmodulesharedlibrary.h>
#include <modules/python3/python3modulesharedlibrary.h>
#include <inviwo/dataframepython/dataframepythonmodulesharedlibrary.h>
#include <modules/brushingandlinking/brushingandlinkingmodulesharedlibrary.h>

#include <inviwo/testutil/configurablegtesteventlistener.h>

#include <warn/push>
#include <warn/ignore/all>
#include <gtest/gtest.h>
#include <warn/pop>

int main(int argc, char** argv) {
    using namespace inviwo;
    LogCentral::init();
    auto logger = std::make_shared<ConsoleLogger>();
    LogCentral::getPtr()->setVerbosity(LogVerbosity::Error);
    LogCentral::getPtr()->registerLogger(logger);
    InviwoApplication app(argc, argv, "Inviwo-Unittests-DataFramePython");

    {
        std::vector<std::unique_ptr<InviwoModuleFactoryObject>> modules;
        modules.emplace_back(createInviwoCore());
        modules.emplace_back(createBaseModule());
        modules.emplace_back(createJSONModule());
        modules.emplace_back(createDataFrameModule());
        modules.emplace_back(createBrushingAndLinkingModule());
        modules.emplace_back(createPython3Module());
        modules.emplace_back(createDataFramePythonModule());
        app.registerModules(std::move(modules));
    }

    app.processFront();

    int ret = -1;
    {
#ifdef IVW_ENABLE_MSVC_MEM_LEAK_TEST
        VLDDisable();
        ::testing::InitGoogleTest(&argc, argv);
        VLDEnable();
#else
        ::testing::InitGoogleTest(&argc, argv);
#endif
        inviwo::ConfigurableGTestEventListener::setup();
        ret = RUN_ALL_TESTS();
    }
    return ret;
}
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Collision/TriangleMeshTriangleMeshDcdContact.h"
#include "SurgSim/Collision/UnitTests/ContactCalculationTestsCommon.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Timer.h"

using SurgSim::Math::MeshShape;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;

namespace SurgSim
{
namespace Collision
{

TEST(TriangleMeshTriangleMeshContactCalculationPerformanceTests, IntersectionTest)
{

	auto runtime = std::make_shared<SurgSim::Framework::Runtime>("config.txt");
	auto meshA = std::make_shared<MeshShape>();
	meshA->load("MeshShapeData/stapler_collision.ply");

	auto meshB = std::make_shared<MeshShape>();
	meshB->load("MeshShapeData/wound_deformable.ply");

	std::shared_ptr<ShapeCollisionRepresentation> meshARep =
		std::make_shared<ShapeCollisionRepresentation>("Collision Mesh 0");
	meshARep->setShape(meshA);

	std::shared_ptr<ShapeCollisionRepresentation> meshBRep =
		std::make_shared<ShapeCollisionRepresentation>("Collision Mesh 1");
	meshBRep->setShape(meshB);

	TriangleMeshTriangleMeshDcdContact calcContact;
	std::shared_ptr<CollisionPair> pair = std::make_shared<CollisionPair>(meshARep, meshBRep);

	Framework::Timer timer;
	int loops = 100;
	size_t contacts = 0;
	for (int i = 0 ; i < loops; ++i)
	{
		pair->clearContacts();
		meshARep->getCollisions().unsafeGet().clear();
		meshBRep->getCollisions().unsafeGet().clear();
		RigidTransform3d pose =
			Math::makeRigidTransform(Math::makeRotationQuaternion(2.0 * M_PI * i / loops, Vector3d::UnitX().eval()),
			Vector3d(i, -1.5 * i, 0.0));
		meshARep->setLocalPose(pose);
		meshBRep->setLocalPose(pose);
		timer.beginFrame();
		calcContact.calculateContact(pair);
		timer.endFrame();
		contacts += pair->getContacts().size();
	}

	RecordProperty("FrameRate", boost::to_string(loops / timer.getCumulativeTime()));
	RecordProperty("Duration", boost::to_string(timer.getCumulativeTime()));
	RecordProperty("Loops", boost::to_string(loops));
}

}
}
<commit_msg>Fix cpplint warning<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Collision/TriangleMeshTriangleMeshDcdContact.h"
#include "SurgSim/Collision/UnitTests/ContactCalculationTestsCommon.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Timer.h"

using SurgSim::Math::MeshShape;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;

namespace SurgSim
{
namespace Collision
{

TEST(TriangleMeshTriangleMeshContactCalculationPerformanceTests, IntersectionTest)
{

	auto runtime = std::make_shared<SurgSim::Framework::Runtime>("config.txt");
	auto meshA = std::make_shared<MeshShape>();
	meshA->load("MeshShapeData/stapler_collision.ply");

	auto meshB = std::make_shared<MeshShape>();
	meshB->load("MeshShapeData/wound_deformable.ply");

	std::shared_ptr<ShapeCollisionRepresentation> meshARep =
		std::make_shared<ShapeCollisionRepresentation>("Collision Mesh 0");
	meshARep->setShape(meshA);

	std::shared_ptr<ShapeCollisionRepresentation> meshBRep =
		std::make_shared<ShapeCollisionRepresentation>("Collision Mesh 1");
	meshBRep->setShape(meshB);

	TriangleMeshTriangleMeshDcdContact calcContact;
	std::shared_ptr<CollisionPair> pair = std::make_shared<CollisionPair>(meshARep, meshBRep);

	Framework::Timer timer;
	int loops = 100;
	size_t contacts = 0;
	for (int i = 0 ; i < loops; ++i)
	{
		pair->clearContacts();
		meshARep->getCollisions().unsafeGet().clear();
		meshBRep->getCollisions().unsafeGet().clear();
		RigidTransform3d pose =
			Math::makeRigidTransform(Math::makeRotationQuaternion(2.0 * M_PI * i / loops, Vector3d::UnitX().eval()),
			Vector3d(i, -1.5 * i, 0.0));
		meshARep->setLocalPose(pose);
		meshBRep->setLocalPose(pose);
		timer.beginFrame();
		calcContact.calculateContact(pair);
		timer.endFrame();
		contacts += pair->getContacts().size();
	}

	RecordProperty("FrameRate", boost::to_string(loops / timer.getCumulativeTime()));
	RecordProperty("Duration", boost::to_string(timer.getCumulativeTime()));
	RecordProperty("Loops", boost::to_string(loops));
}

}
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/PoseStamped.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <tf/tf.h>
#include <iostream>

#include "waypoint_follower/libwaypoint_follower.h"

namespace
{
geometry_msgs::Twist _current_velocity;

const std::string SIMULATION_FRAME = "sim_base_link";
const std::string MAP_FRAME = "map";

geometry_msgs::Pose _initial_pose;
bool _initial_set = false;
bool _pose_set = false;
bool _waypoint_set = false;
WayPoints _current_waypoints;
ros::Publisher g_odometry_publisher;
ros::Publisher g_velocity_publisher;

constexpr int LOOP_RATE = 50; // 50Hz

void CmdCallBack(const geometry_msgs::TwistStampedConstPtr &msg, double accel_rate)
{

  static double previous_linear_velocity = 0;

  if(_current_velocity.linear.x < msg->twist.linear.x)
  {
    _current_velocity.linear.x = previous_linear_velocity + accel_rate / (double)LOOP_RATE;

    if(_current_velocity.linear.x > msg->twist.linear.x)
    {
      _current_velocity.linear.x = msg->twist.linear.x;
    }
  }
  else
  {
    _current_velocity.linear.x = previous_linear_velocity - accel_rate / (double)LOOP_RATE;

    if(_current_velocity.linear.x < msg->twist.linear.x)
    {
      _current_velocity.linear.x = msg->twist.linear.x;
    }
  }

  previous_linear_velocity = _current_velocity.linear.x;

  _current_velocity.angular.z = msg->twist.angular.z;

  //_current_velocity = msg->twist;
}

void getTransformFromTF(const std::string parent_frame, const std::string child_frame, tf::StampedTransform &transform)
{
  static tf::TransformListener listener;

  while (1)
  {
    try
    {
      listener.lookupTransform(parent_frame, child_frame, ros::Time(0), transform);
      break;
    }
    catch (tf::TransformException ex)
    {
      ROS_ERROR("%s", ex.what());
      ros::Duration(1.0).sleep();
    }
  }
}

void initialposeCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr &input)
{
  tf::StampedTransform transform;
  getTransformFromTF(MAP_FRAME, "world", transform);

  _initial_pose.position.x = input->pose.pose.position.x + transform.getOrigin().x();
  _initial_pose.position.y = input->pose.pose.position.y + transform.getOrigin().y();
  _initial_pose.position.z = input->pose.pose.position.z + transform.getOrigin().z();
  _initial_pose.orientation = input->pose.pose.orientation;

  _initial_set = true;
  _pose_set = false;
}

void callbackFromPoseStamped(const geometry_msgs::PoseStampedConstPtr &msg)
{
  _initial_pose = msg->pose;
  _initial_set = true;
}

void waypointCallback(const waypoint_follower::laneConstPtr &msg)
{
  // _path_og.setPath(msg);
  _current_waypoints.setPath(*msg);
  _waypoint_set = true;
  //ROS_INFO_STREAM("waypoint subscribed");
}

void publishOdometry()
{
  static ros::Time current_time = ros::Time::now();
  static ros::Time last_time = ros::Time::now();
  static geometry_msgs::Pose pose;
  static double th = 0;
  static tf::TransformBroadcaster odom_broadcaster;

  if (!_pose_set)
  {
    pose.position = _initial_pose.position;
    pose.orientation = _initial_pose.orientation;
    th = tf::getYaw(pose.orientation);
    ROS_INFO_STREAM("pose set : (" << pose.position.x << " " << pose.position.y << " " << pose.position.z << " " << th
                                   << ")");
    _pose_set = true;
  }

  /*int closest_waypoint = getClosestWaypoint(_current_waypoints.getCurrentWaypoints(), pose);
  if (closest_waypoint == -1)
  {
    ROS_INFO("cannot publish odometry because closest waypoint is -1.");
    return;
  }
  else
  {
    pose.position.z = _current_waypoints.getWaypointPosition(closest_waypoint).z;
  }
*/if(_waypoint_set)
    pose.position.z = _current_waypoints.getWaypointPosition(1).z;

  double vx = _current_velocity.linear.x;
  double vth = _current_velocity.angular.z;
  current_time = ros::Time::now();

  // compute odometry in a typical way given the velocities of the robot
  double dt = (current_time - last_time).toSec();
  double delta_x = (vx * cos(th)) * dt;
  double delta_y = (vx * sin(th)) * dt;
  double delta_th = vth * dt;

  pose.position.x += delta_x;
  pose.position.y += delta_y;
  th += delta_th;
  pose.orientation = tf::createQuaternionMsgFromYaw(th);

  // std::cout << "delta (x y th) : (" << delta_x << " " << delta_y << " " << delta_th << ")" << std::endl;
  // std::cout << "current_velocity(linear.x angular.z) : (" << _current_velocity.linear.x << " " <<
  // _current_velocity.angular.z << ")"<< std::endl;
  //    std::cout << "current_pose : (" << pose.position.x << " " << pose.position.y<< " " << pose.position.z << " " <<
  //    th << ")" << std::endl << std::endl;

  // first, we'll publish the transform over tf
  geometry_msgs::TransformStamped odom_trans;
  odom_trans.header.stamp = current_time;
  odom_trans.header.frame_id = MAP_FRAME;
  odom_trans.child_frame_id = SIMULATION_FRAME;

  odom_trans.transform.translation.x = pose.position.x;
  odom_trans.transform.translation.y = pose.position.y;
  odom_trans.transform.translation.z = pose.position.z;
  odom_trans.transform.rotation = pose.orientation;

  // send the transform
  odom_broadcaster.sendTransform(odom_trans);

  // next, we'll publish the odometry message over ROS
  std_msgs::Header h;
  h.stamp = current_time;
  h.frame_id = MAP_FRAME;

  geometry_msgs::PoseStamped ps;
  ps.header = h;
  ps.pose = pose;

  geometry_msgs::TwistStamped ts;
  ts.header = h;
  ts.twist.linear.x = vx;
  ts.twist.angular.z = vth;

  // publish the message
  g_odometry_publisher.publish(ps);
  g_velocity_publisher.publish(ts);

  last_time = current_time;
}
}
int main(int argc, char **argv)
{
  ros::init(argc, argv, "wf_simulator");

  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  std::string initialize_source;
  private_nh.getParam("initialize_source", initialize_source);
  ROS_INFO_STREAM("initialize_source : " << initialize_source);

  double accel_rate;
  private_nh.param("accel_rate",accel_rate,double(1.0));
  ROS_INFO_STREAM("accel_rate : " << accel_rate);
  // publish topic
  g_odometry_publisher = nh.advertise<geometry_msgs::PoseStamped>("sim_pose", 10);
  g_velocity_publisher = nh.advertise<geometry_msgs::TwistStamped>("sim_velocity", 10);

  // subscribe topic
  ros::Subscriber cmd_subscriber = nh.subscribe<geometry_msgs::TwistStamped>("twist_cmd", 10, boost::bind(CmdCallBack, _1, accel_rate));
  ros::Subscriber waypoint_subcscriber = nh.subscribe("base_waypoints", 10, waypointCallback);
  ros::Subscriber initialpose_subscriber;

  if (initialize_source == "Rviz")
  {
    initialpose_subscriber = nh.subscribe("initialpose", 10, initialposeCallback);
  }
  else if (initialize_source == "ndt_localizer")
  {
    initialpose_subscriber = nh.subscribe("ndt_pose", 10, callbackFromPoseStamped);
  }
  else if (initialize_source == "GNSS")
  {
    initialpose_subscriber = nh.subscribe("gnss_pose", 10, callbackFromPoseStamped);
  }
  else
  {
    ROS_INFO("Set pose initializer!!");
  }

  ros::Rate loop_rate(LOOP_RATE);
  while (ros::ok())
  {
    ros::spinOnce();  // check subscribe topic

    /*if (!_waypoint_set)
    {
      loop_rate.sleep();
      continue;
    }*/

    if (!_initial_set)
    {
      loop_rate.sleep();
      continue;
    }

    publishOdometry();

    loop_rate.sleep();
  }

  return 0;
}
<commit_msg>Add subscription for closest waypoint<commit_after>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/PoseStamped.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <tf/tf.h>
#include <iostream>
#include <std_msgs/Int32.h>

#include "waypoint_follower/libwaypoint_follower.h"

namespace
{
geometry_msgs::Twist _current_velocity;

const std::string SIMULATION_FRAME = "sim_base_link";
const std::string MAP_FRAME = "map";

geometry_msgs::Pose _initial_pose;
bool _initial_set = false;
bool _pose_set = false;
bool _waypoint_set = false;
bool g_is_closest_waypoint_subscribed = false;
WayPoints _current_waypoints;
ros::Publisher g_odometry_publisher;
ros::Publisher g_velocity_publisher;
int32_t g_closest_waypoint = -1;

constexpr int LOOP_RATE = 50; // 50Hz

void CmdCallBack(const geometry_msgs::TwistStampedConstPtr &msg, double accel_rate)
{

  static double previous_linear_velocity = 0;

  if(_current_velocity.linear.x < msg->twist.linear.x)
  {
    _current_velocity.linear.x = previous_linear_velocity + accel_rate / (double)LOOP_RATE;

    if(_current_velocity.linear.x > msg->twist.linear.x)
    {
      _current_velocity.linear.x = msg->twist.linear.x;
    }
  }
  else
  {
    _current_velocity.linear.x = previous_linear_velocity - accel_rate / (double)LOOP_RATE;

    if(_current_velocity.linear.x < msg->twist.linear.x)
    {
      _current_velocity.linear.x = msg->twist.linear.x;
    }
  }

  previous_linear_velocity = _current_velocity.linear.x;

  _current_velocity.angular.z = msg->twist.angular.z;

  //_current_velocity = msg->twist;
}

void getTransformFromTF(const std::string parent_frame, const std::string child_frame, tf::StampedTransform &transform)
{
  static tf::TransformListener listener;

  while (1)
  {
    try
    {
      listener.lookupTransform(parent_frame, child_frame, ros::Time(0), transform);
      break;
    }
    catch (tf::TransformException ex)
    {
      ROS_ERROR("%s", ex.what());
      ros::Duration(1.0).sleep();
    }
  }
}

void initialposeCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr &input)
{
  tf::StampedTransform transform;
  getTransformFromTF(MAP_FRAME, "world", transform);

  _initial_pose.position.x = input->pose.pose.position.x + transform.getOrigin().x();
  _initial_pose.position.y = input->pose.pose.position.y + transform.getOrigin().y();
  _initial_pose.position.z = input->pose.pose.position.z + transform.getOrigin().z();
  _initial_pose.orientation = input->pose.pose.orientation;

  _initial_set = true;
  _pose_set = false;
}

void callbackFromPoseStamped(const geometry_msgs::PoseStampedConstPtr &msg)
{
  _initial_pose = msg->pose;
  _initial_set = true;
}

void waypointCallback(const waypoint_follower::laneConstPtr &msg)
{
  // _path_og.setPath(msg);
  _current_waypoints.setPath(*msg);
  _waypoint_set = true;
  //ROS_INFO_STREAM("waypoint subscribed");
}

void callbackFromClosestWaypoint(const std_msgs::Int32ConstPtr &msg)
{
  g_closest_waypoint = msg->data;
  g_is_closest_waypoint_subscribed = true;
}

void publishOdometry()
{
  static ros::Time current_time = ros::Time::now();
  static ros::Time last_time = ros::Time::now();
  static geometry_msgs::Pose pose;
  static double th = 0;
  static tf::TransformBroadcaster odom_broadcaster;

  if (!_pose_set)
  {
    pose.position = _initial_pose.position;
    pose.orientation = _initial_pose.orientation;
    th = tf::getYaw(pose.orientation);
    ROS_INFO_STREAM("pose set : (" << pose.position.x << " " << pose.position.y << " " << pose.position.z << " " << th
                                   << ")");
    _pose_set = true;
  }

  /*int closest_waypoint = getClosestWaypoint(_current_waypoints.getCurrentWaypoints(), pose);
  if (closest_waypoint == -1)
  {
    ROS_INFO("cannot publish odometry because closest waypoint is -1.");
    return;
  }
  else
  {
    pose.position.z = _current_waypoints.getWaypointPosition(closest_waypoint).z;
  }
*/if(_waypoint_set && g_is_closest_waypoint_subscribed)
    pose.position.z = _current_waypoints.getWaypointPosition(g_closest_waypoint).z;

  double vx = _current_velocity.linear.x;
  double vth = _current_velocity.angular.z;
  current_time = ros::Time::now();

  // compute odometry in a typical way given the velocities of the robot
  double dt = (current_time - last_time).toSec();
  double delta_x = (vx * cos(th)) * dt;
  double delta_y = (vx * sin(th)) * dt;
  double delta_th = vth * dt;

  pose.position.x += delta_x;
  pose.position.y += delta_y;
  th += delta_th;
  pose.orientation = tf::createQuaternionMsgFromYaw(th);

  // std::cout << "delta (x y th) : (" << delta_x << " " << delta_y << " " << delta_th << ")" << std::endl;
  // std::cout << "current_velocity(linear.x angular.z) : (" << _current_velocity.linear.x << " " <<
  // _current_velocity.angular.z << ")"<< std::endl;
  //    std::cout << "current_pose : (" << pose.position.x << " " << pose.position.y<< " " << pose.position.z << " " <<
  //    th << ")" << std::endl << std::endl;

  // first, we'll publish the transform over tf
  geometry_msgs::TransformStamped odom_trans;
  odom_trans.header.stamp = current_time;
  odom_trans.header.frame_id = MAP_FRAME;
  odom_trans.child_frame_id = SIMULATION_FRAME;

  odom_trans.transform.translation.x = pose.position.x;
  odom_trans.transform.translation.y = pose.position.y;
  odom_trans.transform.translation.z = pose.position.z;
  odom_trans.transform.rotation = pose.orientation;

  // send the transform
  odom_broadcaster.sendTransform(odom_trans);

  // next, we'll publish the odometry message over ROS
  std_msgs::Header h;
  h.stamp = current_time;
  h.frame_id = MAP_FRAME;

  geometry_msgs::PoseStamped ps;
  ps.header = h;
  ps.pose = pose;

  geometry_msgs::TwistStamped ts;
  ts.header = h;
  ts.twist.linear.x = vx;
  ts.twist.angular.z = vth;

  // publish the message
  g_odometry_publisher.publish(ps);
  g_velocity_publisher.publish(ts);

  last_time = current_time;
}
}
int main(int argc, char **argv)
{
  ros::init(argc, argv, "wf_simulator");

  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  std::string initialize_source;
  private_nh.getParam("initialize_source", initialize_source);
  ROS_INFO_STREAM("initialize_source : " << initialize_source);

  double accel_rate;
  private_nh.param("accel_rate",accel_rate,double(1.0));
  ROS_INFO_STREAM("accel_rate : " << accel_rate);
  // publish topic
  g_odometry_publisher = nh.advertise<geometry_msgs::PoseStamped>("sim_pose", 10);
  g_velocity_publisher = nh.advertise<geometry_msgs::TwistStamped>("sim_velocity", 10);

  // subscribe topic
  ros::Subscriber cmd_subscriber = nh.subscribe<geometry_msgs::TwistStamped>("twist_cmd", 10, boost::bind(CmdCallBack, _1, accel_rate));
  ros::Subscriber waypoint_subcscriber = nh.subscribe("base_waypoints", 10, waypointCallback);
  ros::Subscriber closest_sub = nh.subscribe("closest_waypoint", 10, callbackFromClosestWaypoint);
  ros::Subscriber initialpose_subscriber;

  if (initialize_source == "Rviz")
  {
    initialpose_subscriber = nh.subscribe("initialpose", 10, initialposeCallback);
  }
  else if (initialize_source == "ndt_localizer")
  {
    initialpose_subscriber = nh.subscribe("ndt_pose", 10, callbackFromPoseStamped);
  }
  else if (initialize_source == "GNSS")
  {
    initialpose_subscriber = nh.subscribe("gnss_pose", 10, callbackFromPoseStamped);
  }
  else
  {
    ROS_INFO("Set pose initializer!!");
  }

  ros::Rate loop_rate(LOOP_RATE);
  while (ros::ok())
  {
    ros::spinOnce();  // check subscribe topic

    /*if (!_waypoint_set)
    {
      loop_rate.sleep();
      continue;
    }*/

    if (!_initial_set)
    {
      loop_rate.sleep();
      continue;
    }

    publishOdometry();

    loop_rate.sleep();
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "Turret.h"
#include "vision/vision_processing.h"
#include "ports.h"

const int Zero_Max = 4;
const int Zero_Min = -1;
const int Left = 0;
const int Right = 1;
const float Turn_Speed = 0.1;

void Turret::Align(int Target) {
	while(Direction(Target)==Left)
	{
		Jaguar turret_XY_control_jag.Set(-1*Turn_Speed);
	}
	while(Direction(Target)==Right)
	{
		Jaguar turret_XY_control_jag.Set(Turn_Speed);
	}
}

int Difference(int target) {
	int Picture_Center = ; //Picture Width/2
	int Target_Center_Mass_X = ;//Add code Here
	return (Picture_Center-Target_Center_Mass_X);
}
int Direction(int Target) {
	int Diff=Difference(Target);
	if((Diff<10)&&(Diff>-10))
	{
		return 2;
	}
	else if (Diff>10)
	{
		return Left;
	}
	else
	{
		return Right;
	}
}
<commit_msg>Updated Turret.cpp to use new jag definitions<commit_after>#include "Turret.h"
#include "vision/vision_processing.h"
#include "ports.h"

const int Zero_Max = 4;
const int Zero_Min = -1;
const int Left = 0;
const int Right = 1;
const float Turn_Speed = 0.1;

void Turret::Align(int Target) {
    while(Direction(Target)==Left) {
        Jaguar turret_rotation_jag.Set(-1*Turn_Speed);
    }
    while(Direction(Target)==Right) {
        Jaguar turret_rotation_jag.Set(Turn_Speed);
    }
}

int Difference(int target) {
    int Picture_Center = ; //Picture Width/2
    int Target_Center_Mass_X = ;//Add code Here
    return (Picture_Center-Target_Center_Mass_X);
}

int Direction(int Target) {
    int Diff=Difference(Target);
    if((Diff<10)&&(Diff>-10)) {
        return 2;
    }
    else if (Diff>10) {
        return Left;
    }
    else {
        return Right;
    }
}

<|endoftext|>


<commit_before>#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory>
#include <pthread.h>
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "PlotWindow.h"
#include "../Utility/System.h"
#include "cli.h"
#include "gui.h"

volatile bool quit = false;
static void signalHandler(int){ quit = true; }

int argc;
char **argv;
const char *arg0; // program name without path
unsigned long terminalID = 0;

int main(int argc, char *argv[])
{
	::argc = argc;
	::argv = argv;
	arg0 = argv[0];
	for (const char *s = arg0; *s; ++s) if (*s == '/') arg0 = s+1;

	const char *t = getenv("WINDOWID");
	if (t){ auto tt = atoll(t); if (tt > 0) terminalID = (unsigned long)tt; }

	struct sigaction sa;
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_handler = signalHandler;
	sigaction(SIGINT,  &sa, 0);
	sigaction(SIGPIPE, &sa, 0);
	sigaction(SIGQUIT, &sa, 0);
	sigaction(SIGTERM, &sa, 0);

	pthread_t guiID = 0, cliID = 0;
	if (0 != pthread_create(&cliID, NULL, cli, NULL))
	{
		fprintf(stderr, "%s: can't create CLI thread\n", arg0);
		exit(1);
	}
	if (0 != pthread_create(&guiID, NULL, gui, NULL))
	{
		fprintf(stderr, "%s: can't create GUI thread\n", arg0);
		pthread_cancel(cliID);
		exit(1);
	}

	pthread_join(guiID, NULL); quit = true;
	struct timespec tv; tv.tv_nsec = 1000000000/2; tv.tv_sec = 0;
	if (pthread_timedjoin_np(cliID, NULL, &tv)) pthread_cancel(cliID);
	printf("\n");

	return 0;
}

<commit_msg>Handle WINDOWID not being set<commit_after>#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory>
#include <pthread.h>
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "PlotWindow.h"
#include "../Utility/System.h"
#include "cli.h"
#include "gui.h"

volatile bool quit = false;
static void signalHandler(int){ quit = true; }

int argc;
char **argv;
const char *arg0; // program name without path
unsigned long terminalID = 0;

static long findTerminalID()
{
	const char *t = getenv("WINDOWID");
	if (t)
	{
		auto tt = atoll(t);
		if (tt > 0) return (long)tt;
	}

	// Use the active window and hope that that is our terminal.
	// Matching by _NET_WM_PID did not work (because that is
	// the terminal's pid, not ours).
	Display *display = XOpenDisplay(0);
	if (!display) return 0;

	int dummy;
	Window w = 0;
	XGetInputFocus(display, &w, &dummy);
	if (w == None || w == PointerRoot) w = 0;

	XCloseDisplay(display);
	return w;
};

int main(int argc, char *argv[])
{
	::argc = argc;
	::argv = argv;
	arg0 = argv[0];
	for (const char *s = arg0; *s; ++s) if (*s == '/') arg0 = s+1;

	terminalID = findTerminalID();

	struct sigaction sa;
	memset(&sa, 0, sizeof(struct sigaction));
	sa.sa_handler = signalHandler;
	sigaction(SIGINT,  &sa, 0);
	sigaction(SIGPIPE, &sa, 0);
	sigaction(SIGQUIT, &sa, 0);
	sigaction(SIGTERM, &sa, 0);

	pthread_t guiID = 0, cliID = 0;
	if (0 != pthread_create(&cliID, NULL, cli, NULL))
	{
		fprintf(stderr, "%s: can't create CLI thread\n", arg0);
		exit(1);
	}
	if (0 != pthread_create(&guiID, NULL, gui, NULL))
	{
		fprintf(stderr, "%s: can't create GUI thread\n", arg0);
		pthread_cancel(cliID);
		exit(1);
	}

	pthread_join(guiID, NULL); quit = true;
	struct timespec tv; tv.tv_nsec = 1000000000/2; tv.tv_sec = 0;
	if (pthread_timedjoin_np(cliID, NULL, &tv)) pthread_cancel(cliID);
	printf("\n");

	return 0;
}

<|endoftext|>


<commit_before>#include <windows.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>

#include "Common.h"
#include "PrjHndl.h"
#include "WinAPI.h"

namespace WinAPI
{

HWND hWnd;
HMENU hMenu;
HMENU hSubMenu;

void SaveHWND(SDL_Window* const window)
{
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version)
	SDL_GetWindowWMInfo(window,&info);
	hWnd = info.info.win.window;
}

void CreateMenuBar(void)
{
	hMenu = CreateMenu();
	hSubMenu = CreatePopupMenu();
	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
	AppendMenu(hSubMenu, MF_STRING, MENUBAR_FILE_OPENPROJECT, "&Open project file");
	AppendMenu(hSubMenu, MF_STRING | MF_GRAYED, MENUBAR_FILE_SAVE, "&Save");
	AppendMenu(hSubMenu, MF_STRING | MF_GRAYED, MENUBAR_FILE_CLOSE, "&Close");
	AppendMenu(hSubMenu, MF_STRING, MENUBAR_FILE_EXIT, "&Exit");

	SetMenu(hWnd, hMenu);

	SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
}

void HandleWindowsEvent(const SDL_Event* const event)
{
	if (event->syswm.msg->msg.win.msg == WM_COMMAND)
	{
		switch (LOWORD(event->syswm.msg->msg.win.wParam))
		{
			case MENUBAR_FILE_OPENPROJECT:
			{
				char filename[500] = "";
				if (WinAPI::OpenProjectFilePrompt(filename) == true)
				{
					if (CurProject != NULL)
						delete CurProject;
					CurProject = new Project(filename, MainScreen);

					EnableMenuItem(hSubMenu, MENUBAR_FILE_SAVE, MF_ENABLED);
					EnableMenuItem(hSubMenu, MENUBAR_FILE_CLOSE, MF_ENABLED);

					//Process initial display
					MainScreen->Fill(0, 0, 0);
					CurProject->Redraw();
				}
				break;
			}
			case MENUBAR_FILE_SAVE:
			{
				CurProject->Save();
				break;
			}
			case MENUBAR_FILE_CLOSE:
			{
				delete CurProject;
				CurProject = NULL;	// Deleting an object does not NULL this pointer, so we have to do it ourselves
				EnableMenuItem(hSubMenu, MENUBAR_FILE_SAVE, MF_GRAYED);
				EnableMenuItem(hSubMenu, MENUBAR_FILE_CLOSE, MF_GRAYED);
				MainScreen->Fill(0, 0, 0);
				break;
			}
			case MENUBAR_FILE_EXIT:
			{
				exit(1);
			}
		}
	}
}

bool OpenProjectFilePrompt(char* const filepath)
{
	OPENFILENAME ofn;
        memset(&ofn, 0, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = NULL;
        ofn.lpstrFilter = TEXT("PlaneEd project file (*.txt)\0*.txt\0\0");
        ofn.nFilterIndex = 1;
        ofn.lpstrFile = filepath;
        ofn.nMaxFile = 500;
        ofn.Flags = OFN_FILEMUSTEXIST;
        bool bRes = GetOpenFileName(&ofn);
	return bRes;
}

}
<commit_msg>Neatening up menubar<commit_after>#include <windows.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>

#include "Common.h"
#include "PrjHndl.h"
#include "WinAPI.h"

namespace WinAPI
{

HWND hWnd;
HMENU hMenu;
HMENU hSubMenu;

void SaveHWND(SDL_Window* const window)
{
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version)
	SDL_GetWindowWMInfo(window,&info);
	hWnd = info.info.win.window;
}

void CreateMenuBar(void)
{
	hMenu = CreateMenu();
	hSubMenu = CreatePopupMenu();
	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
	AppendMenu(hSubMenu, MF_STRING, MENUBAR_FILE_OPENPROJECT, "&Open");
	AppendMenu(hSubMenu, MF_STRING | MF_GRAYED, MENUBAR_FILE_SAVE, "&Save");
	AppendMenu(hSubMenu, MF_STRING | MF_GRAYED, MENUBAR_FILE_CLOSE, "&Close");
	AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
	AppendMenu(hSubMenu, MF_STRING, MENUBAR_FILE_EXIT, "&Exit");

	SetMenu(hWnd, hMenu);

	SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
}

void HandleWindowsEvent(const SDL_Event* const event)
{
	if (event->syswm.msg->msg.win.msg == WM_COMMAND)
	{
		switch (LOWORD(event->syswm.msg->msg.win.wParam))
		{
			case MENUBAR_FILE_OPENPROJECT:
			{
				char filename[500] = "";
				if (WinAPI::OpenProjectFilePrompt(filename) == true)
				{
					if (CurProject != NULL)
						delete CurProject;
					CurProject = new Project(filename, MainScreen);

					EnableMenuItem(hSubMenu, MENUBAR_FILE_SAVE, MF_ENABLED);
					EnableMenuItem(hSubMenu, MENUBAR_FILE_CLOSE, MF_ENABLED);

					//Process initial display
					MainScreen->Fill(0, 0, 0);
					CurProject->Redraw();
				}
				break;
			}
			case MENUBAR_FILE_SAVE:
			{
				CurProject->Save();
				break;
			}
			case MENUBAR_FILE_CLOSE:
			{
				delete CurProject;
				CurProject = NULL;	// Deleting an object does not NULL this pointer, so we have to do it ourselves
				EnableMenuItem(hSubMenu, MENUBAR_FILE_SAVE, MF_GRAYED);
				EnableMenuItem(hSubMenu, MENUBAR_FILE_CLOSE, MF_GRAYED);
				MainScreen->Fill(0, 0, 0);
				break;
			}
			case MENUBAR_FILE_EXIT:
			{
				exit(1);
			}
		}
	}
}

bool OpenProjectFilePrompt(char* const filepath)
{
	OPENFILENAME ofn;
        memset(&ofn, 0, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = NULL;
        ofn.lpstrFilter = TEXT("PlaneEd project file (*.txt)\0*.txt\0\0");
        ofn.nFilterIndex = 1;
        ofn.lpstrFile = filepath;
        ofn.nMaxFile = 500;
        ofn.Flags = OFN_FILEMUSTEXIST;
        bool bRes = GetOpenFileName(&ofn);
	return bRes;
}

}
<|endoftext|>