<commit_before>#include <boost/test/unit_test.hpp>
#include <envire_maps/GridMap.hpp>

#include <chrono>

using namespace envire::maps;

double default_value = std::numeric_limits<double>::infinity();

BOOST_AUTO_TEST_CASE(test_grid_empty)
{
    GridMap<double> *grid = new GridMap<double>();

    // if the grid has size of (0,0)
    BOOST_CHECK_THROW(grid->at(Index(0,0)), std::exception);
    BOOST_CHECK_THROW(grid->getMax(), std::exception);
    BOOST_CHECK_THROW(grid->getMin(), std::exception);
    BOOST_CHECK_THROW(grid->clear(), std::exception);
    BOOST_CHECK_THROW(grid->moveBy(Index(0,0)), std::exception);

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_copy)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);
    grid->getOffset().translate(Eigen::Vector3d::Random(3));

    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();
            grid->at(x, y) = cell_value;
        }
    }

    GridMap<double> *grid_copy = new GridMap<double>(*grid);

    // check configuration
    BOOST_CHECK_EQUAL(grid_copy->getNumCells(), grid->getNumCells());
    BOOST_CHECK_EQUAL(grid_copy->getResolution(), grid->getResolution());
    BOOST_CHECK_EQUAL(grid_copy->getOffset().translation(), grid->getOffset().translation());
    BOOST_CHECK_EQUAL(grid_copy->getOffset().rotation(), grid->getOffset().rotation());

    // check default value
    BOOST_CHECK_EQUAL(grid_copy->getDefaultValue(), grid->getDefaultValue());

    // check cell value
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(x, y), grid_copy->at(x,y));
        }
    }

    delete grid;
    delete grid_copy;
}

BOOST_AUTO_TEST_CASE(test_grid_cell_access)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    // check default valuegitk --all

    BOOST_CHECK_EQUAL(grid->getDefaultValue(), std::numeric_limits<double>::infinity());

    // access cell that is not in grid = > should throw error
    BOOST_CHECK_THROW(grid->at(Index(num_cells.x(), num_cells.y())), std::exception);
    BOOST_CHECK_THROW(grid->at(Vector3d(grid->getSize().x(), grid->getSize().y(), 0)), std::exception);
    BOOST_CHECK_THROW(grid->at(num_cells.x(), num_cells.y()), std::exception);

    // access cell that is in grid
    BOOST_CHECK_EQUAL(grid->at(Index(num_cells.x() - 1, num_cells.y() - 1)), std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid->at(Vector3d(grid->getSize().x() - resolution.x() - 0.01,
                                        grid->getSize().y() - resolution.y() - 0.01,
                                        0)),
                      std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid->at(num_cells.x() - 1, num_cells.y() - 1), std::numeric_limits<double>::infinity());

    GridMap<double> const* grid_const = grid;

    // access cell that is not in grid = > should throw error
    BOOST_CHECK_THROW(grid_const->at(Index(num_cells.x(), num_cells.y())), std::exception);
    BOOST_CHECK_THROW(grid_const->at(Vector3d(grid->getSize().x(), grid->getSize().y(), 0)), std::exception);
    BOOST_CHECK_THROW(grid_const->at(num_cells.x(), num_cells.y()), std::exception);

    // access cell that is in grid
    BOOST_CHECK_EQUAL(grid_const->at(Index(num_cells.x() - 1, num_cells.y() - 1)), std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid_const->at(Vector3d(grid->getSize().x() - resolution.x() - 0.01,
                                              grid->getSize().y() - resolution.y() - 0.01,
                                              0)),
                      std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid_const->at(num_cells.x() - 1, num_cells.y() - 1), std::numeric_limits<double>::infinity());

    //delete grid;
    //delete grid_const;
}

BOOST_AUTO_TEST_CASE(test_grid_minmax)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    double min = std::numeric_limits<double>::max();
    double max = std::numeric_limits<double>::min();
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();

            if (min > cell_value)
                min = cell_value;
            if (max < cell_value)
                max = cell_value;

            grid->at(x, y) = cell_value;
        }
    }

    BOOST_CHECK_CLOSE(grid->getMax(), max, 0.000001);
    BOOST_CHECK_CLOSE(grid->getMin(), min, 0.000001);

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_clear)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();
            grid->at(x, y) = cell_value;
        }
    }

    // check if all cell are set
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL((grid->at(x, y) != grid->getDefaultValue()), true);
        }
    }

    grid->clear();

    // after the clean all cell should have default value
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(x, y), grid->getDefaultValue());
        }
    }

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_move)
{
    Vector2ui num_cells(7, 5);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    // random values
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            grid->at(Index(x,y)) = rand();
        }
    }

    // -------------- Test 1: move all values out of grid

    grid->moveBy(Index(7,5));

    // in grid should be only default values
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(Index(x,y)), grid->getDefaultValue());
        }
    }

    // -------------- Test 2: move by Index(-2,-3);

    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
    {
        for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
        {
            grid->at(Index(x,y)) = x;
        }
    }

    grid->moveBy(Index(-2, -3));

    // 2 3 4 5 6 inf inf
    // 2 3 4 5 6 inf inf
    // inf inf inf inf inf inf inf
    // inf inf inf inf inf inf inf
    // inf inf inf inf inf inf inf
    for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
    {
        for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
        {
            if (y < (grid->getNumCells().y() - 3) && x < (grid->getNumCells().x() - 2))
                BOOST_CHECK_EQUAL(grid->at(Index(x,y)), x + 2);
            else
                BOOST_CHECK_EQUAL(grid->at(Index(x,y)), grid->getDefaultValue());
        }
    }

    delete grid;
}<commit_msg>GridMap::clear and GridMap::move are valid for an empty Grid<commit_after>#include <boost/test/unit_test.hpp>
#include <envire_maps/GridMap.hpp>

#include <chrono>

using namespace envire::maps;

double default_value = std::numeric_limits<double>::infinity();

BOOST_AUTO_TEST_CASE(test_grid_empty)
{
    GridMap<double> *grid = new GridMap<double>();

    // if the grid has size of (0,0)
    BOOST_CHECK_THROW(grid->at(Index(0,0)), std::exception);
    BOOST_CHECK_THROW(grid->getMax(), std::exception);
    BOOST_CHECK_THROW(grid->getMin(), std::exception);
    BOOST_CHECK_NO_THROW(grid->clear());
    BOOST_CHECK_NO_THROW(grid->moveBy(Index(0,0)));

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_copy)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);
    grid->getOffset().translate(Eigen::Vector3d::Random(3));

    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();
            grid->at(x, y) = cell_value;
        }
    }

    GridMap<double> *grid_copy = new GridMap<double>(*grid);

    // check configuration
    BOOST_CHECK_EQUAL(grid_copy->getNumCells(), grid->getNumCells());
    BOOST_CHECK_EQUAL(grid_copy->getResolution(), grid->getResolution());
    BOOST_CHECK_EQUAL(grid_copy->getOffset().translation(), grid->getOffset().translation());
    BOOST_CHECK_EQUAL(grid_copy->getOffset().rotation(), grid->getOffset().rotation());

    // check default value
    BOOST_CHECK_EQUAL(grid_copy->getDefaultValue(), grid->getDefaultValue());

    // check cell value
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(x, y), grid_copy->at(x,y));
        }
    }

    delete grid;
    delete grid_copy;
}

BOOST_AUTO_TEST_CASE(test_grid_cell_access)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    // check default valuegitk --all

    BOOST_CHECK_EQUAL(grid->getDefaultValue(), std::numeric_limits<double>::infinity());

    // access cell that is not in grid = > should throw error
    BOOST_CHECK_THROW(grid->at(Index(num_cells.x(), num_cells.y())), std::exception);
    BOOST_CHECK_THROW(grid->at(Vector3d(grid->getSize().x(), grid->getSize().y(), 0)), std::exception);
    BOOST_CHECK_THROW(grid->at(num_cells.x(), num_cells.y()), std::exception);

    // access cell that is in grid
    BOOST_CHECK_EQUAL(grid->at(Index(num_cells.x() - 1, num_cells.y() - 1)), std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid->at(Vector3d(grid->getSize().x() - resolution.x() - 0.01,
                                        grid->getSize().y() - resolution.y() - 0.01,
                                        0)),
                      std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid->at(num_cells.x() - 1, num_cells.y() - 1), std::numeric_limits<double>::infinity());

    GridMap<double> const* grid_const = grid;

    // access cell that is not in grid = > should throw error
    BOOST_CHECK_THROW(grid_const->at(Index(num_cells.x(), num_cells.y())), std::exception);
    BOOST_CHECK_THROW(grid_const->at(Vector3d(grid->getSize().x(), grid->getSize().y(), 0)), std::exception);
    BOOST_CHECK_THROW(grid_const->at(num_cells.x(), num_cells.y()), std::exception);

    // access cell that is in grid
    BOOST_CHECK_EQUAL(grid_const->at(Index(num_cells.x() - 1, num_cells.y() - 1)), std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid_const->at(Vector3d(grid->getSize().x() - resolution.x() - 0.01,
                                              grid->getSize().y() - resolution.y() - 0.01,
                                              0)),
                      std::numeric_limits<double>::infinity());
    BOOST_CHECK_EQUAL(grid_const->at(num_cells.x() - 1, num_cells.y() - 1), std::numeric_limits<double>::infinity());

    //delete grid;
    //delete grid_const;
}

