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

#include "task_map/CollisionDistance.h"

REGISTER_TASKMAP_TYPE("CollisionDistance", exotica::CollisionDistance);

namespace exotica
{
CollisionDistance::CollisionDistance() {}
void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi)
{
    if (phi.rows() != dim_) throw_named("Wrong size of phi!");
    phi.setZero();
    Eigen::MatrixXd J;
    update(x, phi, J, false);
}

void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi,
                               Eigen::MatrixXdRef J)
{
    if (phi.rows() != dim_) throw_named("Wrong size of phi!");
    phi.setZero();
    J.setZero();
    update(x, phi, J, true);
}

void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi,
                               Eigen::MatrixXdRef J,
                               bool updateJacobian)
{
    cscene_->updateCollisionObjectTransforms();

    // For all robot links: Get all collision distances, sort by distance, and process the closest.
    for (unsigned int i = 0; i < dim_; i++)
    {
        std::vector<CollisionProxy> proxies = cscene_->getCollisionDistance(robotLinks_[i], check_self_collision_);  //, false);
        if (proxies.size() == 0)
        {
            phi(i) = 0;
            J.row(i).setZero();
            continue;
        }

        CollisionProxy& closest_proxy = closestProxies_[i];
        closest_proxy.distance = std::numeric_limits<double>::max();
        for (const auto& tmp_proxy : proxies)
        {
            const bool isRobotToRobot = (tmp_proxy.e1->isRobotLink || tmp_proxy.e1->ClosestRobotLink.lock()) && (tmp_proxy.e2->isRobotLink || tmp_proxy.e2->ClosestRobotLink.lock());
            const double& margin = isRobotToRobot ? robot_margin_ : world_margin_;
            if ((tmp_proxy.distance - margin) < closest_proxy.distance)
            {
                closest_proxy = tmp_proxy;
                closest_proxy.distance -= margin;
            }
        }

        phi(i) = closest_proxy.distance;

        if (updateJacobian)
        {
            KDL::Frame arel = KDL::Frame(closest_proxy.e1->Frame.Inverse(KDL::Vector(
                closest_proxy.contact1(0), closest_proxy.contact1(1), closest_proxy.contact1(2))));
            KDL::Frame brel = KDL::Frame(closest_proxy.e2->Frame.Inverse(KDL::Vector(
                closest_proxy.contact2(0), closest_proxy.contact2(1), closest_proxy.contact2(2))));

            Eigen::MatrixXd tmpJ = scene_->getSolver().Jacobian(
                closest_proxy.e1, arel, nullptr, KDL::Frame());
            J.row(i) += (closest_proxy.normal1.transpose() * tmpJ);
            tmpJ = scene_->getSolver().Jacobian(closest_proxy.e2, brel, nullptr,
                                                KDL::Frame());
            J.row(i) -= (closest_proxy.normal1.transpose() * tmpJ);
        }
    }
}

void CollisionDistance::Instantiate(
    CollisionDistanceInitializer& init)
{
    init_ = init;
}

void CollisionDistance::assignScene(Scene_ptr scene)
{
    scene_ = scene;
    Initialize();
}

void CollisionDistance::Initialize()
{
    cscene_ = scene_->getCollisionScene();
    check_self_collision_ = init_.CheckSelfCollision;
    world_margin_ = init_.WorldMargin;
    robot_margin_ = init_.RobotMargin;

    // Get names of all controlled joints and their corresponding child links
    robotLinks_ = scene_->getControlledLinkNames();
    dim_ = static_cast<unsigned int>(robotLinks_.size());
    closestProxies_.assign(dim_, CollisionProxy());
    if (debug_)
    {
        HIGHLIGHT_NAMED("Collision Distance", "Dimension: " << dim_
                                                            << " - CheckSelfCollision: " << check_self_collision_
                                                            << "World Margin: " << world_margin_
                                                            << " Robot Margin: " << robot_margin_);
    }
}

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

#include "task_map/CollisionDistance.h"

REGISTER_TASKMAP_TYPE("CollisionDistance", exotica::CollisionDistance);

namespace exotica
{
CollisionDistance::CollisionDistance() {}
void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi)
{
    if (phi.rows() != dim_) throw_named("Wrong size of phi!");
    phi.setZero();
    Eigen::MatrixXd J;
    update(x, phi, J, false);
}

void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi,
                               Eigen::MatrixXdRef J)
{
    if (phi.rows() != dim_) throw_named("Wrong size of phi!");
    phi.setZero();
    J.setZero();
    update(x, phi, J, true);
}

void CollisionDistance::update(Eigen::VectorXdRefConst x,
                               Eigen::VectorXdRef phi,
                               Eigen::MatrixXdRef J,
                               bool updateJacobian)
{
    cscene_->updateCollisionObjectTransforms();

    // For all robot links: Get all collision distances, sort by distance, and process the closest.
    for (unsigned int i = 0; i < dim_; i++)
    {
        std::vector<CollisionProxy> proxies = cscene_->getCollisionDistance(scene_->getControlledLinkToCollisionLinkMap()[robotLinks_[i]], check_self_collision_);  //, false);
        if (proxies.size() == 0)
        {
            phi(i) = 0;
            J.row(i).setZero();
            continue;
        }

        CollisionProxy& closest_proxy = closestProxies_[i];
        closest_proxy.distance = std::numeric_limits<double>::max();
        for (const auto& tmp_proxy : proxies)
        {
            const bool isRobotToRobot = (tmp_proxy.e1->isRobotLink || tmp_proxy.e1->ClosestRobotLink.lock()) && (tmp_proxy.e2->isRobotLink || tmp_proxy.e2->ClosestRobotLink.lock());
            const double& margin = isRobotToRobot ? robot_margin_ : world_margin_;
            if ((tmp_proxy.distance - margin) < closest_proxy.distance)
            {
                closest_proxy = tmp_proxy;
                closest_proxy.distance -= margin;
            }
        }

        phi(i) = closest_proxy.distance;

        if (updateJacobian)
        {
            KDL::Frame arel = KDL::Frame(closest_proxy.e1->Frame.Inverse(KDL::Vector(
                closest_proxy.contact1(0), closest_proxy.contact1(1), closest_proxy.contact1(2))));
            KDL::Frame brel = KDL::Frame(closest_proxy.e2->Frame.Inverse(KDL::Vector(
                closest_proxy.contact2(0), closest_proxy.contact2(1), closest_proxy.contact2(2))));

            Eigen::MatrixXd tmpJ = scene_->getSolver().Jacobian(
                closest_proxy.e1, arel, nullptr, KDL::Frame());
            J.row(i) += (closest_proxy.normal1.transpose() * tmpJ);
            tmpJ = scene_->getSolver().Jacobian(closest_proxy.e2, brel, nullptr,
                                                KDL::Frame());
            J.row(i) -= (closest_proxy.normal1.transpose() * tmpJ);
        }
    }
}

void CollisionDistance::Instantiate(
    CollisionDistanceInitializer& init)
{
    init_ = init;
}

void CollisionDistance::assignScene(Scene_ptr scene)
{
    scene_ = scene;
    Initialize();
}

void CollisionDistance::Initialize()
{
    cscene_ = scene_->getCollisionScene();
    check_self_collision_ = init_.CheckSelfCollision;
    world_margin_ = init_.WorldMargin;
    robot_margin_ = init_.RobotMargin;

    // Get names of all controlled joints and their corresponding child links
    robotLinks_ = scene_->getControlledLinkNames();
    dim_ = static_cast<unsigned int>(robotLinks_.size());
    closestProxies_.assign(dim_, CollisionProxy());
    if (debug_)
    {
        HIGHLIGHT_NAMED("Collision Distance", "Dimension: " << dim_
                                                            << " - CheckSelfCollision: " << check_self_collision_
                                                            << "World Margin: " << world_margin_
                                                            << " Robot Margin: " << robot_margin_);
    }
}

int CollisionDistance::taskSpaceDim() { return dim_; }
}
<|endoftext|>


<commit_before>#pragma once

#include <type_list.hpp>
#include <integer_sequence.hpp>
#include <sfinae.hpp>

#include "reflection_info.hpp"
#include "director.hpp"

namespace shadow
{
// generate type_list of instantiated compile_time_type_info to feed
// generate_array_of_type_info and generate_array_of_strings
template <template <std::size_t> class CTI, class IntSeqRange>
struct generate_valid_compile_time_type_infos
{
    template <typename IntSeqRange::value_type LineNum>
    using is_defined_predicate =
        metamusil::integral_specialization_defined<std::size_t, CTI, LineNum>;

    typedef metamusil::int_seq::filter_t<IntSeqRange, is_defined_predicate>
        filtered_line_range;

    typedef metamusil::t_list::from_integer_template_instantiations_t<
        std::size_t,
        CTI,
        filtered_line_range>
        type;
};

template <template <std::size_t> class CTI, class IntSeqRange>
using generate_valid_compile_time_type_infos_t =
    typename generate_valid_compile_time_type_infos<CTI, IntSeqRange>::type;

// extract name and make an array of type names at compile time
template <class CompileTimeTypeInfo>
struct extract_name
{
    static constexpr const char* value = CompileTimeTypeInfo::name;
};

template <class TypeListOfCompileTimeTypeInfo>
using generate_array_of_strings =
    metamusil::t_list::value_transform<TypeListOfCompileTimeTypeInfo,
                                       extract_name>;

// extract type info and make array of type_info at compile time
template <class CompileTimeTypeInfo>
struct extract_type_info
{
    static constexpr type_info value = {CompileTimeTypeInfo::name,
                                        CompileTimeTypeInfo::size};
};

template <class TypeListOfCompileTimeTypeInfo>
using generate_array_of_type_info =
    metamusil::t_list::value_transform<TypeListOfCompileTimeTypeInfo,
                                       extract_type_info>;

// extract type from compile_time_info
template <class CTI>
using extract_type = typename CTI::type;

// extract dynamic constructor_info from compile_time_constructor info template
// instantiations
template <class CTCI>
struct extract_constructor_info
{
    static constexpr constructor_info value = {
        CTCI::type_index,
        CTCI::num_parameters,
        CTCI::parameter_type_indices_holder::value,
        CTCI::bind_point};
};

template <class TypeListOfCompileTimeConstructorInfo>
using generate_array_of_constructor_info =
    metamusil::t_list::value_transform<TypeListOfCompileTimeConstructorInfo,
                                       extract_constructor_info>;
}

////////////////////////////////////////////////////////////////////////////////
// Type registration
#define REGISTER_TYPE_BEGIN()                                                  \
    constexpr std::size_t type_line_begin = __LINE__;                          \
    template <std::size_t LineNum>                                             \
    struct compile_time_type_info;

#define REGISTER_TYPE(type_name)                                               \
    template <>                                                                \
    struct compile_time_type_info<__LINE__>                                    \
    {                                                                          \
        typedef type_name type;                                                \
        static constexpr char name[] = #type_name;                             \
        static const std::size_t size = sizeof(type_name);                     \
    };                                                                         \
                                                                               \
    constexpr char compile_time_type_info<__LINE__>::name[];

#define REGISTER_TYPE_END()                                                    \
    constexpr std::size_t type_line_end = __LINE__;                            \
                                                                               \
    typedef metamusil::int_seq::integer_sequence_from_range_t<                 \
        std::size_t,                                                           \
        type_line_begin + 1,                                                   \
        type_line_end>                                                         \
        type_line_range;                                                       \
                                                                               \
    typedef shadow::generate_valid_compile_time_type_infos_t<                  \
        compile_time_type_info,                                                \
        type_line_range>                                                       \
        instantiated_compile_time_infos;                                       \
                                                                               \
    typedef shadow::generate_array_of_strings<instantiated_compile_time_infos> \
        type_name_array_holder;                                                \
                                                                               \
    typedef shadow::generate_array_of_type_info<                               \
        instantiated_compile_time_infos>                                       \
        type_info_array_holder;                                                \
                                                                               \
    typedef metamusil::t_list::type_transform_t<                               \
        instantiated_compile_time_infos,                                       \
        shadow::extract_type>                                                  \
        type_universe;

////////////////////////////////////////////////////////////////////////////////
// Constructor registration
#define REGISTER_CONSTRUCTOR_BEGIN()                                           \
    constexpr std::size_t constructor_line_begin = __LINE__;                   \
                                                                               \
    template <std::size_t>                                                     \
    struct compile_time_constructor_info;

#define REGISTER_CONSTRUCTOR(type_name, ...)                                   \
    template <>                                                                \
    struct compile_time_constructor_info<__LINE__>                             \
    {                                                                          \
        static const std::size_t type_index =                                  \
            metamusil::t_list::index_of_type_v<type_universe, type_name>;      \
                                                                               \
        typedef metamusil::t_list::type_list<__VA_ARGS__> parameter_type_list; \
                                                                               \
        static const std::size_t num_parameters =                              \
            metamusil::t_list::length_v<parameter_type_list>;                  \
                                                                               \
        typedef metamusil::t_list::order_t<parameter_type_list, type_universe> \
            parameter_index_sequence;                                          \
                                                                               \
        typedef metamusil::int_seq::integer_sequence_to_array<                 \
            parameter_index_sequence>                                          \
            parameter_type_indices_holder;                                     \
                                                                               \
        static constexpr shadow::constructor_binding_signature bind_point =    \
            &shadow::constructor_detail::                                      \
                generic_constructor_bind_point<type_name, __VA_ARGS__>;        \
    };

#define REGISTER_CONSTRUCTOR_END()                                             \
    constexpr std::size_t constructor_line_end = __LINE__;                     \
                                                                               \
    typedef metamusil::int_seq::integer_sequence_from_range_t<                 \
        std::size_t,                                                           \
        constructor_line_begin + 1,                                            \
        constructor_line_end>                                                  \
        constructor_line_range;

////////////////////////////////////////////////////////////////////////////////
// Initialize Shadow reflection library
#define SHADOW_INIT()                                                          \
    static const shadow::director reflection_director{                         \
        type_name_array_holder(), type_info_array_holder()};
<commit_msg>Rename generate_valid_compile_time_type_infos to *_infos. 	modified:   include/compile_time.hpp<commit_after>#pragma once

#include <type_list.hpp>
#include <integer_sequence.hpp>
#include <sfinae.hpp>

#include "reflection_info.hpp"
#include "director.hpp"

namespace shadow
{
// generate type_list of instantiated compile_time_type_info to feed
// generate_array_of_type_info and generate_array_of_strings
template <template <std::size_t> class CTI, class IntSeqRange>
struct generate_valid_compile_time_infos
{
    template <typename IntSeqRange::value_type LineNum>
    using is_defined_predicate =
        metamusil::integral_specialization_defined<std::size_t, CTI, LineNum>;

    typedef metamusil::int_seq::filter_t<IntSeqRange, is_defined_predicate>
        filtered_line_range;

    typedef metamusil::t_list::from_integer_template_instantiations_t<
        std::size_t,
        CTI,
        filtered_line_range>
        type;
};

template <template <std::size_t> class CTI, class IntSeqRange>
using generate_valid_compile_time_infos_t =
    typename generate_valid_compile_time_infos<CTI, IntSeqRange>::type;

// extract name and make an array of type names at compile time
template <class CompileTimeTypeInfo>
struct extract_name
{
    static constexpr const char* value = CompileTimeTypeInfo::name;
};

template <class TypeListOfCompileTimeTypeInfo>
using generate_array_of_strings =
    metamusil::t_list::value_transform<TypeListOfCompileTimeTypeInfo,
                                       extract_name>;

// extract type info and make array of type_info at compile time
template <class CompileTimeTypeInfo>
struct extract_type_info
{
    static constexpr type_info value = {CompileTimeTypeInfo::name,
                                        CompileTimeTypeInfo::size};
};

template <class TypeListOfCompileTimeTypeInfo>
using generate_array_of_type_info =
    metamusil::t_list::value_transform<TypeListOfCompileTimeTypeInfo,
                                       extract_type_info>;

// extract type from compile_time_info
template <class CTI>
using extract_type = typename CTI::type;

// extract dynamic constructor_info from compile_time_constructor info template
// instantiations
template <class CTCI>
struct extract_constructor_info
{
    static constexpr constructor_info value = {
        CTCI::type_index,
        CTCI::num_parameters,
        CTCI::parameter_type_indices_holder::value,
        CTCI::bind_point};
};

template <class TypeListOfCompileTimeConstructorInfo>
using generate_array_of_constructor_info =
    metamusil::t_list::value_transform<TypeListOfCompileTimeConstructorInfo,
                                       extract_constructor_info>;
}

////////////////////////////////////////////////////////////////////////////////
// Type registration
#define REGISTER_TYPE_BEGIN()                                                  \
    constexpr std::size_t type_line_begin = __LINE__;                          \
    template <std::size_t LineNum>                                             \
    struct compile_time_type_info;

#define REGISTER_TYPE(type_name)                                               \
    template <>                                                                \
    struct compile_time_type_info<__LINE__>                                    \
    {                                                                          \
        typedef type_name type;                                                \
        static constexpr char name[] = #type_name;                             \
        static const std::size_t size = sizeof(type_name);                     \
    };                                                                         \
                                                                               \
    constexpr char compile_time_type_info<__LINE__>::name[];

#define REGISTER_TYPE_END()                                                    \
    constexpr std::size_t type_line_end = __LINE__;                            \
                                                                               \
    typedef metamusil::int_seq::integer_sequence_from_range_t<                 \
        std::size_t,                                                           \
        type_line_begin + 1,                                                   \
        type_line_end>                                                         \
        type_line_range;                                                       \
                                                                               \
    typedef shadow::generate_valid_compile_time_infos_t<                       \
        compile_time_type_info,                                                \
        type_line_range>                                                       \
        instantiated_compile_time_infos;                                       \
                                                                               \
    typedef shadow::generate_array_of_strings<instantiated_compile_time_infos> \
        type_name_array_holder;                                                \
                                                                               \
    typedef shadow::generate_array_of_type_info<                               \
        instantiated_compile_time_infos>                                       \
        type_info_array_holder;                                                \
                                                                               \
    typedef metamusil::t_list::type_transform_t<                               \
        instantiated_compile_time_infos,                                       \
        shadow::extract_type>                                                  \
        type_universe;

////////////////////////////////////////////////////////////////////////////////
// Constructor registration
#define REGISTER_CONSTRUCTOR_BEGIN()                                           \
    constexpr std::size_t constructor_line_begin = __LINE__;                   \
                                                                               \
    template <std::size_t>                                                     \
    struct compile_time_constructor_info;

#define REGISTER_CONSTRUCTOR(type_name, ...)                                   \
    template <>                                                                \
    struct compile_time_constructor_info<__LINE__>                             \
    {                                                                          \
        static const std::size_t type_index =                                  \
            metamusil::t_list::index_of_type_v<type_universe, type_name>;      \
                                                                               \
        typedef metamusil::t_list::type_list<__VA_ARGS__> parameter_type_list; \
                                                                               \
        static const std::size_t num_parameters =                              \
            metamusil::t_list::length_v<parameter_type_list>;                  \
                                                                               \
        typedef metamusil::t_list::order_t<parameter_type_list, type_universe> \
            parameter_index_sequence;                                          \
                                                                               \
        typedef metamusil::int_seq::integer_sequence_to_array<                 \
            parameter_index_sequence>                                          \
            parameter_type_indices_holder;                                     \
                                                                               \
        static constexpr shadow::constructor_binding_signature bind_point =    \
            &shadow::constructor_detail::                                      \
                generic_constructor_bind_point<type_name, __VA_ARGS__>;        \
    };