BOOST_AUTO_TEST_CASE(test_grid_minmax)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    double min = std::numeric_limits<double>::max();
    double max = std::numeric_limits<double>::min();
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();

            if (min > cell_value)
                min = cell_value;
            if (max < cell_value)
                max = cell_value;

            grid->at(x, y) = cell_value;
        }
    }

    BOOST_CHECK_CLOSE(grid->getMax(), max, 0.000001);
    BOOST_CHECK_CLOSE(grid->getMin(), min, 0.000001);

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_clear)
{
    Vector2ui num_cells(100, 200);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            double cell_value = rand();
            grid->at(x, y) = cell_value;
        }
    }

    // check if all cell are set
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL((grid->at(x, y) != grid->getDefaultValue()), true);
        }
    }

    grid->clear();

    // after the clean all cell should have default value
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(x, y), grid->getDefaultValue());
        }
    }

    delete grid;
}

BOOST_AUTO_TEST_CASE(test_grid_move)
{
    Vector2ui num_cells(7, 5);
    Vector2d resolution(0.1, 0.5);

    GridMap<double> *grid = new GridMap<double>(num_cells, resolution, default_value);

    // random values
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            grid->at(Index(x,y)) = rand();
        }
    }

    // -------------- Test 1: move all values out of grid

    grid->moveBy(Index(7,5));

    // in grid should be only default values
    for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
    {
        for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
        {
            BOOST_CHECK_EQUAL(grid->at(Index(x,y)), grid->getDefaultValue());
        }
    }

    // -------------- Test 2: move by Index(-2,-3);

    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    // 0 1 2 3 4 5 6
    for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
    {
        for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
        {
            grid->at(Index(x,y)) = x;
        }
    }

    grid->moveBy(Index(-2, -3));

    // 2 3 4 5 6 inf inf
    // 2 3 4 5 6 inf inf
    // inf inf inf inf inf inf inf
    // inf inf inf inf inf inf inf
    // inf inf inf inf inf inf inf
    for (unsigned int y = 0; y < grid->getNumCells().y(); ++y)
    {
        for (unsigned int x = 0; x < grid->getNumCells().x(); ++x)
        {
            if (y < (grid->getNumCells().y() - 3) && x < (grid->getNumCells().x() - 2))
                BOOST_CHECK_EQUAL(grid->at(Index(x,y)), x + 2);
            else
                BOOST_CHECK_EQUAL(grid->at(Index(x,y)), grid->getDefaultValue());
        }
    }

    delete grid;
}
<|endoftext|>


<commit_before><commit_msg>Journaler: call set_layout after init_headers.<commit_after><|endoftext|>


<commit_before>#ifndef FMO_EXPLORER_IMPL_HPP
#define FMO_EXPLORER_IMPL_HPP

#include <fmo/explorer.hpp>

namespace fmo {
    /// Implementation details of class Explorer.
    struct Explorer::Impl {
        static const uint8_t DIFF_THRESH = 19; ///< threshold value for difference image
        static const int MIN_STRIPS = 12;      ///< minimum strips to detect an object

        /// Initializes all caches. Creates as many decimation levels as needed to process images
        /// with dimensions specified in the configuration object.
        Impl(const Config& cfg);

        /// Called every frame, providing the next image for processing. The processing will take
        /// place during the call and might take some time.
        void setInput(const Mat& src);

        /// Visualizes the result of detection, returning an image that should be displayed to the
        /// user.
        const Image& getDebugImage() {
            visualize();
            return mVisualized;
        }

        /// Determines whether a new object has been found as a result of analyzing the last frame.
        bool haveObject() const { return !mObjects.empty(); }

        Object getObject() const;

    private:
        /// Data related to decimation levels that will not be processed processed any further.
        /// Serves as a cache during decimation.
        struct IgnoredLevel {
            Image image;
        };

        /// Data related to decimation levels that will be processed. Holds all data required to
        /// detect strips in this frame, as well as some detection results.
        struct Level {
            Image image1;       ///< newest source image
            Image image2;       ///< source image from previous frame
            Image image3;       ///< source image from two frames before
            Image diff1;        ///< newest difference image
            Image diff2;        ///< difference image from previous frame
            Image preprocessed; ///< image ready for strip detection
            int step;           ///< relative pixel width (due to downscaling)
            int numStrips;      ///< number of strips detected this frame
        };

        /// Strip data.
        struct Strip {
            enum : int16_t {
                UNTOUCHED = 0,
                TOUCHED = 1,
                END = -1,
            };

            Strip(int16_t aX, int16_t aY, int16_t aHalfHeight)
                : x(aX), y(aY), halfHeight(aHalfHeight), special(UNTOUCHED) {}

            // data
            int16_t x, y;       ///< strip coordinates in the source image
            int16_t halfHeight; ///< strip height in the source image, divided by 2
            int16_t special;    ///< special value, status or index of next strip in stroke
        };

        /// Connected component data.
        struct Component {
            enum : int16_t {
                NO_TRAJECTORY = -1,
                NO_COMPONENT = -1,
            };

            Component(int16_t aFirst) : first(aFirst), trajectory(NO_TRAJECTORY) {}

            int16_t first;            ///< index of first strip
            int16_t last;             ///< index of last strip
            int16_t numStrips;        ///< the number of strips in component
            int16_t approxHalfHeight; ///< median of strip half heights
            int16_t next;             ///< index of next component in trajectory
            int16_t trajectory;       ///< index of assigned trajectory
        };

        /// Trajectory data.
        struct Trajectory {
            Trajectory(int16_t aFirst) : first(aFirst), maxWidth(0) {}

            int16_t first;     ///< index of first component
            int16_t last;      ///< index of last component
            int16_t maxWidth;  ///< width of the largest component
            int16_t numStrips; ///< number of strips in trajectory
        };

        /// Creates low-resolution versions of the source image using decimation.
        void createLevelPyramid(const Mat& src);

        /// Applies image-wide operations before strips are detected.
        void preprocess();

        /// Applies image-wide operations before strips are detected.
        void preprocess(Level& level);

        /// Detects strips by iterating over the pixels in the image.
        void findStrips();

        /// Detects strips by iterating over the pixels in the image.
        void findStrips(Level& level);

        /// Creates connected components by joining strips together.
        void findComponents();

        /// Finds properties of previously found components before trajectory search.
        void analyzeComponents();

        /// Creates trajectories by joining components together.
        void findTrajectories();

        /// Finds properties of previously found trajectories before picking the best one.
        void analyzeTrajectories();

        /// Locates an object by selecting the best trajectory.
        void findObjects();

        /// Determines whether the given trajectory should be considered a fast-moving object.
        bool isObject(const Trajectory&) const;

        /// Finds the range of x-coordinates of strips which are present in a given difference
        /// image.
        std::pair<int, int> findTrajectoryRangeInDiff(const Trajectory& traj, const Level& level,
                                                      const Mat& diff) const;

        /// Finds the bounding box that encloses a given trajectory.
        Bounds findBounds(const Trajectory&) const;

        /// Visualizes the results into the visualization image.
        void visualize();

        // data
        std::vector<IgnoredLevel> mIgnoredLevels; ///< levels that will not be processed
        Level mLevel;                             ///< the level that will be processed
        std::vector<Strip> mStrips;               ///< detected strips, ordered by x coordinate
        std::vector<Component> mComponents;       ///< detected components, ordered by x coordinate
        std::vector<Trajectory> mTrajectories;    ///< detected trajectories
        std::vector<int> mSortCache;              ///< for storing and sorting integers
        std::vector<const Trajectory*> mRejected; ///< objects that have been rejected this frame
        std::vector<const Trajectory*> mObjects;  ///< objects that have been accepted this frame
        int mFrameNum = 0; ///< frame number, 1 when processing the first frame
        Image mVisualized; ///< visualization image
        const Config mCfg; ///< configuration settings
    };
}

#endif // FMO_EXPLORER_IMPL_HPP
<commit_msg>Fix crash due to an uninitialized value<commit_after>#ifndef FMO_EXPLORER_IMPL_HPP
#define FMO_EXPLORER_IMPL_HPP

#include <fmo/explorer.hpp>

namespace fmo {
    /// Implementation details of class Explorer.
    struct Explorer::Impl {
        static const uint8_t DIFF_THRESH = 19; ///< threshold value for difference image
        static const int MIN_STRIPS = 12;      ///< minimum strips to detect an object

        /// Initializes all caches. Creates as many decimation levels as needed to process images
        /// with dimensions specified in the configuration object.
        Impl(const Config& cfg);

        /// Called every frame, providing the next image for processing. The processing will take
        /// place during the call and might take some time.
        void setInput(const Mat& src);

        /// Visualizes the result of detection, returning an image that should be displayed to the
        /// user.
        const Image& getDebugImage() {
            visualize();
            return mVisualized;
        }