#define REGISTER_CONSTRUCTOR_END()                                             \
    constexpr std::size_t constructor_line_end = __LINE__;                     \
                                                                               \
    typedef metamusil::int_seq::integer_sequence_from_range_t<                 \
        std::size_t,                                                           \
        constructor_line_begin + 1,                                            \
        constructor_line_end>                                                  \
        constructor_line_range;

////////////////////////////////////////////////////////////////////////////////
// Initialize Shadow reflection library
#define SHADOW_INIT()                                                          \
    static const shadow::director reflection_director{                         \
        type_name_array_holder(), type_info_array_holder()};
<|endoftext|>


<commit_before>#ifndef VECTOR3_H
#define VECTOR3_H

#include <gdnative/vector3.h>

#include "Defs.hpp"

#include "String.hpp"

#include <Math.hpp>

namespace godot {

class Basis;

struct Vector3 {

	enum Axis {
		AXIS_X,
		AXIS_Y,
		AXIS_Z,
	};

	union {
		struct {
			real_t x;
			real_t y;
			real_t z;
		};

		real_t coord[3]; // Not for direct access, use [] operator instead
	};

	inline Vector3(real_t x, real_t y, real_t z) {
		this->x = x;
		this->y = y;
		this->z = z;
	}

	inline Vector3() {
		this->x = 0;
		this->y = 0;
		this->z = 0;
	}

	inline const real_t &operator[](int p_axis) const {
		return coord[p_axis];
	}

	inline real_t &operator[](int p_axis) {
		return coord[p_axis];
	}

	inline Vector3 &operator+=(const Vector3 &p_v) {
		x += p_v.x;
		y += p_v.y;
		z += p_v.z;
		return *this;
	}

	inline Vector3 operator+(const Vector3 &p_v) const {
		Vector3 v = *this;
		v += p_v;
		return v;
	}

	inline Vector3 &operator-=(const Vector3 &p_v) {
		x -= p_v.x;
		y -= p_v.y;
		z -= p_v.z;
		return *this;
	}

	inline Vector3 operator-(const Vector3 &p_v) const {
		Vector3 v = *this;
		v -= p_v;
		return v;
	}

	inline Vector3 &operator*=(const Vector3 &p_v) {
		x *= p_v.x;
		y *= p_v.y;
		z *= p_v.z;
		return *this;
	}

	inline Vector3 operator*(const Vector3 &p_v) const {
		Vector3 v = *this;
		v *= p_v;
		return v;
	}

	inline Vector3 &operator/=(const Vector3 &p_v) {
		x /= p_v.x;
		y /= p_v.y;
		z /= p_v.z;
		return *this;
	}

	inline Vector3 operator/(const Vector3 &p_v) const {
		Vector3 v = *this;
		v /= p_v;
		return v;
	}

	inline Vector3 &operator*=(real_t p_scalar) {
		*this *= Vector3(p_scalar, p_scalar, p_scalar);
		return *this;
	}

	inline Vector3 operator*(real_t p_scalar) const {
		Vector3 v = *this;
		v *= p_scalar;
		return v;
	}

	inline Vector3 &operator/=(real_t p_scalar) {
		*this /= Vector3(p_scalar, p_scalar, p_scalar);
		return *this;
	}

	inline Vector3 operator/(real_t p_scalar) const {
		Vector3 v = *this;
		v /= p_scalar;
		return v;
	}

	inline Vector3 operator-() const {
		return Vector3(-x, -y, -z);
	}

	inline bool operator==(const Vector3 &p_v) const {
		return (x == p_v.x && y == p_v.y && z == p_v.z);
	}

	inline bool operator!=(const Vector3 &p_v) const {
		return (x != p_v.x || y != p_v.y || z != p_v.z);
	}

	bool operator<(const Vector3 &p_v) const;

	bool operator<=(const Vector3 &p_v) const;

	inline Vector3 abs() const {
		return Vector3(::fabs(x), ::fabs(y), ::fabs(z));
	}

	inline Vector3 ceil() const {
		return Vector3(::ceil(x), ::ceil(y), ::ceil(z));
	}

	inline Vector3 cross(const Vector3 &b) const {
		Vector3 ret(
				(y * b.z) - (z * b.y),
				(z * b.x) - (x * b.z),
				(x * b.y) - (y * b.x));

		return ret;
	}

	inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const {
		return Vector3(
				x + (p_t * (p_b.x - x)),
				y + (p_t * (p_b.y - y)),
				z + (p_t * (p_b.z - z)));
	}

	Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const;

	Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const {
		Vector3 v = *this;
		Vector3 vd = p_to - v;
		real_t len = vd.length();
		return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
	}

	Vector3 bounce(const Vector3 &p_normal) const {
		return -reflect(p_normal);
	}

	inline real_t length() const {
		real_t x2 = x * x;
		real_t y2 = y * y;
		real_t z2 = z * z;

		return ::sqrt(x2 + y2 + z2);
	}

	inline real_t length_squared() const {
		real_t x2 = x * x;
		real_t y2 = y * y;
		real_t z2 = z * z;

		return x2 + y2 + z2;
	}

	inline real_t distance_squared_to(const Vector3 &b) const {
		return (b - *this).length_squared();
	}

	inline real_t distance_to(const Vector3 &b) const {
		return (b - *this).length();
	}

	inline real_t dot(const Vector3 &b) const {
		return x * b.x + y * b.y + z * b.z;
	}

	inline real_t angle_to(const Vector3 &b) const {
		return std::atan2(cross(b).length(), dot(b));
	}

	inline Vector3 direction_to(const Vector3 &p_b) const {
		Vector3 ret(p_b.x - x, p_b.y - y, p_b.z - z);
		ret.normalize();
		return ret;
	}

	inline Vector3 floor() const {
		return Vector3(::floor(x), ::floor(y), ::floor(z));
	}

	inline Vector3 inverse() const {
		return Vector3(1.f / x, 1.f / y, 1.f / z);
	}

	inline bool is_normalized() const {
		return std::abs(length_squared() - 1.f) < 0.00001f;
	}

	Basis outer(const Vector3 &b) const;

	int max_axis() const;

	int min_axis() const;

	inline void normalize() {
		real_t l = length();
		if (l == 0) {
			x = y = z = 0;
		} else {
			x /= l;
			y /= l;
			z /= l;
		}
	}

	inline Vector3 normalized() const {
		Vector3 v = *this;
		v.normalize();
		return v;
	}

	inline Vector3 reflect(const Vector3 &p_normal) const {
		return -(*this - p_normal * this->dot(p_normal) * 2.0);
	}

	inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {
		Vector3 v = *this;
		v.rotate(axis, phi);
		return v;
	}

	void rotate(const Vector3 &p_axis, real_t p_phi);

	inline Vector3 slide(const Vector3 &by) const {
		return by - *this * this->dot(by);
	}

	void snap(real_t p_val);

	inline Vector3 snapped(const float by) {
		Vector3 v = *this;
		v.snap(by);
		return v;
	}

	operator String() const;
};

inline Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) {
	return p_vec * p_scalar;
}

inline Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {

	return p_a.cross(p_b);
}

} // namespace godot

#endif // VECTOR3_H
<commit_msg>Update Vector3 slide to match godot implementation<commit_after>#ifndef VECTOR3_H
#define VECTOR3_H

#include <gdnative/vector3.h>

#include "Defs.hpp"

#include "String.hpp"

#include <Math.hpp>

namespace godot {

class Basis;

struct Vector3 {

	enum Axis {
		AXIS_X,
		AXIS_Y,
		AXIS_Z,
	};

	union {
		struct {
			real_t x;
			real_t y;
			real_t z;
		};

		real_t coord[3]; // Not for direct access, use [] operator instead
	};

	inline Vector3(real_t x, real_t y, real_t z) {
		this->x = x;
		this->y = y;
		this->z = z;
	}

	inline Vector3() {
		this->x = 0;
		this->y = 0;
		this->z = 0;
	}

	inline const real_t &operator[](int p_axis) const {
		return coord[p_axis];
	}

	inline real_t &operator[](int p_axis) {
		return coord[p_axis];
	}

	inline Vector3 &operator+=(const Vector3 &p_v) {
		x += p_v.x;
		y += p_v.y;
		z += p_v.z;
		return *this;
	}

	inline Vector3 operator+(const Vector3 &p_v) const {
		Vector3 v = *this;
		v += p_v;
		return v;
	}

	inline Vector3 &operator-=(const Vector3 &p_v) {
		x -= p_v.x;
		y -= p_v.y;
		z -= p_v.z;
		return *this;
	}

	inline Vector3 operator-(const Vector3 &p_v) const {
		Vector3 v = *this;
		v -= p_v;
		return v;
	}

	inline Vector3 &operator*=(const Vector3 &p_v) {
		x *= p_v.x;
		y *= p_v.y;
		z *= p_v.z;
		return *this;
	}

	inline Vector3 operator*(const Vector3 &p_v) const {
		Vector3 v = *this;
		v *= p_v;
		return v;
	}

	inline Vector3 &operator/=(const Vector3 &p_v) {
		x /= p_v.x;
		y /= p_v.y;
		z /= p_v.z;
		return *this;
	}

	inline Vector3 operator/(const Vector3 &p_v) const {
		Vector3 v = *this;
		v /= p_v;
		return v;
	}

	inline Vector3 &operator*=(real_t p_scalar) {
		*this *= Vector3(p_scalar, p_scalar, p_scalar);
		return *this;
	}

	inline Vector3 operator*(real_t p_scalar) const {
		Vector3 v = *this;
		v *= p_scalar;
		return v;
	}

	inline Vector3 &operator/=(real_t p_scalar) {
		*this /= Vector3(p_scalar, p_scalar, p_scalar);
		return *this;
	}

	inline Vector3 operator/(real_t p_scalar) const {
		Vector3 v = *this;
		v /= p_scalar;
		return v;
	}

	inline Vector3 operator-() const {
		return Vector3(-x, -y, -z);
	}

	inline bool operator==(const Vector3 &p_v) const {
		return (x == p_v.x && y == p_v.y && z == p_v.z);
	}

	inline bool operator!=(const Vector3 &p_v) const {
		return (x != p_v.x || y != p_v.y || z != p_v.z);
	}

	bool operator<(const Vector3 &p_v) const;

	bool operator<=(const Vector3 &p_v) const;

	inline Vector3 abs() const {
		return Vector3(::fabs(x), ::fabs(y), ::fabs(z));
	}

	inline Vector3 ceil() const {
		return Vector3(::ceil(x), ::ceil(y), ::ceil(z));
	}

	inline Vector3 cross(const Vector3 &b) const {
		Vector3 ret(
				(y * b.z) - (z * b.y),
				(z * b.x) - (x * b.z),
				(x * b.y) - (y * b.x));

		return ret;
	}

	inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const {
		return Vector3(
				x + (p_t * (p_b.x - x)),
				y + (p_t * (p_b.y - y)),
				z + (p_t * (p_b.z - z)));
	}

	Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const;

	Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const {
		Vector3 v = *this;
		Vector3 vd = p_to - v;
		real_t len = vd.length();
		return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
	}

	Vector3 bounce(const Vector3 &p_normal) const {
		return -reflect(p_normal);
	}

	inline real_t length() const {
		real_t x2 = x * x;
		real_t y2 = y * y;
		real_t z2 = z * z;

		return ::sqrt(x2 + y2 + z2);
	}

	inline real_t length_squared() const {
		real_t x2 = x * x;
		real_t y2 = y * y;
		real_t z2 = z * z;

		return x2 + y2 + z2;
	}

	inline real_t distance_squared_to(const Vector3 &b) const {
		return (b - *this).length_squared();
	}

	inline real_t distance_to(const Vector3 &b) const {
		return (b - *this).length();
	}

	inline real_t dot(const Vector3 &b) const {
		return x * b.x + y * b.y + z * b.z;
	}

	inline real_t angle_to(const Vector3 &b) const {
		return std::atan2(cross(b).length(), dot(b));
	}

	inline Vector3 direction_to(const Vector3 &p_b) const {
		Vector3 ret(p_b.x - x, p_b.y - y, p_b.z - z);
		ret.normalize();
		return ret;
	}

	inline Vector3 floor() const {
		return Vector3(::floor(x), ::floor(y), ::floor(z));
	}

	inline Vector3 inverse() const {
		return Vector3(1.f / x, 1.f / y, 1.f / z);
	}

	inline bool is_normalized() const {
		return std::abs(length_squared() - 1.f) < 0.00001f;
	}

	Basis outer(const Vector3 &b) const;

	int max_axis() const;

	int min_axis() const;

	inline void normalize() {
		real_t l = length();
		if (l == 0) {
			x = y = z = 0;
		} else {
			x /= l;
			y /= l;
			z /= l;
		}
	}

	inline Vector3 normalized() const {
		Vector3 v = *this;
		v.normalize();
		return v;
	}

	inline Vector3 reflect(const Vector3 &p_normal) const {
		return -(*this - p_normal * this->dot(p_normal) * 2.0);
	}

	inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {
		Vector3 v = *this;
		v.rotate(axis, phi);
		return v;
	}

	void rotate(const Vector3 &p_axis, real_t p_phi);

	inline Vector3 slide(const Vector3 &by) const {
		return *this - by * this->dot(by);
	}

	void snap(real_t p_val);

	inline Vector3 snapped(const float by) {
		Vector3 v = *this;
		v.snap(by);
		return v;
	}

	operator String() const;
};

inline Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) {
	return p_vec * p_scalar;
}

inline Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {

	return p_a.cross(p_b);
}

} // namespace godot

#endif // VECTOR3_H
<|endoftext|>


<commit_before>#ifndef MPACK_ALGORITHM_HPP
#define MPACK_ALGORITHM_HPP

#include "IndexedSkipList.hpp"
#include "StaticStack.hpp"
#include "StaticQueue.hpp"
#include "SearchList.hpp"
#include "AVL.hpp"

#endif
<commit_msg>Added Geometry.hpp to Algorithms module<commit_after>#ifndef MPACK_ALGORITHM_HPP
#define MPACK_ALGORITHM_HPP

#include "IndexedSkipList.hpp"
#include "StaticStack.hpp"
#include "StaticQueue.hpp"
#include "SearchList.hpp"
#include "AVL.hpp"

#include "Geometry.hpp"
#include "Polygon.hpp"

#endif
<|endoftext|>


<commit_before>#ifndef GLHPP_OBJECT_HPP
#define GLHPP_OBJECT_HPP

#include<memory>

namespace gl
{

namespace impl
{

template<class IDType>
class Resource
{
private:
	std::unique_ptr<int> objects_are_noncopyable;

protected:
	IDType id;
	typedef void (*DeleterFuncPtr)(GLsizei,const IDType*);
	DeleterFuncPtr deleter_func;
	static void NullDeleter(GLsizei,const IDType*) {};
public:
	Resource& operator=(Resource<IDType>&& other)
	{
		if (this != &other && id != other.id)
		{
			if (id != 0)
			{
				deleter_func(1, &id);
			}

			id = std::move(other.id);
			other.id = 0;
		}

		deleter_func = std::move(other.deleter_func);

		return *this;
	}
	Resource(Resource<IDType>&& other):Resource()
	{
		*this=std::move(other);
	}
	const IDType& name() const
	{
		return id;
	}

	virtual GLboolean Is() const=0;

#ifndef GLHPP_STRICT_API
	operator bool() const { return Is(); }
#endif

protected:
	Resource(const IDType& tname=IDType(0)):
		id(tname)
	{}
	virtual ~Resource()  //This is required to be virtual in case anyone uses Object*
	{
		if(id!=0)
		{
			deleter_func(1,&id);
		}
	}

};

class Object: public Resource<GLuint>
{
protected:
	Object(GLuint tid=0):Resource(tid)
	{}
public:
};

struct NullInitializerFlagType {};

template<GLenum GLOBJECTENUM>
class EnumerableObject: public Object
{
protected:
	using Object::Object;
public:
	void Label(GLsizei length,const char* dat)
	{
		glObjectLabel(GLOBJECTENUM,name(),length,dat);
	}
	void GetLabel(GLsizei bufSize,const GLsizei* lenout,char* out) const
	{
		glGetObjectLabel(GLOBJECTENUM,name(),bufSize,lenout,out);
	}
#ifndef GLHPP_STRICT_API
	#if __cplusplus >= 201703L
	void Label(const std::string_view& str)
	{
		Label(str.length(),str.data());
	}
	#else
	void Label(const std::string& str)
	{
		Label(str.length(),str.c_str());
	}
	#endif
	std::string GetLabel() const
	{

		GLsizei bufsize;
		GLint mxsize;
		glGetIntegerv(GL_MAX_LABEL_LENGTH,&mxsize);
		bufsize=mxsize;
		std::string out(bufsize+1,'\0');
		GLsizei lenout;
		GetLabel(bufsize,&lenout,const_cast<char*>(out.data()));
		out.resize(lenout);
		return out;
	}
#endif

};

template<class GLHPPTYPE,GLenum GLOBJECTENUM>
class DefaultableObject:public EnumerableObject<GLOBJECTENUM>
{
protected:
	using EnumerableObject<GLOBJECTENUM>::EnumerableObject;
public:
	static GLHPPTYPE& Default(){
		static GLHPPTYPE dzt((NullInitializerFlagType()));
		return dzt;
	}
};
}

}

#endif
<commit_msg>Make the () operator return name not Is()<commit_after>#ifndef GLHPP_OBJECT_HPP
#define GLHPP_OBJECT_HPP

#include<memory>

namespace gl
{

namespace impl
{

template<class IDType>
class Resource
{
private:
	std::unique_ptr<int> objects_are_noncopyable;

protected:
	IDType id;
	typedef void (*DeleterFuncPtr)(GLsizei,const IDType*);
	DeleterFuncPtr deleter_func;
	static void NullDeleter(GLsizei,const IDType*) {};
public:
	Resource& operator=(Resource<IDType>&& other)
	{
		if (this != &other && id != other.id)
		{
			if (id != 0)
			{
				deleter_func(1, &id);
			}

			id = std::move(other.id);
			other.id = 0;
		}

		deleter_func = std::move(other.deleter_func);

		return *this;
	}
	Resource(Resource<IDType>&& other):Resource()
	{
		*this=std::move(other);
	}
	const IDType& name() const
	{
		return id;
	}

	virtual GLboolean Is() const=0;

#ifndef GLHPP_STRICT_API
	operator IDType() const { return id; }
#endif

protected:
	Resource(const IDType& tname=IDType(0)):
		id(tname)
	{}
	virtual ~Resource()  //This is required to be virtual in case anyone uses Object*
	{
		if(id!=0)
		{
			deleter_func(1,&id);
		}
	}

};

class Object: public Resource<GLuint>
{
protected:
	Object(GLuint tid=0):Resource(tid)
	{}
public:
};

struct NullInitializerFlagType {};

template<GLenum GLOBJECTENUM>
class EnumerableObject: public Object
{
protected:
	using Object::Object;
public:
	void Label(GLsizei length,const char* dat)
	{
		glObjectLabel(GLOBJECTENUM,name(),length,dat);
	}
	void GetLabel(GLsizei bufSize,const GLsizei* lenout,char* out) const
	{
		glGetObjectLabel(GLOBJECTENUM,name(),bufSize,lenout,out);
	}
#ifndef GLHPP_STRICT_API
	#if __cplusplus >= 201703L
	void Label(const std::string_view& str)
	{
		Label(str.length(),str.data());
	}
	#else
	void Label(const std::string& str)
	{
		Label(str.length(),str.c_str());
	}
	#endif
	std::string GetLabel() const
	{

		GLsizei bufsize;
		GLint mxsize;
		glGetIntegerv(GL_MAX_LABEL_LENGTH,&mxsize);
		bufsize=mxsize;
		std::string out(bufsize+1,'\0');
		GLsizei lenout;
		GetLabel(bufsize,&lenout,const_cast<char*>(out.data()));
		out.resize(lenout);
		return out;
	}
#endif

};

template<class GLHPPTYPE,GLenum GLOBJECTENUM>
class DefaultableObject:public EnumerableObject<GLOBJECTENUM>
{
protected:
	using EnumerableObject<GLOBJECTENUM>::EnumerableObject;
public:
	static GLHPPTYPE& Default(){
		static GLHPPTYPE dzt((NullInitializerFlagType()));
		return dzt;
	}
};
}

}