        /// Determines whether a new object has been found as a result of analyzing the last frame.
        bool haveObject() const { return !mObjects.empty(); }

        Object getObject() const;

    private:
        /// Data related to decimation levels that will not be processed processed any further.
        /// Serves as a cache during decimation.
        struct IgnoredLevel {
            Image image;
        };

        /// Data related to decimation levels that will be processed. Holds all data required to
        /// detect strips in this frame, as well as some detection results.
        struct Level {
            Image image1;       ///< newest source image
            Image image2;       ///< source image from previous frame
            Image image3;       ///< source image from two frames before
            Image diff1;        ///< newest difference image
            Image diff2;        ///< difference image from previous frame
            Image preprocessed; ///< image ready for strip detection
            int step;           ///< relative pixel width (due to downscaling)
            int numStrips = 0;  ///< number of strips detected this frame
        };

        /// Strip data.
        struct Strip {
            enum : int16_t {
                UNTOUCHED = 0,
                TOUCHED = 1,
                END = -1,
            };

            Strip(int16_t aX, int16_t aY, int16_t aHalfHeight)
                : x(aX), y(aY), halfHeight(aHalfHeight), special(UNTOUCHED) {}

            // data
            int16_t x, y;       ///< strip coordinates in the source image
            int16_t halfHeight; ///< strip height in the source image, divided by 2
            int16_t special;    ///< special value, status or index of next strip in stroke
        };

        /// Connected component data.
        struct Component {
            enum : int16_t {
                NO_TRAJECTORY = -1,
                NO_COMPONENT = -1,
            };

            Component(int16_t aFirst) : first(aFirst), trajectory(NO_TRAJECTORY) {}

            int16_t first;            ///< index of first strip
            int16_t last;             ///< index of last strip
            int16_t numStrips;        ///< the number of strips in component
            int16_t approxHalfHeight; ///< median of strip half heights
            int16_t next;             ///< index of next component in trajectory
            int16_t trajectory;       ///< index of assigned trajectory
        };

        /// Trajectory data.
        struct Trajectory {
            Trajectory(int16_t aFirst) : first(aFirst), maxWidth(0) {}

            int16_t first;     ///< index of first component
            int16_t last;      ///< index of last component
            int16_t maxWidth;  ///< width of the largest component
            int16_t numStrips; ///< number of strips in trajectory
        };

        /// Creates low-resolution versions of the source image using decimation.
        void createLevelPyramid(const Mat& src);

        /// Applies image-wide operations before strips are detected.
        void preprocess();

        /// Applies image-wide operations before strips are detected.
        void preprocess(Level& level);

        /// Detects strips by iterating over the pixels in the image.
        void findStrips();

        /// Detects strips by iterating over the pixels in the image.
        void findStrips(Level& level);

        /// Creates connected components by joining strips together.
        void findComponents();

        /// Finds properties of previously found components before trajectory search.
        void analyzeComponents();

        /// Creates trajectories by joining components together.
        void findTrajectories();

        /// Finds properties of previously found trajectories before picking the best one.
        void analyzeTrajectories();

        /// Locates an object by selecting the best trajectory.
        void findObjects();

        /// Determines whether the given trajectory should be considered a fast-moving object.
        bool isObject(const Trajectory&) const;

        /// Finds the range of x-coordinates of strips which are present in a given difference
        /// image.
        std::pair<int, int> findTrajectoryRangeInDiff(const Trajectory& traj, const Level& level,
                                                      const Mat& diff) const;

        /// Finds the bounding box that encloses a given trajectory.
        Bounds findBounds(const Trajectory&) const;

        /// Visualizes the results into the visualization image.
        void visualize();

        // data
        std::vector<IgnoredLevel> mIgnoredLevels; ///< levels that will not be processed
        Level mLevel;                             ///< the level that will be processed
        std::vector<Strip> mStrips;               ///< detected strips, ordered by x coordinate
        std::vector<Component> mComponents;       ///< detected components, ordered by x coordinate
        std::vector<Trajectory> mTrajectories;    ///< detected trajectories
        std::vector<int> mSortCache;              ///< for storing and sorting integers
        std::vector<const Trajectory*> mRejected; ///< objects that have been rejected this frame
        std::vector<const Trajectory*> mObjects;  ///< objects that have been accepted this frame
        int mFrameNum = 0; ///< frame number, 1 when processing the first frame
        Image mVisualized; ///< visualization image
        const Config mCfg; ///< configuration settings
    };
}

#endif // FMO_EXPLORER_IMPL_HPP
<|endoftext|>


<commit_before>#include "Iop_LibSd.h"
#include "../Log.h"

//Not an actual implementation of the LIBSD module
//It is only used for debugging purposes (ie.: function names)

using namespace Iop;

#define FUNCTION_SETPARAM				"SetParam"
#define FUNCTION_SETSWITCH				"SetSwitch"
#define FUNCTION_SETADDR				"SetAddr"
#define FUNCTION_GETADDR				"GetAddr"
#define FUNCTION_SETCOREATTR			"SetCoreAttr"
#define FUNCTION_VOICETRANS				"VoiceTrans"
#define FUNCTION_VOICETRANSSTATUS		"VoiceTransStatus"
#define FUNCTION_SETTRANSINTRHANDLER	"SetTransIntrHandler"
#define FUNCTION_SETSPU2INTRHANDLER		"SetSpu2IntrHandler"

#define LOG_NAME "iop_libsd"

std::string CLibSd::GetId() const
{
	return "libsd";
}

std::string CLibSd::GetFunctionName(unsigned int functionId) const
{
	switch(functionId)
	{
	case 5:
		return FUNCTION_SETPARAM;
		break;
	case 7:
		return FUNCTION_SETSWITCH;
		break;
	case 9:
		return FUNCTION_SETADDR;
		break;
	case 10:
		return FUNCTION_GETADDR;
		break;
	case 11:
		return FUNCTION_SETCOREATTR;
		break;
	case 17:
		return FUNCTION_VOICETRANS;
		break;
	case 19:
		return FUNCTION_VOICETRANSSTATUS;
		break;
	case 26:
		return FUNCTION_SETTRANSINTRHANDLER;
		break;
	case 27:
		return FUNCTION_SETSPU2INTRHANDLER;
		break;
	default:
		return "unknown";
		break;
	}
}

void CLibSd::Invoke(CMIPS&, unsigned int)
{

}