#endif
<|endoftext|>


<commit_before>// Copyright 2017 Adam Smith
//
// 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 "as/serial_value/serial_value.hpp"

namespace as {

	// serial_value

	serial_value::serial_value() throw() :
		mType(NULL_T)
	{}

	serial_value::serial_value(type aType) throw() :
		mType(aType)
	{
		switch(mType) {
		case STRING_T:
			mString = new string_t();
			break;
		case ARRAY_T:
			mArray = new array_t();
			break;
		case OBJECT_T:
			mObject = new object_t();
			break;
		}
	}

	serial_value::serial_value(bool_t aValue) throw() :
		mType(BOOL_T),
		mBool(aValue)
	{}

	serial_value::serial_value(uint8_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint16_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint32_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint64_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(int8_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int16_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int32_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int64_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(float aValue) throw() :
		mType(FLOAT_T),
		mFloat(aValue)
	{}

	serial_value::serial_value(double aValue) throw() :
		mType(FLOAT_T),
		mFloat(aValue)
	{}

	serial_value::serial_value(const string_t& aValue) throw() :
		mType(STRING_T),
		mString(new string_t(aValue))
	{}

	serial_value::serial_value(const char* aValue) throw() :
		mType(STRING_T),
		mString(new string_t(aValue))
	{}

	serial_value::~serial_value() throw() {
		set_null();
	}

	void serial_value::set_null() throw() {
		switch(mType) {
		case NULL_T :
			break;
		case CHAR_T:
			break;
		case BOOL_T:
			break;
		case UNSIGNED_T:
			break;
		case SIGNED_T:
			break;
		case FLOAT_T:
			break;
		case POINTER_T:
			break;
		case STRING_T:
			delete mString;
			break;
		case ARRAY_T:
			delete mArray;
			break;
		case OBJECT_T:
			delete mObject;
			break;
		}
		mType = NULL_T;
	}

	serial_value::char_t& serial_value::set_char() throw() {
		if(mType != CHAR_T) {
			set_null();
			mType = CHAR_T;
		}
		return mChar;
	}

	serial_value::bool_t& serial_value::set_bool() throw() {
		if(mType != BOOL_T) {
			set_null();
			mType = BOOL_T;
		}
		return mBool;
	}

	serial_value::unsigned_t& serial_value::set_unsigned() throw() {
		if(mType != UNSIGNED_T) {
			set_null();
			mType = UNSIGNED_T;
		}
		return mUnsigned;
	}

	serial_value::signed_t& serial_value::set_signed() throw() {
		if(mType != SIGNED_T) {
			set_null();
			mType = SIGNED_T;
		}
		return mSigned;
	}

	serial_value::float_t& serial_value::set_float() throw() {
		if(mType != FLOAT_T) {
			set_null();
			mType = FLOAT_T;
		}
		return mFloat;
	}

	serial_value::pointer_t& serial_value::set_pointer() throw() {
		if(mType != POINTER_T) {
			set_null();
			mType = POINTER_T;
		}
		return mPointer;
	}

	serial_value::string_t& serial_value::set_string() throw() {
		if(mType != STRING_T) {
			set_null();
			mType = STRING_T;
			mString = new string_t();
		}else {
			mString->clear();
		}

	return			*mString;
	}

	serial_value::array_t& serial_value::set_array() throw() {
		if(mType != ARRAY_T) {
			set_null();
			mType = ARRAY_T;
			mArray = new array_t();
		}else {
			mArray->clear();
		}
		return *mArray;
	}

	serial_value::object_t& serial_value::set_object() throw() {
		if(mType != OBJECT_T) {
			set_null();
			mType = OBJECT_T;
			mObject = new object_t();
		}else {
			mObject->clear();
		}
		return *mObject;
	}

	serial_value::char_t& serial_value::get_char() {
		if(mType == CHAR_T) return mChar;
		set_char() = const_cast<const serial_value*>(this)->get_char();
		return mChar;
	}

	serial_value::bool_t& serial_value::get_bool() {
		if(mType == BOOL_T) return mBool;
		set_bool() = const_cast<const serial_value*>(this)->get_bool();
		return mBool;
	}

	serial_value::unsigned_t& serial_value::get_unsigned() {
		if(mType == UNSIGNED_T) return mUnsigned;
		set_unsigned() = const_cast<const serial_value*>(this)->get_unsigned();
		return mUnsigned;
	}

	serial_value::signed_t& serial_value::get_signed() {
		if(mType == SIGNED_T) return mSigned;
		set_signed() = const_cast<const serial_value*>(this)->get_signed();
		return mSigned;
	}

	serial_value::float_t& serial_value::get_float() {
		if(mType == FLOAT_T) return mFloat;
		set_float() = const_cast<const serial_value*>(this)->get_float();
		return mFloat;
	}

	serial_value::pointer_t& serial_value::get_pointer() {
		if(mType == POINTER_T) return mPointer;
		set_pointer() = const_cast<const serial_value*>(this)->get_pointer();
		return mPointer;
	}

	serial_value::string_t& serial_value::get_string() {
		if(mType == STRING_T) return *mString;
		const string_t tmp = const_cast<const serial_value*>(this)->get_string();
		set_string() = tmp;
		return *mString;
	}

	serial_value::array_t& serial_value::get_array() {
		if(mType == ARRAY_T) return *mArray;
		const array_t tmp = const_cast<const serial_value*>(this)->get_array();
		set_array() = tmp;
		return *mArray;
	}

	serial_value::object_t& serial_value::get_object() {
		if(mType == OBJECT_T) return *mObject;
		const object_t tmp = const_cast<const serial_value*>(this)->get_object();
		set_object() = tmp;
		return *mObject;
	}

	serial_value::char_t serial_value::get_char() const {
		switch(mType) {
		case CHAR_T:
			return mChar;
			break;
		case BOOL_T:
			return mBool ? '1' : '0';
			break;
		case UNSIGNED_T:
			if(mUnsigned >= 0 && mUnsigned <= 9) return static_cast<char_t>('0' + mUnsigned);
			break;
		case SIGNED_T:
			if(mSigned >= 0 && mSigned <= 9) return static_cast<char_t>('0' + mSigned);
			break;
		case FLOAT_T:
			{
				const int64_t tmp = static_cast<int64_t>(mFloat);
				if(static_cast<float_t>(tmp) == mFloat && tmp >= 0 && tmp <= 9)
					return static_cast<char_t>('0' + tmp);
			}
			break;
		case STRING_T:
			if(mString->size() == 1) mString->front();
			break;
		}
		throw std::runtime_error("as::serial_value::get_char : Type is not convertable to char");
	}

	serial_value::bool_t serial_value::get_bool() const {
		//! \todo Implement
		return mBool;
	}

	serial_value::unsigned_t serial_value::get_unsigned() const {
		//! \todo Implement
		return mUnsigned;
	}

	serial_value::signed_t serial_value::get_signed() const {
		//! \todo Implement
		return mSigned;
	}

	serial_value::float_t serial_value::get_float() const {
		//! \todo Implement
		return mFloat;
	}

	serial_value::pointer_t serial_value::get_pointer() const {
		//! \todo Implement
		return mPointer;
	}

	const serial_value::string_t& serial_value::get_string() const {
		//! \todo Implement
		return *mString;
	}

	const serial_value::array_t& serial_value::get_array() const {
		//! \todo Implement
		return *mArray;
	}

	const serial_value::object_t& serial_value::get_object() const {
		//! \todo Implement
		return *mObject;
	}

	bool serial_value::is_null() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_char() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_bool() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_unsigned() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_signed() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_float() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_pointer() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_string() const {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_array() const {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_object() const {
		//! \todo Implement
		return false;
	}

}<commit_msg>Implemented get_bool<commit_after>// Copyright 2017 Adam Smith
//
// 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 "as/serial_value/serial_value.hpp"

namespace as {

	// serial_value

	serial_value::serial_value() throw() :
		mType(NULL_T)
	{}

	serial_value::serial_value(type aType) throw() :
		mType(aType)
	{
		switch(mType) {
		case STRING_T:
			mString = new string_t();
			break;
		case ARRAY_T:
			mArray = new array_t();
			break;
		case OBJECT_T:
			mObject = new object_t();
			break;
		}
	}

	serial_value::serial_value(bool_t aValue) throw() :
		mType(BOOL_T),
		mBool(aValue)
	{}

	serial_value::serial_value(uint8_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint16_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint32_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(uint64_t aValue) throw() :
		mType(UNSIGNED_T),
		mUnsigned(aValue)
	{}

	serial_value::serial_value(int8_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int16_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int32_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(int64_t aValue) throw() :
		mType(SIGNED_T),
		mSigned(aValue)
	{}

	serial_value::serial_value(float aValue) throw() :
		mType(FLOAT_T),
		mFloat(aValue)
	{}

	serial_value::serial_value(double aValue) throw() :
		mType(FLOAT_T),
		mFloat(aValue)
	{}

	serial_value::serial_value(const string_t& aValue) throw() :
		mType(STRING_T),
		mString(new string_t(aValue))
	{}

	serial_value::serial_value(const char* aValue) throw() :
		mType(STRING_T),
		mString(new string_t(aValue))
	{}

	serial_value::~serial_value() throw() {
		set_null();
	}

	void serial_value::set_null() throw() {
		switch(mType) {
		case NULL_T :
			break;
		case CHAR_T:
			break;
		case BOOL_T:
			break;
		case UNSIGNED_T:
			break;
		case SIGNED_T:
			break;
		case FLOAT_T:
			break;
		case POINTER_T:
			break;
		case STRING_T:
			delete mString;
			break;
		case ARRAY_T:
			delete mArray;
			break;
		case OBJECT_T:
			delete mObject;
			break;
		}
		mType = NULL_T;
	}

	serial_value::char_t& serial_value::set_char() throw() {
		if(mType != CHAR_T) {
			set_null();
			mType = CHAR_T;
		}
		return mChar;
	}

	serial_value::bool_t& serial_value::set_bool() throw() {
		if(mType != BOOL_T) {
			set_null();
			mType = BOOL_T;
		}
		return mBool;
	}

	serial_value::unsigned_t& serial_value::set_unsigned() throw() {
		if(mType != UNSIGNED_T) {
			set_null();
			mType = UNSIGNED_T;
		}
		return mUnsigned;
	}

	serial_value::signed_t& serial_value::set_signed() throw() {
		if(mType != SIGNED_T) {
			set_null();
			mType = SIGNED_T;
		}
		return mSigned;
	}

	serial_value::float_t& serial_value::set_float() throw() {
		if(mType != FLOAT_T) {
			set_null();
			mType = FLOAT_T;
		}
		return mFloat;
	}

	serial_value::pointer_t& serial_value::set_pointer() throw() {
		if(mType != POINTER_T) {
			set_null();
			mType = POINTER_T;
		}
		return mPointer;
	}

	serial_value::string_t& serial_value::set_string() throw() {
		if(mType != STRING_T) {
			set_null();
			mType = STRING_T;
			mString = new string_t();
		}else {
			mString->clear();
		}

	return			*mString;
	}

	serial_value::array_t& serial_value::set_array() throw() {
		if(mType != ARRAY_T) {
			set_null();
			mType = ARRAY_T;
			mArray = new array_t();
		}else {
			mArray->clear();
		}
		return *mArray;
	}

	serial_value::object_t& serial_value::set_object() throw() {
		if(mType != OBJECT_T) {
			set_null();
			mType = OBJECT_T;
			mObject = new object_t();
		}else {
			mObject->clear();
		}
		return *mObject;
	}

	serial_value::char_t& serial_value::get_char() {
		if(mType == CHAR_T) return mChar;
		set_char() = const_cast<const serial_value*>(this)->get_char();
		return mChar;
	}

	serial_value::bool_t& serial_value::get_bool() {
		if(mType == BOOL_T) return mBool;
		set_bool() = const_cast<const serial_value*>(this)->get_bool();
		return mBool;
	}

	serial_value::unsigned_t& serial_value::get_unsigned() {
		if(mType == UNSIGNED_T) return mUnsigned;
		set_unsigned() = const_cast<const serial_value*>(this)->get_unsigned();
		return mUnsigned;
	}

	serial_value::signed_t& serial_value::get_signed() {
		if(mType == SIGNED_T) return mSigned;
		set_signed() = const_cast<const serial_value*>(this)->get_signed();
		return mSigned;
	}

	serial_value::float_t& serial_value::get_float() {
		if(mType == FLOAT_T) return mFloat;
		set_float() = const_cast<const serial_value*>(this)->get_float();
		return mFloat;
	}

	serial_value::pointer_t& serial_value::get_pointer() {
		if(mType == POINTER_T) return mPointer;
		set_pointer() = const_cast<const serial_value*>(this)->get_pointer();
		return mPointer;
	}

	serial_value::string_t& serial_value::get_string() {
		if(mType == STRING_T) return *mString;
		const string_t tmp = const_cast<const serial_value*>(this)->get_string();
		set_string() = tmp;
		return *mString;
	}

	serial_value::array_t& serial_value::get_array() {
		if(mType == ARRAY_T) return *mArray;
		const array_t tmp = const_cast<const serial_value*>(this)->get_array();
		set_array() = tmp;
		return *mArray;
	}

	serial_value::object_t& serial_value::get_object() {
		if(mType == OBJECT_T) return *mObject;
		const object_t tmp = const_cast<const serial_value*>(this)->get_object();
		set_object() = tmp;
		return *mObject;
	}

	serial_value::char_t serial_value::get_char() const {
		switch(mType) {
		case CHAR_T:
			return mChar;
			break;
		case BOOL_T:
			return mBool ? '1' : '0';
			break;
		case UNSIGNED_T:
			if(mUnsigned >= 0 && mUnsigned <= 9) return static_cast<char_t>('0' + mUnsigned);
			break;
		case SIGNED_T:
			if(mSigned >= 0 && mSigned <= 9) return static_cast<char_t>('0' + mSigned);
			break;
		case FLOAT_T:
			{
				const int64_t tmp = static_cast<int64_t>(mFloat);
				if(static_cast<float_t>(tmp) == mFloat && tmp >= 0 && tmp <= 9)
					return static_cast<char_t>('0' + tmp);
			}
			break;
		case STRING_T:
			if(mString->size() == 1) mString->front();
			break;
		}
		throw std::runtime_error("as::serial_value::get_char : Type is not convertable to char");
	}

	serial_value::bool_t serial_value::get_bool() const {
		switch(mType) {
		case CHAR_T:
			if(mChar == '1' || mChar == 'y' || mChar == 'Y') return true;
			else if(mChar == '0' || mChar == 'n' || mChar == 'N') return false;
			break;
		case BOOL_T:
			return mBool;
			break;
		case UNSIGNED_T:
			return mSigned > 0;
			break;
		case SIGNED_T:
			return mUnsigned > 0;
			break;
		case FLOAT_T:
			return mFloat >= 1.0;
			break;
		case POINTER_T:
			return mPointer != nullptr;
			break;
		case STRING_T:
			if(
				*mString == "1" || *mString == "y" || *mString == "Y" || *mString == "true" ||
				*mString == "TRUE" || *mString == "True" || *mString == "yes" || *mString == "YES" ||
				*mString == "Yes"
			) return true;
			else if(
				*mString == "0" || *mString == "n" || *mString == "N" || *mString == "false" ||
				*mString == "FALSE" || *mString == "False" || *mString == "no" || *mString == "NO" ||
				*mString == "N0"
			) return true;
			break;
		}
		throw std::runtime_error("as::serial_value::get_bool : Type is not convertable to bool");
	}

	serial_value::unsigned_t serial_value::get_unsigned() const {
		//! \todo Implement
		return mUnsigned;
	}

	serial_value::signed_t serial_value::get_signed() const {
		//! \todo Implement
		return mSigned;
	}

	serial_value::float_t serial_value::get_float() const {
		//! \todo Implement
		return mFloat;
	}

	serial_value::pointer_t serial_value::get_pointer() const {
		//! \todo Implement
		return mPointer;
	}

	const serial_value::string_t& serial_value::get_string() const {
		//! \todo Implement
		return *mString;
	}

	const serial_value::array_t& serial_value::get_array() const {
		//! \todo Implement
		return *mArray;
	}

	const serial_value::object_t& serial_value::get_object() const {
		//! \todo Implement
		return *mObject;
	}

	bool serial_value::is_null() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_char() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_bool() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_unsigned() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_signed() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_float() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_pointer() const throw() {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_string() const {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_array() const {
		//! \todo Implement
		return false;
	}

	bool serial_value::is_object() const {
		//! \todo Implement
		return false;
	}

}<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2007 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// logDetail.cpp : Plugin module for logging server events to stdout
//

#include <iostream>
#include <sstream>
#include "bzfsAPI.h"

BZ_GET_PLUGIN_VERSION

enum action { join , auth , part };

class LogDetail : public bz_EventHandler
{
public:
  LogDetail();
  virtual ~LogDetail();
  virtual void process( bz_EventData *eventData );
private:
  std::string displayPlayerPrivs( int playerID );
  std::string displayCallsign( bzApiString callsign );
  std::string displayCallsign( int playerID );
  std::string displayBZid( int playerID );
  std::string displayTeam( bz_eTeamType team );
  virtual void listPlayers( action act, bz_PlayerJoinPartEventData *data );
};

LogDetail logDetailHandler;

BZF_PLUGIN_CALL int bz_Load ( const char* /*commandLine*/ )
{
  bz_registerEvent(bz_eSlashCommandEvent, &logDetailHandler);
  bz_registerEvent(bz_eChatMessageEvent, &logDetailHandler);
  bz_registerEvent(bz_eServerMsgEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerJoinEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerPartEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerAuthEvent, &logDetailHandler);
  bz_registerEvent(bz_eMessageFilteredEvent, &logDetailHandler);
  bz_debugMessage(4, "logDetail plugin loaded");
  return 0;
}

BZF_PLUGIN_CALL int bz_Unload ( void )
{
  bz_removeEvent(bz_eSlashCommandEvent, &logDetailHandler);
  bz_removeEvent(bz_eChatMessageEvent, &logDetailHandler);
  bz_removeEvent(bz_eServerMsgEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerJoinEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerPartEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerAuthEvent, &logDetailHandler);
  bz_removeEvent(bz_eMessageFilteredEvent, &logDetailHandler);
  bz_debugMessage(4, "logDetail plugin unloaded");
  return 0;
}

LogDetail::LogDetail()
{
  bz_debugMessage(0, "SERVER-STATUS Running");
  listPlayers( join , NULL );
}

LogDetail::~LogDetail()
{
  listPlayers( part , NULL );
  bz_debugMessage(0, "SERVER-STATUS Stopped");
}

void LogDetail::process( bz_EventData *eventData )
{
  bz_ChatEventData *chatData = (bz_ChatEventData *) eventData;
  bz_ServerMsgEventData *serverMsgData = (bz_ServerMsgEventData *) eventData;
  bz_SlashCommandEventData *cmdData = (bz_SlashCommandEventData *) eventData;
  bz_PlayerJoinPartEventData *joinPartData = (bz_PlayerJoinPartEventData *) eventData;
  bz_PlayerAuthEventData *authData = (bz_PlayerAuthEventData *) eventData;
  bz_MessageFilteredEventData *filteredData = (bz_MessageFilteredEventData *) eventData;
  char temp[9] = {0};

  if (eventData) {
    switch (eventData->eventType) {
      case bz_eSlashCommandEvent:
	// Slash commands are case insensitive
	// Tokenize the stream and check the first word
	// /report -> MSG-REPORT
	// anything -> MSG-COMMAND

	strncpy(temp, cmdData->message.c_str(), 8);

	if (strcasecmp( temp, "/REPORT ") == 0) {
	  bz_debugMessagef(0, "MSG-REPORT %s %s",
			   displayCallsign( cmdData->from ).c_str(),
			   cmdData->message.c_str()+8);
	} else {
	  bz_debugMessagef(0, "MSG-COMMAND %s %s",
			   displayCallsign( cmdData->from ).c_str(),
			   cmdData->message.c_str()+1);
	}
	break;
      case bz_eChatMessageEvent:
	if ((chatData->to == BZ_ALLUSERS) && (chatData->team == eNoTeam)) {
	  bz_debugMessagef(0, "MSG-BROADCAST %s %s",
			   displayCallsign( chatData->from ).c_str(),
			   chatData->message.c_str());
	} else if (chatData->to == BZ_NULLUSER) {
	  if (chatData->team == eAdministrators) {
	    bz_debugMessagef(0, "MSG-ADMIN %s %s",
			     displayCallsign( chatData->from ).c_str(),
			     chatData->message.c_str());
	  } else {
	    bz_debugMessagef(0, "MSG-TEAM %s %s %s",
			     displayCallsign( chatData->from ).c_str(),
			     displayTeam( chatData->team ).c_str(),
			     chatData->message.c_str());
	  }
	} else {
	  bz_debugMessagef(0, "MSG-DIRECT %s %s %s",
			   displayCallsign( chatData->from ).c_str(),
			   displayCallsign( chatData->to ).c_str(),
			   chatData->message.c_str());
	}
	break;
      case bz_eMessageFilteredEvent:
	bz_debugMessagef(0, "MSG-FILTERED %s %s",
			 displayCallsign( filteredData->player ).c_str(),
			 filteredData->filteredMessage.c_str());
	break;
      case bz_eServerMsgEvent:
	if ((serverMsgData->to == BZ_ALLUSERS) && (serverMsgData->team == eNoTeam)) {
	  bz_debugMessagef(0, "MSG-BROADCAST 6:SERVER %s",
			   serverMsgData->message.c_str());
	} else if (serverMsgData->to == BZ_NULLUSER) {
	  if (serverMsgData->team == eAdministrators) {
	    bz_debugMessagef(0, "MSG-ADMIN 6:SERVER %s",
			     serverMsgData->message.c_str());
	  } else {
	    bz_debugMessagef(0, "MSG-TEAM 6:SERVER %s %s",
			     displayTeam( serverMsgData->team ).c_str(),
			     chatData->message.c_str());
	  }
	} else {
	  bz_debugMessagef(0, "MSG-DIRECT 6:SERVER %s %s",
			   displayCallsign( serverMsgData->to ).c_str(),
			   serverMsgData->message.c_str());
	}
	break;
      case bz_ePlayerJoinEvent:
	{
	  bz_PlayerRecord *player = bz_getPlayerByIndex( joinPartData->playerID );
	  if (player) {
	    bz_debugMessagef(0, "PLAYER-JOIN %s #%d%s %s %s",
			     displayCallsign( player->callsign ).c_str(),
			     joinPartData->playerID,
			     displayBZid( joinPartData->playerID ).c_str(),
			     displayTeam( joinPartData->team ).c_str(),
			     displayPlayerPrivs( joinPartData->playerID ).c_str());
	    listPlayers( join, joinPartData);
	    bz_freePlayerRecord( player );
	  }
	}
	break;
      case bz_ePlayerPartEvent:
	bz_debugMessagef(0, "PLAYER-PART %s #%d%s %s",
			 displayCallsign( joinPartData->playerID ).c_str(),
			 joinPartData->playerID,
			 displayBZid( joinPartData->playerID ).c_str(),
			 joinPartData->reason.c_str());
	listPlayers( part, joinPartData);
	break;
      case bz_ePlayerAuthEvent:
	bz_debugMessagef(0, "PLAYER-AUTH %s %s",
			 displayCallsign( authData->playerID ).c_str(),
			 displayPlayerPrivs( authData->playerID ).c_str()),
	listPlayers( join, joinPartData);
	break;
      default :
	break;
    }
  }
}

std::string LogDetail::displayBZid( int playerID )
{
  std::ostringstream bzid;

  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    if (player->globalUser)
      bzid << " BZid:" << player->bzID.c_str();
    bz_freePlayerRecord( player );
  }

  return bzid.str();
}

std::string LogDetail::displayPlayerPrivs( int playerID )
{
  std::ostringstream playerPrivs;

  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    playerPrivs << " IP:" << player->ipAddress.c_str();
    if (player->verified ) playerPrivs << " VERIFIED";
    if (player->globalUser ) playerPrivs << " GLOBALUSER";
    if (player->admin ) playerPrivs << " ADMIN";
    if (player->op ) playerPrivs << " OPERATOR";
    bz_freePlayerRecord( player );
  } else {
    playerPrivs << " IP:0.0.0.0";
  }

  return playerPrivs.str();
}

std::string LogDetail::displayCallsign( bzApiString callsign )
{
  std::ostringstream result;

  result << strlen( callsign.c_str() ) << ":" << callsign.c_str();

  return result.str();
}

std::string LogDetail::displayCallsign( int playerID )
{
  std::ostringstream callsign;
  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    callsign << strlen( player->callsign.c_str() ) << ":";
    callsign << player->callsign.c_str();
    bz_freePlayerRecord( player );
  } else {
    callsign << "7:UNKNOWN";
  }
  return callsign.str();
}

std::string LogDetail::displayTeam( bz_eTeamType team )
{
  // Display the player team
  switch ( team ) {
    case eRogueTeam:
      return std::string("ROGUE");
    case eRedTeam:
      return std::string("RED");
    case eGreenTeam:
      return std::string("GREEN");
    case eBlueTeam:
      return std::string("BLUE");
    case ePurpleTeam:
      return std::string("PURPLE");
    case eRabbitTeam:
      return std::string("RABBIT");
    case eHunterTeam:
      return std::string("HUNTER");
    case eObservers:
      return std::string("OBSERVER");
    default :
      return std::string("NOTEAM");
  }
}

void LogDetail::listPlayers( action act , bz_PlayerJoinPartEventData *data )
{
  bzAPIIntList *playerList = bz_newIntList();
  bz_PlayerRecord *player;
  std::ostringstream msg;
  char playerStatus;
  int numPlayers;

  bz_getPlayerIndexList( playerList );

  bz_debugMessage( 4 , "Players:" );
  //
  // Count number of players
  //
  numPlayers = 0;
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID))))
	numPlayers++;
      bz_freePlayerRecord( player );
    }
  }

  //
  // Display number of players, callsign, and email string in the following format:
  //
  // PLAYERS (nn) [G]cc:callsign(ee:emailstring)
  // nn - number of players
  // G	- global auth identifier (+|-| |@)
  // cc - count of characters in player callsign
  // callsign - player callsign
  // ee - count of characters in email string
  // emailstring - player email string
  //
  // eg.
  // PLAYERS (2) [@]7:Thumper(16:me@somewhere.net) [ ]3:xxx()
  //
  msg.str("");
  msg << "PLAYERS (" << numPlayers << ") ";
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID)))) {
	playerStatus = ' ';
	if (player->globalUser) playerStatus = '+';
	if (player->verified) playerStatus = '+';
	if (player->admin && !bz_hasPerm(player->playerID, bz_perm_hideAdmin)) playerStatus = '@';
	msg << "[" << playerStatus << "]";
	msg << player->callsign.size() << ':';
	msg << player->callsign.c_str();
	msg << "(";
	if (player->email != "")
	  msg << player->email.size() << ":" << player->email.c_str();
	msg << ") ";
      }
      bz_freePlayerRecord( player );
    }
  }
  bz_debugMessage(0, msg.str().c_str());

  bz_deleteIntList(playerList);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>Remove extra space before IP: token<commit_after>/* bzflag
 * Copyright (c) 1993 - 2007 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// logDetail.cpp : Plugin module for logging server events to stdout
//

#include <iostream>
#include <sstream>
#include "bzfsAPI.h"

BZ_GET_PLUGIN_VERSION

enum action { join , auth , part };

class LogDetail : public bz_EventHandler
{
public:
  LogDetail();
  virtual ~LogDetail();
  virtual void process( bz_EventData *eventData );
private:
  std::string displayPlayerPrivs( int playerID );
  std::string displayCallsign( bzApiString callsign );
  std::string displayCallsign( int playerID );
  std::string displayBZid( int playerID );
  std::string displayTeam( bz_eTeamType team );
  virtual void listPlayers( action act, bz_PlayerJoinPartEventData *data );
};

LogDetail logDetailHandler;

BZF_PLUGIN_CALL int bz_Load ( const char* /*commandLine*/ )
{
  bz_registerEvent(bz_eSlashCommandEvent, &logDetailHandler);
  bz_registerEvent(bz_eChatMessageEvent, &logDetailHandler);
  bz_registerEvent(bz_eServerMsgEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerJoinEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerPartEvent, &logDetailHandler);
  bz_registerEvent(bz_ePlayerAuthEvent, &logDetailHandler);
  bz_registerEvent(bz_eMessageFilteredEvent, &logDetailHandler);
  bz_debugMessage(4, "logDetail plugin loaded");
  return 0;
}

BZF_PLUGIN_CALL int bz_Unload ( void )
{
  bz_removeEvent(bz_eSlashCommandEvent, &logDetailHandler);
  bz_removeEvent(bz_eChatMessageEvent, &logDetailHandler);
  bz_removeEvent(bz_eServerMsgEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerJoinEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerPartEvent, &logDetailHandler);
  bz_removeEvent(bz_ePlayerAuthEvent, &logDetailHandler);
  bz_removeEvent(bz_eMessageFilteredEvent, &logDetailHandler);
  bz_debugMessage(4, "logDetail plugin unloaded");
  return 0;
}

LogDetail::LogDetail()
{
  bz_debugMessage(0, "SERVER-STATUS Running");
  listPlayers( join , NULL );
}

LogDetail::~LogDetail()
{
  listPlayers( part , NULL );
  bz_debugMessage(0, "SERVER-STATUS Stopped");
}

void LogDetail::process( bz_EventData *eventData )
{
  bz_ChatEventData *chatData = (bz_ChatEventData *) eventData;
  bz_ServerMsgEventData *serverMsgData = (bz_ServerMsgEventData *) eventData;
  bz_SlashCommandEventData *cmdData = (bz_SlashCommandEventData *) eventData;
  bz_PlayerJoinPartEventData *joinPartData = (bz_PlayerJoinPartEventData *) eventData;
  bz_PlayerAuthEventData *authData = (bz_PlayerAuthEventData *) eventData;
  bz_MessageFilteredEventData *filteredData = (bz_MessageFilteredEventData *) eventData;
  char temp[9] = {0};

  if (eventData) {
    switch (eventData->eventType) {
      case bz_eSlashCommandEvent:
	// Slash commands are case insensitive
	// Tokenize the stream and check the first word
	// /report -> MSG-REPORT
	// anything -> MSG-COMMAND

	strncpy(temp, cmdData->message.c_str(), 8);

	if (strcasecmp( temp, "/REPORT ") == 0) {
	  bz_debugMessagef(0, "MSG-REPORT %s %s",
			   displayCallsign( cmdData->from ).c_str(),
			   cmdData->message.c_str()+8);
	} else {
	  bz_debugMessagef(0, "MSG-COMMAND %s %s",
			   displayCallsign( cmdData->from ).c_str(),
			   cmdData->message.c_str()+1);
	}
	break;
      case bz_eChatMessageEvent:
	if ((chatData->to == BZ_ALLUSERS) && (chatData->team == eNoTeam)) {
	  bz_debugMessagef(0, "MSG-BROADCAST %s %s",
			   displayCallsign( chatData->from ).c_str(),
			   chatData->message.c_str());
	} else if (chatData->to == BZ_NULLUSER) {
	  if (chatData->team == eAdministrators) {
	    bz_debugMessagef(0, "MSG-ADMIN %s %s",
			     displayCallsign( chatData->from ).c_str(),
			     chatData->message.c_str());
	  } else {
	    bz_debugMessagef(0, "MSG-TEAM %s %s %s",
			     displayCallsign( chatData->from ).c_str(),
			     displayTeam( chatData->team ).c_str(),
			     chatData->message.c_str());
	  }
	} else {
	  bz_debugMessagef(0, "MSG-DIRECT %s %s %s",
			   displayCallsign( chatData->from ).c_str(),
			   displayCallsign( chatData->to ).c_str(),
			   chatData->message.c_str());
	}
	break;
      case bz_eMessageFilteredEvent:
	bz_debugMessagef(0, "MSG-FILTERED %s %s",
			 displayCallsign( filteredData->player ).c_str(),
			 filteredData->filteredMessage.c_str());
	break;
      case bz_eServerMsgEvent:
	if ((serverMsgData->to == BZ_ALLUSERS) && (serverMsgData->team == eNoTeam)) {
	  bz_debugMessagef(0, "MSG-BROADCAST 6:SERVER %s",
			   serverMsgData->message.c_str());
	} else if (serverMsgData->to == BZ_NULLUSER) {
	  if (serverMsgData->team == eAdministrators) {
	    bz_debugMessagef(0, "MSG-ADMIN 6:SERVER %s",
			     serverMsgData->message.c_str());
	  } else {
	    bz_debugMessagef(0, "MSG-TEAM 6:SERVER %s %s",
			     displayTeam( serverMsgData->team ).c_str(),
			     chatData->message.c_str());
	  }
	} else {
	  bz_debugMessagef(0, "MSG-DIRECT 6:SERVER %s %s",
			   displayCallsign( serverMsgData->to ).c_str(),
			   serverMsgData->message.c_str());
	}
	break;
      case bz_ePlayerJoinEvent:
	{
	  bz_PlayerRecord *player = bz_getPlayerByIndex( joinPartData->playerID );
	  if (player) {
	    bz_debugMessagef(0, "PLAYER-JOIN %s #%d%s %s %s",
			     displayCallsign( player->callsign ).c_str(),
			     joinPartData->playerID,
			     displayBZid( joinPartData->playerID ).c_str(),
			     displayTeam( joinPartData->team ).c_str(),
			     displayPlayerPrivs( joinPartData->playerID ).c_str());
	    listPlayers( join, joinPartData);
	    bz_freePlayerRecord( player );
	  }
	}
	break;
      case bz_ePlayerPartEvent:
	bz_debugMessagef(0, "PLAYER-PART %s #%d%s %s",
			 displayCallsign( joinPartData->playerID ).c_str(),
			 joinPartData->playerID,
			 displayBZid( joinPartData->playerID ).c_str(),
			 joinPartData->reason.c_str());
	listPlayers( part, joinPartData);
	break;
      case bz_ePlayerAuthEvent:
	bz_debugMessagef(0, "PLAYER-AUTH %s %s",
			 displayCallsign( authData->playerID ).c_str(),
			 displayPlayerPrivs( authData->playerID ).c_str()),
	listPlayers( join, joinPartData);
	break;
      default :
	break;
    }
  }
}