void CLibSd::TraceCall(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 4:
		CLog::GetInstance().Print(LOG_NAME, "sceSdInit(flag = %d);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 5:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETPARAM "(entry = 0x%0.4X, value = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 7:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETSWITCH "(entry = 0x%0.4X, value = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 9:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETADDR "(entry = 0x%0.4X, value = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 10:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_GETADDR "(entry = 0x%0.4X);\r\n", context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 17:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_VOICETRANS "(channel = 0x%0.4X, mode = 0x%0.4X, maddr = 0x%0.8X, saddr = 0x%0.8X, size = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0, context.m_State.nGPR[CMIPS::A3].nV0,
			context.m_State.nGPR[CMIPS::T0].nV0);
		break;
	case 18:
		CLog::GetInstance().Print(LOG_NAME, "sceSdBlockTrans(channel = 0x%0.4X, mode = 0x%0.4X, maddr = 0x%0.8X, size = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0, context.m_State.nGPR[CMIPS::A3].nV0);
		break;
	case 19:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_VOICETRANSSTATUS "(channel = 0x%0.4X, flag = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 20:
		CLog::GetInstance().Print(LOG_NAME, "sceSdBlockTransStatus(channel = 0x%0.4X, flag = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 26:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETTRANSINTRHANDLER "(channel = 0x%0.4X, function = 0x%0.8X, arg = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	default:
		CLog::GetInstance().Print(LOG_NAME, "unknownlibsd(%d);\r\n", functionId);
		break;
	}
}
<commit_msg>Cleaned libsd tracing a bit.<commit_after>#include "Iop_LibSd.h"
#include "../Log.h"

//Not an actual implementation of the LIBSD module
//It is only used for debugging purposes (ie.: function names)

using namespace Iop;

#define FUNCTION_INIT					"Init"
#define FUNCTION_SETPARAM				"SetParam"
#define FUNCTION_SETSWITCH				"SetSwitch"
#define FUNCTION_SETADDR				"SetAddr"
#define FUNCTION_GETADDR				"GetAddr"
#define FUNCTION_SETCOREATTR			"SetCoreAttr"
#define FUNCTION_VOICETRANS				"VoiceTrans"
#define FUNCTION_BLOCKTRANS				"BlockTrans"
#define FUNCTION_VOICETRANSSTATUS		"VoiceTransStatus"
#define FUNCTION_BLOCKTRANSSTATUS		"BlockTransStatus"
#define FUNCTION_SETTRANSINTRHANDLER	"SetTransIntrHandler"
#define FUNCTION_SETSPU2INTRHANDLER		"SetSpu2IntrHandler"

#define LOG_NAME "iop_libsd"

std::string CLibSd::GetId() const
{
	return "libsd";
}

std::string CLibSd::GetFunctionName(unsigned int functionId) const
{
	switch(functionId)
	{
	case 4:
		return FUNCTION_INIT;
		break;
	case 5:
		return FUNCTION_SETPARAM;
		break;
	case 7:
		return FUNCTION_SETSWITCH;
		break;
	case 9:
		return FUNCTION_SETADDR;
		break;
	case 10:
		return FUNCTION_GETADDR;
		break;
	case 11:
		return FUNCTION_SETCOREATTR;
		break;
	case 17:
		return FUNCTION_VOICETRANS;
		break;
	case 18:
		return FUNCTION_BLOCKTRANS;
		break;
	case 19:
		return FUNCTION_VOICETRANSSTATUS;
		break;
	case 20:
		return FUNCTION_BLOCKTRANSSTATUS;
		break;
	case 26:
		return FUNCTION_SETTRANSINTRHANDLER;
		break;
	case 27:
		return FUNCTION_SETSPU2INTRHANDLER;
		break;
	default:
		return "unknown";
		break;
	}
}

void CLibSd::Invoke(CMIPS&, unsigned int)
{

}

void CLibSd::TraceCall(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 4:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_INIT "(flag = %d);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 5:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETPARAM "(entry = 0x%0.4X, value = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 7:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETSWITCH "(entry = 0x%0.4X, value = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 9:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETADDR "(entry = 0x%0.4X, value = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 10:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_GETADDR "(entry = 0x%0.4X);\r\n", context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 11:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETCOREATTR "(entry = 0x%0.4X, value = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 17:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_VOICETRANS "(channel = 0x%0.4X, mode = 0x%0.4X, maddr = 0x%0.8X, saddr = 0x%0.8X, size = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0, context.m_State.nGPR[CMIPS::A3].nV0,
			context.m_State.nGPR[CMIPS::T0].nV0);
		break;
	case 18:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_BLOCKTRANS "(channel = 0x%0.4X, mode = 0x%0.4X, maddr = 0x%0.8X, size = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0, context.m_State.nGPR[CMIPS::A3].nV0);
		break;
	case 19:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_VOICETRANSSTATUS "(channel = 0x%0.4X, flag = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 20:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_BLOCKTRANSSTATUS "(channel = 0x%0.4X, flag = 0x%0.4X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 26:
		CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETTRANSINTRHANDLER "(channel = 0x%0.4X, function = 0x%0.8X, arg = 0x%0.8X);\r\n",
			context.m_State.nGPR[CMIPS::A0].nV0, context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	default:
		CLog::GetInstance().Print(LOG_NAME, "unknownlibsd(%d);\r\n", functionId);
		break;
	}
}
<|endoftext|>


<commit_before>/* ****************************************************************
 *
 * Copyright 2018 Samsung Electronics All Rights Reserved.
 *
 * 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 <media/MediaPlayer.h>
#include "PlayerWorker.h"
#include "MediaPlayerImpl.h"

#include <debug.h>
#include "audio/audio_manager.h"

namespace media {
MediaPlayerImpl::MediaPlayerImpl()
{
	mPlayerObserver = nullptr;
	mCurState = PLAYER_STATE_NONE;
	mBuffer = nullptr;
	mInputDataSource = nullptr;

	static int playerId = 1;
	mId = playerId++;
}

player_result_t MediaPlayerImpl::create()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer create\n");
	if (mCurState != PLAYER_STATE_NONE) {
		meddbg("MediaPlayer create fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.startWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	mCurState = PLAYER_STATE_IDLE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::destroy()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer destroy\n");
	if (mCurState != PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer destroy fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);
	mpw.stopWorker();

	PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
	pow.stopWorker();

	mCurState = PLAYER_STATE_NONE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::prepare()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer prepare\n");
	if (mCurState != PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer prepare fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	if (mInputDataSource == nullptr) {
		meddbg("MediaPlayer prepare fail : mInputDataSource is not set\n");
		return PLAYER_ERROR;
	}

	if (!mInputDataSource->open()) {
		meddbg("MediaPlayer prepare fail : file open fail\n");
		return PLAYER_ERROR;
	}

	if (set_audio_stream_out(mInputDataSource->getChannels(), mInputDataSource->getSampleRate(),
							 mInputDataSource->getPcmFormat()) != AUDIO_MANAGER_SUCCESS) {
		meddbg("MediaPlayer prepare fail : set_audio_stream_out fail\n");
		return PLAYER_ERROR;
	}

	mBufSize = get_output_frames_byte_size(get_output_frame_count());
	medvdbg("MediaPlayer mBuffer size : %d\n", mBufSize);

	mBuffer = new unsigned char[mBufSize];
	if (!mBuffer) {
		meddbg("MediaPlayer prepare fail : mBuffer allocation fail\n");
		return PLAYER_ERROR;
	}

	mCurState = PLAYER_STATE_READY;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::unprepare()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer unprepare\n");
	if (mCurState == PLAYER_STATE_NONE || mCurState == PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer unprepare fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	if (mBuffer) {
		delete[] mBuffer;
		mBuffer = nullptr;
	}
	mBufSize = 0;

	if (reset_audio_stream_out() != AUDIO_MANAGER_SUCCESS) {
		meddbg("MediaPlayer unprepare fail : reset_audio_stream_out fail\n");
		return PLAYER_ERROR;
	}

	mInputDataSource->close();

	mCurState = PLAYER_STATE_IDLE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::start()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer start\n");
	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::startPlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::stop()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer stop\n");
	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::stopPlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::pause()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer pause\n");
	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::pausePlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

int MediaPlayerImpl::getVolume()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer getVolume\n");
	if (mCurState == PLAYER_STATE_NONE) {
		meddbg("MediaPlayer getVolume fail : wrong state\n");
		return -1;
	}

	return get_audio_volume();
}

player_result_t MediaPlayerImpl::setVolume(int vol)
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setVolume\n");
	if (mCurState == PLAYER_STATE_NONE) {
		meddbg("MediaPlayer setVolume fail : wrong state\n");
		return PLAYER_ERROR;
	}

	if (vol < 0 || vol > 31) {
		meddbg("MediaPlayer setVolume fail : invalid argument. volume level should be 0(Min) ~ 31(Max)\n");
		return PLAYER_ERROR;
	}

	if (!set_audio_volume(vol)) {
		mCurVolume = vol;
		return PLAYER_OK;
	} else {
		return PLAYER_ERROR;
	}
}

player_result_t MediaPlayerImpl::setDataSource(std::unique_ptr<stream::InputDataSource> source)
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setDataSource\n");
	if (!source) {
		meddbg("MediaPlayer setDataSource fail : invalid argument. DataSource should not be nullptr\n");
		return PLAYER_ERROR;
	}

	mInputDataSource = std::move(source);
	return PLAYER_OK;
}

void MediaPlayerImpl::setObserver(std::shared_ptr<MediaPlayerObserverInterface> observer)
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setObserver\n");
	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);
	PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
	pow.startWorker();
	mPlayerObserver = observer;
}

player_state_t MediaPlayerImpl::getState()
{
	medvdbg("MediaPlayer getState\n");
	return mCurState;
}

player_result_t MediaPlayerImpl::seekTo(int msec)
{
	medvdbg("MediaPlayer seekTo %d msec\n", msec);
	// TODO : implementation of seekTo
	return PLAYER_OK;
}

void MediaPlayerImpl::notifySync()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	mSyncCv.notify_one();
}

void MediaPlayerImpl::notifyObserver(player_observer_command_t cmd)
{
	if (mPlayerObserver != nullptr) {
		PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
		switch (cmd) {
		case PLAYER_OBSERVER_COMMAND_STARTED:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackStarted, mPlayerObserver, mId);
			break;
		case PLAYER_OBSERVER_COMMAND_FINISHIED:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackFinished, mPlayerObserver, mId);
			break;
		case PLAYER_OBSERVER_COMMAND_ERROR:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackError, mPlayerObserver, mId);
			break;
		}
	}
}

int MediaPlayerImpl::playback(int size)
{
	return start_audio_stream_out(mBuffer, get_output_bytes_frame_count(size));
}

MediaPlayerImpl::~MediaPlayerImpl()
{
	player_result_t ret;

	if (mCurState > PLAYER_STATE_IDLE) {
		ret = unprepare();
		if (ret != PLAYER_OK) {
			meddbg("~MediaPlayer fail : unprepare fail\n");
		}
	}

	if (mCurState == PLAYER_STATE_IDLE) {
		ret = destroy();
		if (ret != PLAYER_OK) {
			meddbg("~MediaPlayer fail : destroy fail\n");
		}
	}
}
} // namespace media
<commit_msg>media: Check state in start, stop, pause<commit_after>/* ****************************************************************
 *
 * Copyright 2018 Samsung Electronics All Rights Reserved.
 *
 * 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 <media/MediaPlayer.h>
#include "PlayerWorker.h"
#include "MediaPlayerImpl.h"

#include <debug.h>
#include "audio/audio_manager.h"

namespace media {
MediaPlayerImpl::MediaPlayerImpl()
{
	mPlayerObserver = nullptr;
	mCurState = PLAYER_STATE_NONE;
	mBuffer = nullptr;
	mInputDataSource = nullptr;

	static int playerId = 1;
	mId = playerId++;
}

player_result_t MediaPlayerImpl::create()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer create\n");
	if (mCurState != PLAYER_STATE_NONE) {
		meddbg("MediaPlayer create fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.startWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	mCurState = PLAYER_STATE_IDLE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::destroy()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer destroy\n");
	if (mCurState != PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer destroy fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);
	mpw.stopWorker();

	PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
	pow.stopWorker();

	mCurState = PLAYER_STATE_NONE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::prepare()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer prepare\n");
	if (mCurState != PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer prepare fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	if (mInputDataSource == nullptr) {
		meddbg("MediaPlayer prepare fail : mInputDataSource is not set\n");
		return PLAYER_ERROR;
	}

	if (!mInputDataSource->open()) {
		meddbg("MediaPlayer prepare fail : file open fail\n");
		return PLAYER_ERROR;
	}

	if (set_audio_stream_out(mInputDataSource->getChannels(), mInputDataSource->getSampleRate(),
							 mInputDataSource->getPcmFormat()) != AUDIO_MANAGER_SUCCESS) {
		meddbg("MediaPlayer prepare fail : set_audio_stream_out fail\n");
		return PLAYER_ERROR;
	}

	mBufSize = get_output_frames_byte_size(get_output_frame_count());
	medvdbg("MediaPlayer mBuffer size : %d\n", mBufSize);

	mBuffer = new unsigned char[mBufSize];
	if (!mBuffer) {
		meddbg("MediaPlayer prepare fail : mBuffer allocation fail\n");
		return PLAYER_ERROR;
	}

	mCurState = PLAYER_STATE_READY;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::unprepare()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer unprepare\n");
	if (mCurState == PLAYER_STATE_NONE || mCurState == PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer unprepare fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);

	if (mBuffer) {
		delete[] mBuffer;
		mBuffer = nullptr;
	}
	mBufSize = 0;

	if (reset_audio_stream_out() != AUDIO_MANAGER_SUCCESS) {
		meddbg("MediaPlayer unprepare fail : reset_audio_stream_out fail\n");
		return PLAYER_ERROR;
	}

	mInputDataSource->close();

	mCurState = PLAYER_STATE_IDLE;
	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::start()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer start\n");
	if (mCurState == PLAYER_STATE_NONE || mCurState == PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer unprepare fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::startPlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::stop()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer stop\n");
	if (mCurState == PLAYER_STATE_NONE || mCurState == PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer stop fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::stopPlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

player_result_t MediaPlayerImpl::pause()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer pause\n");
	if (mCurState == PLAYER_STATE_NONE || mCurState == PLAYER_STATE_IDLE) {
		meddbg("MediaPlayer pause fail : wrong state\n");
		return PLAYER_ERROR;
	}

	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&PlayerWorker::pausePlayer, &mpw, shared_from_this());

	return PLAYER_OK;
}

int MediaPlayerImpl::getVolume()
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer getVolume\n");
	if (mCurState == PLAYER_STATE_NONE) {
		meddbg("MediaPlayer getVolume fail : wrong state\n");
		return -1;
	}

	return get_audio_volume();
}

player_result_t MediaPlayerImpl::setVolume(int vol)
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setVolume\n");
	if (mCurState == PLAYER_STATE_NONE) {
		meddbg("MediaPlayer setVolume fail : wrong state\n");
		return PLAYER_ERROR;
	}

	if (vol < 0 || vol > 31) {
		meddbg("MediaPlayer setVolume fail : invalid argument. volume level should be 0(Min) ~ 31(Max)\n");
		return PLAYER_ERROR;
	}

	if (!set_audio_volume(vol)) {
		mCurVolume = vol;
		return PLAYER_OK;
	} else {
		return PLAYER_ERROR;
	}
}

player_result_t MediaPlayerImpl::setDataSource(std::unique_ptr<stream::InputDataSource> source)
{
	std::lock_guard<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setDataSource\n");
	if (!source) {
		meddbg("MediaPlayer setDataSource fail : invalid argument. DataSource should not be nullptr\n");
		return PLAYER_ERROR;
	}

	mInputDataSource = std::move(source);
	return PLAYER_OK;
}

void MediaPlayerImpl::setObserver(std::shared_ptr<MediaPlayerObserverInterface> observer)
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	medvdbg("MediaPlayer setObserver\n");
	PlayerWorker& mpw = PlayerWorker::getWorker();
	mpw.getQueue().enQueue(&MediaPlayerImpl::notifySync, shared_from_this());
	mSyncCv.wait(lock);
	PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
	pow.startWorker();
	mPlayerObserver = observer;
}

player_state_t MediaPlayerImpl::getState()
{
	medvdbg("MediaPlayer getState\n");
	return mCurState;
}

player_result_t MediaPlayerImpl::seekTo(int msec)
{
	medvdbg("MediaPlayer seekTo %d msec\n", msec);
	// TODO : implementation of seekTo
	return PLAYER_OK;
}

void MediaPlayerImpl::notifySync()
{
	std::unique_lock<std::mutex> lock(mCmdMtx);
	mSyncCv.notify_one();
}

void MediaPlayerImpl::notifyObserver(player_observer_command_t cmd)
{
	if (mPlayerObserver != nullptr) {
		PlayerObserverWorker& pow = PlayerObserverWorker::getWorker();
		switch (cmd) {
		case PLAYER_OBSERVER_COMMAND_STARTED:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackStarted, mPlayerObserver, mId);
			break;
		case PLAYER_OBSERVER_COMMAND_FINISHIED:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackFinished, mPlayerObserver, mId);
			break;
		case PLAYER_OBSERVER_COMMAND_ERROR:
			pow.getQueue().enQueue(&MediaPlayerObserverInterface::onPlaybackError, mPlayerObserver, mId);
			break;
		}
	}
}

int MediaPlayerImpl::playback(int size)
{
	return start_audio_stream_out(mBuffer, get_output_bytes_frame_count(size));
}

MediaPlayerImpl::~MediaPlayerImpl()
{
	player_result_t ret;

	if (mCurState > PLAYER_STATE_IDLE) {
		ret = unprepare();
		if (ret != PLAYER_OK) {
			meddbg("~MediaPlayer fail : unprepare fail\n");
		}
	}

	if (mCurState == PLAYER_STATE_IDLE) {
		ret = destroy();
		if (ret != PLAYER_OK) {
			meddbg("~MediaPlayer fail : destroy fail\n");
		}
	}
}
} // namespace media
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <stdio.h>
#include <string.h>

#include "cppuoptions.hxx"
#include "osl/thread.h"
#include "osl/process.h"

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

sal_Bool CppuOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile)
    throw( IllegalArgument )
{
    sal_Bool    ret = sal_True;
    sal_uInt16  i=0;

    if (!bCmdFile)
    {
        bCmdFile = sal_True;

        OString name(av[0]);
        sal_Int32 index = name.lastIndexOf(SEPARATOR);
        m_program = name.copy((index > 0 ? index+1 : 0));

        if (ac < 2)
        {
            fprintf(stderr, "%s", prepareHelp().getStr());
            ret = sal_False;
        }

        i = 1;
    }
    else
    {
        i = 0;
    }

    char    *s=NULL;
    for( ; i < ac; i++)
    {
        if (av[i][0] == '-')
        {
            switch (av[i][1])
            {
                case 'O':
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-O', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    m_options["-O"] = OString(s);
                    break;
                case 'n':
                    if (av[i][2] != 'D' || av[i][3] != '\0')
                    {
                        OString tmp("'-nD', please check");
                            tmp += " your input '" + OString(av[i]) + "'";
                        throw IllegalArgument(tmp);
                    }

                    m_options["-nD"] = OString("");
                    break;
                case 'T':
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-T', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    if (m_options.count("-T") > 0)
                    {
                        OString tmp(m_options["-T"]);
                        tmp = tmp + ";" + s;
                        m_options["-T"] = tmp;
                    }
                    else
                    {
                        m_options["-T"] = OString(s);
                    }
                    break;
                case 'L':
                    if (av[i][2] != '\0')
                    {
                        OString tmp("'-L', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    if (isValid("-C") || isValid("-CS"))
                    {
                        OString tmp("'-L' could not be combined with '-C' or '-CS' option");
                        throw IllegalArgument(tmp);
                    }
                    m_options["-L"] = OString("");
                    break;
                case 'C':
                    if (av[i][2] == 'S')
                    {
                        if (av[i][3] != '\0')
                        {
                            OString tmp("'-CS', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }

                        if (isValid("-L") || isValid("-C"))
                        {
                            OString tmp("'-CS' could not be combined with '-L' or '-C' option");
                            throw IllegalArgument(tmp);
                        }
                        m_options["-CS"] = OString("");
                        break;
                    }
                    else if (av[i][2] != '\0')
                    {
                        OString tmp("'-C', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    if (isValid("-L") || isValid("-CS"))
                    {
                        OString tmp("'-C' could not be combined with '-L' or '-CS' option");
                        throw IllegalArgument(tmp);
                    }
                    m_options["-C"] = OString("");
                    break;
                case 'G':
                    if (av[i][2] == 'c')
                    {
                        if (av[i][3] != '\0')
                        {
                            OString tmp("'-Gc', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }

                        m_options["-Gc"] = OString("");
                        break;
                    }
                    else if (av[i][2] != '\0')
                    {
                        OString tmp("'-G', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    m_options["-G"] = OString("");
                    break;
                case 'X': // support for eXtra type rdbs
                {
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-X', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    m_extra_input_files.push_back( s );
                    break;
                }

                default:
                    throw IllegalArgument("the option is unknown" + OString(av[i]));
            }
        } else
        {
            if (av[i][0] == '@')
            {
                FILE* cmdFile = fopen(av[i]+1, "r");
                if( cmdFile == NULL )
                {
                    fprintf(stderr, "%s", prepareHelp().getStr());
                    ret = sal_False;
                }
                else
                {
                    int rargc=0;
                    char* rargv[512];
                    char  buffer[512];

                    while ( fscanf(cmdFile, "%s", buffer) != EOF )
                    {
                        rargv[rargc]= strdup(buffer);
                        rargc++;
                    }
                    fclose(cmdFile);

                    ret = initOptions(rargc, rargv, bCmdFile);

                    for (long j=0; j < rargc; j++)
                    {
                        free(rargv[j]);
                    }
                }
            }
            else
            {
                if (bCmdFile)
                {
                    m_inputFiles.push_back(av[i]);
                }
                else
                {
                    OUString system_filepath;
                    if (osl_getCommandArg( i-1, &system_filepath.pData )
                        != osl_Process_E_None)
                    {
                        OSL_ASSERT(false);
                    }
                    m_inputFiles.push_back(OUStringToOString(system_filepath, osl_getThreadTextEncoding()));
                }
            }
        }
    }

    return ret;
}

OString CppuOptions::prepareHelp()
{
    OString help("\nusing: ");
    help += m_program + " [-options] file_1 ... file_n\nOptions:\n";
    help += "    -O<path>   = path describes the root directory for the generated output.\n";
    help += "                 The output directory tree is generated under this directory.\n";
    help += "    -T<name>   = name specifies a type or a list of types. The output for this\n";
    help += "      [t1;...]   type is generated. If no '-T' option is specified,\n";
    help += "                 then output for all types is generated.\n";
    help += "                 Example: 'com.sun.star.uno.XInterface' is a valid type.\n";
    help += "    -L         = UNO type functions are generated lightweight, that means only\n";
    help += "                 the name and typeclass are given and everything else is retrieved\n";
    help += "                 from the type library dynamically. The default is that UNO type\n";
    help += "                 functions provides enough type information for bootstrapping C++.\n";
    help += "                 '-L' should be the default for external components.\n";
    help += "    -C         = UNO type functions are generated comprehensive that means all\n";
    help += "                 necessary information is available for bridging the type in UNO.\n";
    help += "    -nD        = no dependent types are generated.\n";
    help += "    -G         = generate only target files which does not exists.\n";
    help += "    -Gc        = generate only target files which content will be changed.\n";
    help += "    -X<file>   = extra types which will not be taken into account for generation.\n\n";
    help += prepareVersion();

    return help;
}

OString CppuOptions::prepareVersion()
{
    OString version(m_program);
    version += " Version 2.0\n\n";
    return version;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#440030 Logically dead code<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <stdio.h>
#include <string.h>

#include "cppuoptions.hxx"
#include "osl/thread.h"
#include "osl/process.h"

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

sal_Bool CppuOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile)
    throw( IllegalArgument )
{
    sal_Bool    ret = sal_True;
    sal_uInt16  i=0;

    if (!bCmdFile)
    {
        bCmdFile = sal_True;

        OString name(av[0]);
        sal_Int32 index = name.lastIndexOf(SEPARATOR);
        m_program = name.copy((index > 0 ? index+1 : 0));

        if (ac < 2)
        {
            fprintf(stderr, "%s", prepareHelp().getStr());
            ret = sal_False;
        }

        i = 1;
    }
    else
    {
        i = 0;
    }

    char    *s=NULL;
    for( ; i < ac; i++)
    {
        if (av[i][0] == '-')
        {
            switch (av[i][1])
            {
                case 'O':
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-O', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    m_options["-O"] = OString(s);
                    break;
                case 'n':
                    if (av[i][2] != 'D' || av[i][3] != '\0')
                    {
                        OString tmp("'-nD', please check");
                            tmp += " your input '" + OString(av[i]) + "'";
                        throw IllegalArgument(tmp);
                    }

                    m_options["-nD"] = OString("");
                    break;
                case 'T':
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-T', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    if (m_options.count("-T") > 0)
                    {
                        OString tmp(m_options["-T"]);
                        tmp = tmp + ";" + s;
                        m_options["-T"] = tmp;
                    }
                    else
                    {
                        m_options["-T"] = OString(s);
                    }
                    break;
                case 'L':
                    if (av[i][2] != '\0')
                    {
                        OString tmp("'-L', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    if (isValid("-C") || isValid("-CS"))
                    {
                        OString tmp("'-L' could not be combined with '-C' or '-CS' option");
                        throw IllegalArgument(tmp);
                    }
                    m_options["-L"] = OString("");
                    break;
                case 'C':
                    if (av[i][2] == 'S')
                    {
                        if (av[i][3] != '\0')
                        {
                            OString tmp("'-CS', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }

                        if (isValid("-L") || isValid("-C"))
                        {
                            OString tmp("'-CS' could not be combined with '-L' or '-C' option");
                            throw IllegalArgument(tmp);
                        }
                        m_options["-CS"] = OString("");
                        break;
                    }
                    else if (av[i][2] != '\0')
                    {
                        OString tmp("'-C', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    if (isValid("-L") || isValid("-CS"))
                    {
                        OString tmp("'-C' could not be combined with '-L' or '-CS' option");
                        throw IllegalArgument(tmp);
                    }
                    m_options["-C"] = OString("");
                    break;
                case 'G':
                    if (av[i][2] == 'c')
                    {
                        if (av[i][3] != '\0')
                        {
                            OString tmp("'-Gc', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }

                        m_options["-Gc"] = OString("");
                        break;
                    }
                    else if (av[i][2] != '\0')
                    {
                        OString tmp("'-G', please check");
                        if (i <= ac - 1)
                        {
                            tmp += " your input '" + OString(av[i]) + "'";
                        }

                        throw IllegalArgument(tmp);
                    }

                    m_options["-G"] = OString("");
                    break;
                case 'X': // support for eXtra type rdbs
                {
                    if (av[i][2] == '\0')
                    {
                        if (i < ac - 1 && av[i+1][0] != '-')
                        {
                            i++;
                            s = av[i];
                        }
                        else
                        {
                            OString tmp("'-X', please check");
                            if (i <= ac - 1)
                            {
                                tmp += " your input '" + OString(av[i+1]) + "'";
                            }

                            throw IllegalArgument(tmp);
                        }
                    }
                    else
                    {
                        s = av[i] + 2;
                    }

                    m_extra_input_files.push_back( s );
                    break;
                }

                default:
                    throw IllegalArgument("the option is unknown" + OString(av[i]));
            }
        } else
        {
            if (av[i][0] == '@')
            {
                FILE* cmdFile = fopen(av[i]+1, "r");
                if( cmdFile == NULL )
                {
                    fprintf(stderr, "%s", prepareHelp().getStr());
                    ret = sal_False;
                }
                else
                {
                    int rargc=0;
                    char* rargv[512];
                    char  buffer[512];

                    while ( fscanf(cmdFile, "%s", buffer) != EOF )
                    {
                        rargv[rargc]= strdup(buffer);
                        rargc++;
                    }
                    fclose(cmdFile);

                    ret = initOptions(rargc, rargv, bCmdFile);

                    for (long j=0; j < rargc; j++)
                    {
                        free(rargv[j]);
                    }
                }
            }
            else
            {
                m_inputFiles.push_back(av[i]);
            }
        }
    }

    return ret;
}

OString CppuOptions::prepareHelp()
{
    OString help("\nusing: ");
    help += m_program + " [-options] file_1 ... file_n\nOptions:\n";
    help += "    -O<path>   = path describes the root directory for the generated output.\n";
    help += "                 The output directory tree is generated under this directory.\n";
    help += "    -T<name>   = name specifies a type or a list of types. The output for this\n";
    help += "      [t1;...]   type is generated. If no '-T' option is specified,\n";
    help += "                 then output for all types is generated.\n";
    help += "                 Example: 'com.sun.star.uno.XInterface' is a valid type.\n";
    help += "    -L         = UNO type functions are generated lightweight, that means only\n";
    help += "                 the name and typeclass are given and everything else is retrieved\n";
    help += "                 from the type library dynamically. The default is that UNO type\n";
    help += "                 functions provides enough type information for bootstrapping C++.\n";
    help += "                 '-L' should be the default for external components.\n";
    help += "    -C         = UNO type functions are generated comprehensive that means all\n";
    help += "                 necessary information is available for bridging the type in UNO.\n";
    help += "    -nD        = no dependent types are generated.\n";
    help += "    -G         = generate only target files which does not exists.\n";
    help += "    -Gc        = generate only target files which content will be changed.\n";
    help += "    -X<file>   = extra types which will not be taken into account for generation.\n\n";
    help += prepareVersion();

    return help;
}

OString CppuOptions::prepareVersion()
{
    OString version(m_program);
    version += " Version 2.0\n\n";
    return version;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>///
/// @file   CountPrintPrimes.cpp
/// @brief  CountPrintPrimes is used for counting primes and for
///         printing primes to stdout. After a segment has been sieved
///         (using the parent Erat class) CountPrintPrimes is used
///         to reconstruct primes and prime k-tuplets from 1 bits of
///         the sieve array.
///
/// Copyright (C) 2022 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CountPrintPrimes.hpp>
#include <primesieve/Erat.hpp>
#include <primesieve/forward.hpp>
#include <primesieve/littleendian_cast.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/SievingPrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <iostream>
#include <sstream>

namespace {

const uint64_t bitmasks[6][5] =
{
  { ~0ull },                         // Prime numbers, unused
  { 0x06, 0x18, 0xc0, ~0ull },       // Twin primes: b00000110, b00011000, b11000000
  { 0x07, 0x0e, 0x1c, 0x38, ~0ull }, // Prime triplets: b00000111, b00001110, ...
  { 0x1e, ~0ull },                   // Prime quadruplets: b00011110
  { 0x1f, 0x3e, ~0ull },             // Prime quintuplets: b00011111, b00111110
  { 0x3f, ~0ull }                    // Prime sextuplets: b00111111
};

} // namespace

namespace primesieve {

CountPrintPrimes::CountPrintPrimes(PrimeSieve& ps) :
  counts_(ps.getCounts()),
  ps_(ps)
{
  uint64_t start = ps.getStart();
  uint64_t stop = ps.getStop();
  uint64_t sieveSize = ps.getSieveSize();
  start = std::max<uint64_t>(start, 7);

  ps.getPreSieve().init(start, stop);
  Erat::init(start, stop, sieveSize, ps.getPreSieve(), memoryPool_);

  if (ps_.isCountkTuplets())
    initCounts();
}

/// Initialize the lookup tables to count the number
/// of twins, triplets, ... per byte
///
void CountPrintPrimes::initCounts()
{
  for (unsigned i = 1; i < counts_.size(); i++)
  {
    if (!ps_.isCount(i))
      continue;

    kCounts_[i].resize(256);

    for (uint64_t j = 0; j < 256; j++)
    {
      uint8_t count = 0;
      for (auto* b = bitmasks[i]; *b <= j; b++)
      {
        if ((j & *b) == *b)
          count++;
      }
      kCounts_[i][j] = count;
    }
  }
}

void CountPrintPrimes::sieve()
{
  uint64_t sieveSize = ps_.getSieveSize();
  SievingPrimes sievingPrimes(this, sieveSize, ps_.getPreSieve(), memoryPool_);
  uint64_t prime = sievingPrimes.next();

  while (hasNextSegment())
  {
    low_ = segmentLow_;
    uint64_t sqrtHigh = isqrt(segmentHigh_);

    for (; prime <= sqrtHigh; prime = sievingPrimes.next())
      addSievingPrime(prime);

    sieveSegment();

    if (ps_.isCountPrimes())
      countPrimes();
    if (ps_.isCountkTuplets())
      countkTuplets();
    if (ps_.isPrintPrimes())
      printPrimes();
    if (ps_.isPrintkTuplets())
      printkTuplets();
    if (ps_.isStatus())
      ps_.updateStatus(sieve_.size() * 30);
  }
}

void CountPrintPrimes::countPrimes()
{
  uint64_t size = ceilDiv(sieve_.size(), 8);
  counts_[0] += popcount((const uint64_t*) sieve_.data(), size);
}

void CountPrintPrimes::countkTuplets()
{
  // i = 1 twins, i = 2 triplets, ...
  for (unsigned i = 1; i < counts_.size(); i++)
  {
    if (!ps_.isCount(i))
      continue;

    uint64_t sum = 0;

    for (uint64_t j = 0; j < sieve_.size(); j += 4)
    {
      sum += kCounts_[i][sieve_[j+0]];
      sum += kCounts_[i][sieve_[j+1]];
      sum += kCounts_[i][sieve_[j+2]];
      sum += kCounts_[i][sieve_[j+3]];
    }

    counts_[i] += sum;
  }
}

/// Print primes to stdout
void CountPrintPrimes::printPrimes() const
{
  uint64_t low = low_;
  std::size_t i = 0;

  while (i < sieve_.size())
  {
    std::size_t size = i + (1 << 16);
    size = std::min(size, sieve_.size());
    std::ostringstream primes;

    for (; i < size; i += 8)
    {
      uint64_t bits = littleendian_cast<uint64_t>(&sieve_[i]);
      for (; bits != 0; bits &= bits - 1)
        primes << nextPrime(bits, low) << '\n';

      low += 8 * 30;
    }

    std::cout << primes.str();
  }
}

/// Print prime k-tuplets to stdout
void CountPrintPrimes::printkTuplets() const
{
  // i = 1 twins, i = 2 triplets, ...
  unsigned i = 1;
  uint64_t low = low_;
  std::ostringstream kTuplets;

  while (!ps_.isPrint(i))
    i++;

  for (std::size_t j = 0; j < sieve_.size(); j++, low += 30)
  {
    for (auto* bitmask = bitmasks[i]; *bitmask <= sieve_[j]; bitmask++)
    {
      if ((sieve_[j] & *bitmask) == *bitmask)
      {
        kTuplets << "(";
        uint64_t bits = *bitmask;

        for (; bits != 0; bits &= bits - 1)
        {
          kTuplets << nextPrime(bits, low);
          bool hasNext = (bits & (bits - 1)) != 0;
          kTuplets << (hasNext ? ", " : ")\n");
        }
      }
    }
  }

  std::cout << kTuplets.str();
}

} // namespace
<commit_msg>Add assertion<commit_after>///
/// @file   CountPrintPrimes.cpp
/// @brief  CountPrintPrimes is used for counting primes and for
///         printing primes to stdout. After a segment has been sieved
///         (using the parent Erat class) CountPrintPrimes is used
///         to reconstruct primes and prime k-tuplets from 1 bits of
///         the sieve array.
///
/// Copyright (C) 2022 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CountPrintPrimes.hpp>
#include <primesieve/Erat.hpp>
#include <primesieve/forward.hpp>
#include <primesieve/littleendian_cast.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PreSieve.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/SievingPrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <cassert>
#include <iostream>
#include <sstream>

namespace {

const uint64_t bitmasks[6][5] =
{
  { ~0ull },                         // Prime numbers, unused
  { 0x06, 0x18, 0xc0, ~0ull },       // Twin primes: b00000110, b00011000, b11000000
  { 0x07, 0x0e, 0x1c, 0x38, ~0ull }, // Prime triplets: b00000111, b00001110, ...
  { 0x1e, ~0ull },                   // Prime quadruplets: b00011110
  { 0x1f, 0x3e, ~0ull },             // Prime quintuplets: b00011111, b00111110
  { 0x3f, ~0ull }                    // Prime sextuplets: b00111111
};

} // namespace

namespace primesieve {

CountPrintPrimes::CountPrintPrimes(PrimeSieve& ps) :
  counts_(ps.getCounts()),
  ps_(ps)
{
  uint64_t start = ps.getStart();
  uint64_t stop = ps.getStop();
  uint64_t sieveSize = ps.getSieveSize();
  start = std::max<uint64_t>(start, 7);

  ps.getPreSieve().init(start, stop);
  Erat::init(start, stop, sieveSize, ps.getPreSieve(), memoryPool_);

  if (ps_.isCountkTuplets())
    initCounts();
}

/// Initialize the lookup tables to count the number
/// of twins, triplets, ... per byte
///
void CountPrintPrimes::initCounts()
{
  for (unsigned i = 1; i < counts_.size(); i++)
  {
    if (!ps_.isCount(i))
      continue;

    kCounts_[i].resize(256);

    for (uint64_t j = 0; j < 256; j++)
    {
      uint8_t count = 0;
      for (auto* b = bitmasks[i]; *b <= j; b++)
      {
        if ((j & *b) == *b)
          count++;
      }
      kCounts_[i][j] = count;
    }
  }
}

void CountPrintPrimes::sieve()
{
  uint64_t sieveSize = ps_.getSieveSize();
  SievingPrimes sievingPrimes(this, sieveSize, ps_.getPreSieve(), memoryPool_);
  uint64_t prime = sievingPrimes.next();

  while (hasNextSegment())
  {
    low_ = segmentLow_;
    uint64_t sqrtHigh = isqrt(segmentHigh_);

    for (; prime <= sqrtHigh; prime = sievingPrimes.next())
      addSievingPrime(prime);

    sieveSegment();

    if (ps_.isCountPrimes())
      countPrimes();
    if (ps_.isCountkTuplets())
      countkTuplets();
    if (ps_.isPrintPrimes())
      printPrimes();
    if (ps_.isPrintkTuplets())
      printkTuplets();
    if (ps_.isStatus())
      ps_.updateStatus(sieve_.size() * 30);
  }
}

void CountPrintPrimes::countPrimes()
{
  assert(sieve_.capacity() % sizeof(uint64_t) == 0);
  uint64_t size = ceilDiv(sieve_.size(), 8);
  counts_[0] += popcount((const uint64_t*) sieve_.data(), size);
}

void CountPrintPrimes::countkTuplets()
{
  // i = 1 twins, i = 2 triplets, ...
  for (unsigned i = 1; i < counts_.size(); i++)
  {
    if (!ps_.isCount(i))
      continue;

    uint64_t sum = 0;

    for (uint64_t j = 0; j < sieve_.size(); j += 4)
    {
      sum += kCounts_[i][sieve_[j+0]];
      sum += kCounts_[i][sieve_[j+1]];
      sum += kCounts_[i][sieve_[j+2]];
      sum += kCounts_[i][sieve_[j+3]];
    }

    counts_[i] += sum;
  }
}

/// Print primes to stdout
void CountPrintPrimes::printPrimes() const
{
  uint64_t low = low_;
  std::size_t i = 0;

  while (i < sieve_.size())
  {
    std::size_t size = i + (1 << 16);
    size = std::min(size, sieve_.size());
    std::ostringstream primes;

    for (; i < size; i += 8)
    {
      uint64_t bits = littleendian_cast<uint64_t>(&sieve_[i]);
      for (; bits != 0; bits &= bits - 1)
        primes << nextPrime(bits, low) << '\n';

      low += 8 * 30;
    }

    std::cout << primes.str();
  }
}

/// Print prime k-tuplets to stdout
void CountPrintPrimes::printkTuplets() const
{
  // i = 1 twins, i = 2 triplets, ...
  unsigned i = 1;
  uint64_t low = low_;
  std::ostringstream kTuplets;

  while (!ps_.isPrint(i))
    i++;

  for (std::size_t j = 0; j < sieve_.size(); j++, low += 30)
  {
    for (auto* bitmask = bitmasks[i]; *bitmask <= sieve_[j]; bitmask++)
    {
      if ((sieve_[j] & *bitmask) == *bitmask)
      {
        kTuplets << "(";
        uint64_t bits = *bitmask;

        for (; bits != 0; bits &= bits - 1)
        {
          kTuplets << nextPrime(bits, low);
          bool hasNext = (bits & (bits - 1)) != 0;
          kTuplets << (hasNext ? ", " : ")\n");
        }
      }
    }
  }

  std::cout << kTuplets.str();
}

} // namespace
<|endoftext|>


<commit_before>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#include <NDK/Sdk.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Lua/Lua.hpp>
#include <Nazara/Noise/Noise.hpp>
#include <Nazara/Physics/Physics.hpp>
#include <Nazara/Utility/Utility.hpp>
#include <NDK/Algorithm.hpp>
#include <NDK/BaseSystem.hpp>
#include <NDK/Components/CollisionComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/PhysicsComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#include <NDK/Systems/PhysicsSystem.hpp>
#include <NDK/Systems/VelocitySystem.hpp>

#ifndef NDK_SERVER
#include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/ListenerComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#endif

namespace Ndk
{
	bool Sdk::Initialize()
	{
		if (s_referenceCounter++ > 0)
			return true; // Already initialized

		try
		{
			Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true);

			// Initialize the engine first

			// Shared modules
			Nz::Lua::Initialize();
			Nz::Noise::Initialize();
			Nz::Physics::Initialize();
			Nz::Utility::Initialize();

			#ifndef NDK_SERVER
			// Client modules
			Nz::Audio::Initialize();
			Nz::Graphics::Initialize();
			#endif

			// SDK Initialization

			// Components
			BaseComponent::Initialize();

			// Shared components
			InitializeComponent<CollisionComponent>("NdkColli");
			InitializeComponent<NodeComponent>("NdkNode");
			InitializeComponent<PhysicsComponent>("NdkPhys");
			InitializeComponent<VelocityComponent>("NdkVeloc");

			#ifndef NDK_SERVER
			// Client components
			InitializeComponent<CameraComponent>("NdkCam");
			InitializeComponent<LightComponent>("NdkLight");
			InitializeComponent<ListenerComponent>("NdkList");
			InitializeComponent<GraphicsComponent>("NdkGfx");
			#endif

			// Systems

			BaseSystem::Initialize();

			// Shared systems
			InitializeSystem<PhysicsSystem>();
			InitializeSystem<VelocitySystem>();

			#ifndef NDK_SERVER
			// Client systems
			InitializeSystem<ListenerSystem>();
			InitializeSystem<RenderSystem>();
			#endif

			NazaraNotice("Initialized: SDK");
			return true;
		}
		catch (const std::exception& e)
		{
			NazaraError("Failed to initialize NDK: " + Nz::String(e.what()));

			return false;
		}
	}

	void Sdk::Uninitialize()
	{
		if (s_referenceCounter != 1)
		{
			// Either the module is not initialized, either it was initialized multiple times
			if (s_referenceCounter > 1)
				s_referenceCounter--;

			return;
		}

		// Uninitialize the SDK
		s_referenceCounter = 0;

		// Uninitialize the engine

		#ifndef NDK_SERVER
		// Client modules
		Nz::Audio::Uninitialize();
		Nz::Graphics::Uninitialize();
		#endif

		// Shared modules
		Nz::Lua::Uninitialize();
		Nz::Noise::Uninitialize();
		Nz::Physics::Uninitialize();
		Nz::Utility::Uninitialize();

		NazaraNotice("Uninitialized: SDK");
	}

	unsigned int Sdk::s_referenceCounter = 0;
}
<commit_msg>Sdk: Fix uninitialization of components and systems<commit_after>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#include <NDK/Sdk.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Lua/Lua.hpp>
#include <Nazara/Noise/Noise.hpp>
#include <Nazara/Physics/Physics.hpp>
#include <Nazara/Utility/Utility.hpp>
#include <NDK/Algorithm.hpp>
#include <NDK/BaseSystem.hpp>
#include <NDK/Components/CollisionComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/PhysicsComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#include <NDK/Systems/PhysicsSystem.hpp>
#include <NDK/Systems/VelocitySystem.hpp>

#ifndef NDK_SERVER
#include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/ListenerComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#endif

namespace Ndk
{
	bool Sdk::Initialize()
	{
		if (s_referenceCounter++ > 0)
			return true; // Already initialized

		try
		{
			Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true);

			// Initialize the engine first

			// Shared modules
			Nz::Lua::Initialize();
			Nz::Noise::Initialize();
			Nz::Physics::Initialize();
			Nz::Utility::Initialize();

			#ifndef NDK_SERVER
			// Client modules
			Nz::Audio::Initialize();
			Nz::Graphics::Initialize();
			#endif

			// SDK Initialization

			// Components
			BaseComponent::Initialize();

			// Shared components
			InitializeComponent<CollisionComponent>("NdkColli");
			InitializeComponent<NodeComponent>("NdkNode");
			InitializeComponent<PhysicsComponent>("NdkPhys");
			InitializeComponent<VelocityComponent>("NdkVeloc");

			#ifndef NDK_SERVER
			// Client components
			InitializeComponent<CameraComponent>("NdkCam");
			InitializeComponent<LightComponent>("NdkLight");
			InitializeComponent<ListenerComponent>("NdkList");
			InitializeComponent<GraphicsComponent>("NdkGfx");
			#endif

			// Systems

			BaseSystem::Initialize();

			// Shared systems
			InitializeSystem<PhysicsSystem>();
			InitializeSystem<VelocitySystem>();

			#ifndef NDK_SERVER
			// Client systems
			InitializeSystem<ListenerSystem>();
			InitializeSystem<RenderSystem>();
			#endif

			NazaraNotice("Initialized: SDK");
			return true;
		}
		catch (const std::exception& e)
		{
			NazaraError("Failed to initialize NDK: " + Nz::String(e.what()));

			return false;
		}
	}

	void Sdk::Uninitialize()
	{
		if (s_referenceCounter != 1)
		{
			// Either the module is not initialized, either it was initialized multiple times
			if (s_referenceCounter > 1)
				s_referenceCounter--;

			return;
		}

		// Uninitialize the SDK
		s_referenceCounter = 0;

		// Components
		BaseComponent::Uninitialize();

		// Systems
		BaseSystem::Uninitialize();

		// Uninitialize the engine

		#ifndef NDK_SERVER
		// Client modules
		Nz::Audio::Uninitialize();
		Nz::Graphics::Uninitialize();
		#endif

		// Shared modules
		Nz::Lua::Uninitialize();
		Nz::Noise::Uninitialize();
		Nz::Physics::Uninitialize();
		Nz::Utility::Uninitialize();

		NazaraNotice("Uninitialized: SDK");
	}

	unsigned int Sdk::s_referenceCounter = 0;
}
<|endoftext|>