std::string LogDetail::displayBZid( int playerID )
{
  std::ostringstream bzid;

  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    if (player->globalUser)
      bzid << " BZid:" << player->bzID.c_str();
    bz_freePlayerRecord( player );
  }

  return bzid.str();
}

std::string LogDetail::displayPlayerPrivs( int playerID )
{
  std::ostringstream playerPrivs;

  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    playerPrivs << "IP:" << player->ipAddress.c_str();
    if (player->verified ) playerPrivs << " VERIFIED";
    if (player->globalUser ) playerPrivs << " GLOBALUSER";
    if (player->admin ) playerPrivs << " ADMIN";
    if (player->op ) playerPrivs << " OPERATOR";
    bz_freePlayerRecord( player );
  } else {
    playerPrivs << "IP:0.0.0.0";
  }

  return playerPrivs.str();
}

std::string LogDetail::displayCallsign( bzApiString callsign )
{
  std::ostringstream result;

  result << strlen( callsign.c_str() ) << ":" << callsign.c_str();

  return result.str();
}

std::string LogDetail::displayCallsign( int playerID )
{
  std::ostringstream callsign;
  bz_PlayerRecord *player = bz_getPlayerByIndex( playerID );
  if (player) {
    callsign << strlen( player->callsign.c_str() ) << ":";
    callsign << player->callsign.c_str();
    bz_freePlayerRecord( player );
  } else {
    callsign << "7:UNKNOWN";
  }
  return callsign.str();
}

std::string LogDetail::displayTeam( bz_eTeamType team )
{
  // Display the player team
  switch ( team ) {
    case eRogueTeam:
      return std::string("ROGUE");
    case eRedTeam:
      return std::string("RED");
    case eGreenTeam:
      return std::string("GREEN");
    case eBlueTeam:
      return std::string("BLUE");
    case ePurpleTeam:
      return std::string("PURPLE");
    case eRabbitTeam:
      return std::string("RABBIT");
    case eHunterTeam:
      return std::string("HUNTER");
    case eObservers:
      return std::string("OBSERVER");
    default :
      return std::string("NOTEAM");
  }
}

void LogDetail::listPlayers( action act , bz_PlayerJoinPartEventData *data )
{
  bzAPIIntList *playerList = bz_newIntList();
  bz_PlayerRecord *player;
  std::ostringstream msg;
  char playerStatus;
  int numPlayers;

  bz_getPlayerIndexList( playerList );

  bz_debugMessage( 4 , "Players:" );
  //
  // Count number of players
  //
  numPlayers = 0;
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID))))
	numPlayers++;
      bz_freePlayerRecord( player );
    }
  }

  //
  // Display number of players, callsign, and email string in the following format:
  //
  // PLAYERS (nn) [G]cc:callsign(ee:emailstring)
  // nn - number of players
  // G	- global auth identifier (+|-| |@)
  // cc - count of characters in player callsign
  // callsign - player callsign
  // ee - count of characters in email string
  // emailstring - player email string
  //
  // eg.
  // PLAYERS (2) [@]7:Thumper(16:me@somewhere.net) [ ]3:xxx()
  //
  msg.str("");
  msg << "PLAYERS (" << numPlayers << ") ";
  for ( unsigned int i = 0; i < playerList->size(); i++ ) {
    player = bz_getPlayerByIndex( playerList->get(i));
    if (player) {
      if ((player->callsign != "") && (act == join || act == auth || (data && (player->playerID != data->playerID)))) {
	playerStatus = ' ';
	if (player->globalUser) playerStatus = '+';
	if (player->verified) playerStatus = '+';
	if (player->admin && !bz_hasPerm(player->playerID, bz_perm_hideAdmin)) playerStatus = '@';
	msg << "[" << playerStatus << "]";
	msg << player->callsign.size() << ':';
	msg << player->callsign.c_str();
	msg << "(";
	if (player->email != "")
	  msg << player->email.size() << ":" << player->email.c_str();
	msg << ") ";
      }
      bz_freePlayerRecord( player );
    }
  }
  bz_debugMessage(0, msg.str().c_str());

  bz_deleteIntList(playerList);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>