<commit_before>/*
//  character.cpp
//
//  Author:     Sophia Lee
//  Created:    2017. 03. 19. 12:28
//  Copyright (c) 2017 Sophia Lee. All rights reserved.
//
//
*/
#include <seshat/character.h>

#include <seshat/codepoint.h>
#include <seshat/unicode/normalize.h>
#include <seshat/unicode/segmentation.h>

#include <sstream>
#include <utility>

namespace seshat {

Character::Character(char a_char)
    : _code_points(decltype(_code_points)())
{
    CodePoint cp = CodePoint(static_cast<uint32_t>(a_char));
    _code_points.append(cp);
}

Character::Character(const CodePoint& code_point)
    : _code_points(decltype(_code_points)())
{
    // if (gc(code_point.code()) == Gc::Cs) {
    // For performance, Surrogate code points compared directly.
    if (0xD800 <= code_point && code_point <= 0xDFFF) {
        throw SurrogateIncluded();
    }
    _code_points.append(code_point);
}

Character::Character(const CodePointSequence &sequence)
    : _code_points(decltype(_code_points)())
{
    for (auto cp: sequence) {
        if (0xD800 <= cp && cp <= 0xDFFF) {
            throw SurrogateIncluded();
        }
    }
    // Check if not a single grapheme cluster (zero or greater than one)
    if (unicode::grapheme_bound(sequence.begin(), sequence.end()) + 1 !=
        sequence.end()) {
    // if ((unicode::grapheme_bound(sequence) + 1) != sequence.length()) {
        throw NotASingleCharacter();
    }
    for (auto cp: sequence) {
        _code_points.append(cp);
    }
}

Character::Character(const Character& origin)
    : _code_points(origin._code_points)
{}

Character::Character(Character&& origin)
    : _code_points(std::move(origin._code_points))
{}

Character::~Character()
{
}

size_t Character::size() const
{
    return _code_points.length();
}

const CodePointSequence& Character::sequence() const
{
    return _code_points;
}

std::string Character::to_utf8() const
{
    std::stringstream stream;

    // For all code points
    for (auto&& cp: _code_points) {
        if (0x0000 <= cp && cp <= 0x007F) {
            stream << static_cast<char>(cp);
        } else if (0x0080 <= cp && cp <= 0x07FF) {
            stream << static_cast<char>(0xC0 | (cp >> 6));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        } else if (0x0800 <= cp && cp <= 0xFFFF) {
            stream << static_cast<char>(0xE0 | (cp >> 12));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 6)));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        } else if (0x10000 <= cp && cp <= 0x10FFFF) {
            stream << static_cast<char>(0xF0 | (cp >> 18));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 12)));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 6)));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        }
    }

    return stream.str();
}

Character& Character::operator=(const Character& origin)
{
    _code_points = origin._code_points;
    return *this;
}

Character& Character::operator=(Character&& origin)
{
    _code_points = std::move(origin._code_points);
    return *this;
}

bool Character::operator==(const Character& other) const
{
    return (unicode::nfd(_code_points) == unicode::nfd(other._code_points));
}

bool Character::operator!=(const Character& other) const
{
    return *this != other;
}

} // namespace seshat<commit_msg>Comparison error fixed.<commit_after>/*
//  character.cpp
//
//  Author:     Sophia Lee
//  Created:    2017. 03. 19. 12:28
//  Copyright (c) 2017 Sophia Lee. All rights reserved.
//
//
*/
#include <seshat/character.h>

#include <seshat/codepoint.h>
#include <seshat/unicode/normalize.h>
#include <seshat/unicode/segmentation.h>

#include <sstream>
#include <utility>

namespace seshat {

Character::Character(char a_char)
    : _code_points(decltype(_code_points)())
{
    CodePoint cp = CodePoint(static_cast<uint32_t>(a_char));
    _code_points.append(cp);
}

Character::Character(const CodePoint& code_point)
    : _code_points(decltype(_code_points)())
{
    // if (gc(code_point.code()) == Gc::Cs) {
    // For performance, Surrogate code points compared directly.
    if (0xD800 <= code_point && code_point <= 0xDFFF) {
        throw SurrogateIncluded();
    }
    _code_points.append(code_point);
}

Character::Character(const CodePointSequence &sequence)
    : _code_points(decltype(_code_points)())
{
    for (auto cp: sequence) {
        if (0xD800 <= cp && cp <= 0xDFFF) {
            throw SurrogateIncluded();
        }
    }
    // Check if not a single grapheme cluster (zero or greater than one)
    if (unicode::grapheme_bound(sequence.begin(), sequence.end()) + 1 !=
        sequence.end()) {
    // if ((unicode::grapheme_bound(sequence) + 1) != sequence.length()) {
        throw NotASingleCharacter();
    }
    for (auto cp: sequence) {
        _code_points.append(cp);
    }
}

Character::Character(const Character& origin)
    : _code_points(origin._code_points)
{}

Character::Character(Character&& origin)
    : _code_points(std::move(origin._code_points))
{}

Character::~Character()
{
}

size_t Character::size() const
{
    return _code_points.length();
}

const CodePointSequence& Character::sequence() const
{
    return _code_points;
}

std::string Character::to_utf8() const
{
    std::stringstream stream;

    // For all code points
    for (auto&& cp: _code_points) {
        if (0x0000 <= cp && cp <= 0x007F) {
            stream << static_cast<char>(cp);
        } else if (0x0080 <= cp && cp <= 0x07FF) {
            stream << static_cast<char>(0xC0 | (cp >> 6));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        } else if (0x0800 <= cp && cp <= 0xFFFF) {
            stream << static_cast<char>(0xE0 | (cp >> 12));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 6)));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        } else if (0x10000 <= cp && cp <= 0x10FFFF) {
            stream << static_cast<char>(0xF0 | (cp >> 18));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 12)));
            stream << static_cast<char>(0x80 | (0x3F & (cp >> 6)));
            stream << static_cast<char>(0x80 | (0x3F & (cp)));
        }
    }

    return stream.str();
}

Character& Character::operator=(const Character& origin)
{
    _code_points = origin._code_points;
    return *this;
}

Character& Character::operator=(Character&& origin)
{
    _code_points = std::move(origin._code_points);
    return *this;
}

bool Character::operator==(const Character& other) const
{
    return (unicode::nfd(_code_points) == unicode::nfd(other._code_points));
}

bool Character::operator!=(const Character& other) const
{
    return !(*this == other);
}

} // namespace seshat<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (c) 2012-2013 Sergey Lisitsyn
 */

#include <shogun/lib/tapkee/tapkee_shogun.hpp>

#ifdef HAVE_EIGEN3

#define TAPKEE_EIGEN_INCLUDE_FILE <shogun/mathematics/eigen3.h>
#ifdef HAVE_ARPACK
	#define TAPKEE_WITH_ARPACK
#endif
#define TAPKEE_USE_LGPL_COVERTREE
#include <shogun/lib/tapkee/tapkee.hpp>
#include <shogun/lib/tapkee/callbacks/pimpl_callbacks.hpp>

TAPKEE_CALLBACK_IS_KERNEL(pimpl_kernel_callback<CKernel>);
TAPKEE_CALLBACK_IS_DISTANCE(pimpl_distance_callback<CDistance>);

using namespace shogun;

class ShogunLoggerImplementation : public tapkee::LoggerImplementation
{
	virtual void message_info(const std::string& msg)
	{
		SG_SINFO((msg+"\n").c_str())
	}
	virtual void message_warning(const std::string& msg)
	{
		SG_SWARNING((msg+"\n").c_str())
	}
	virtual void message_error(const std::string& msg)
	{
		SG_SERROR((msg+"\n").c_str())
	}
	virtual void message_debug(const std::string& msg)
	{
		SG_SDEBUG((msg+"\n").c_str())
	}
	virtual void message_benchmark(const std::string& msg)
	{
		SG_SINFO((msg+"\n").c_str())
	}
};

struct ShogunFeatureVectorCallback
{
	ShogunFeatureVectorCallback(CDotFeatures* f) : features(f) { }
	inline void operator()(int i, tapkee::DenseVector& vector) const
	{
		vector.setZero();
		features->add_to_dense_vec(1.0,i,vector.data(),features->get_dim_feature_space());
	}
	CDotFeatures* features;
};

CDenseFeatures<float64_t>* shogun::tapkee_embed(const shogun::TAPKEE_PARAMETERS_FOR_SHOGUN& parameters)
{
	tapkee::LoggingSingleton::instance().set_logger_impl(new ShogunLoggerImplementation);
	tapkee::LoggingSingleton::instance().enable_benchmark();
	tapkee::LoggingSingleton::instance().enable_info();

	pimpl_kernel_callback<CKernel> kernel_callback(parameters.kernel);
	pimpl_distance_callback<CDistance> distance_callback(parameters.distance);
	ShogunFeatureVectorCallback features_callback(parameters.features);

	tapkee::ParametersMap tapkee_parameters;
#ifdef HAVE_ARPACK
	tapkee_parameters[tapkee::EIGEN_EMBEDDING_METHOD] = tapkee::ARPACK;
#else
	tapkee_parameters[tapkee::EIGEN_EMBEDDING_METHOD] = tapkee::EIGEN_DENSE_SELFADJOINT_SOLVER;
#endif
	tapkee_parameters[tapkee::NEIGHBORS_METHOD] = tapkee::COVER_TREE;
	tapkee_parameters[tapkee::TARGET_DIMENSION] = static_cast<tapkee::IndexType>(parameters.target_dimension);
	tapkee_parameters[tapkee::EIGENSHIFT] = static_cast<tapkee::ScalarType>(parameters.eigenshift);
	tapkee_parameters[tapkee::CHECK_CONNECTIVITY] = true;
	size_t N = 0;

	switch (parameters.method)
	{
		case SHOGUN_KERNEL_LOCALLY_LINEAR_EMBEDDING:
		case SHOGUN_LOCALLY_LINEAR_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_NEIGHBORHOOD_PRESERVING_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_LOCAL_TANGENT_SPACE_ALIGNMENT:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCAL_TANGENT_SPACE_ALIGNMENT;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_LINEAR_LOCAL_TANGENT_SPACE_ALIGNMENT:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LINEAR_LOCAL_TANGENT_SPACE_ALIGNMENT;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_HESSIAN_LOCALLY_LINEAR_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::HESSIAN_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_DIFFUSION_MAPS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::DIFFUSION_MAP;
			tapkee_parameters[tapkee::DIFFUSION_MAP_TIMESTEPS] =
				static_cast<tapkee::IndexType>(parameters.n_timesteps);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LAPLACIAN_EIGENMAPS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LAPLACIAN_EIGENMAPS;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LOCALITY_PRESERVING_PROJECTIONS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LOCALITY_PRESERVING_PROJECTIONS;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_MULTIDIMENSIONAL_SCALING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::MULTIDIMENSIONAL_SCALING;
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LANDMARK_MULTIDIMENSIONAL_SCALING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LANDMARK_MULTIDIMENSIONAL_SCALING;
			tapkee_parameters[tapkee::LANDMARK_RATIO] =
				static_cast<tapkee::ScalarType>(parameters.landmark_ratio);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_ISOMAP:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::ISOMAP;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LANDMARK_ISOMAP:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LANDMARK_ISOMAP;
			tapkee_parameters[tapkee::LANDMARK_RATIO] =
				static_cast<tapkee::ScalarType>(parameters.landmark_ratio);
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_STOCHASTIC_PROXIMITY_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::STOCHASTIC_PROXIMITY_EMBEDDING;
			N = parameters.distance->get_num_vec_lhs();
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::SPE_TOLERANCE] =
				static_cast<tapkee::ScalarType>(parameters.spe_tolerance);
			tapkee_parameters[tapkee::SPE_NUM_UPDATES] =
				static_cast<tapkee::IndexType>(parameters.spe_num_updates);
			tapkee_parameters[tapkee::MAX_ITERATION] =
				static_cast<tapkee::IndexType>(parameters.max_iteration);
			if (parameters.spe_global_strategy)
				tapkee_parameters[tapkee::SPE_GLOBAL_STRATEGY] = true;
			else
				tapkee_parameters[tapkee::SPE_GLOBAL_STRATEGY] = false;
			break;
		case SHOGUN_FACTOR_ANALYSIS:
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.features->get_num_vectors();
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::FACTOR_ANALYSIS;
			tapkee_parameters[tapkee::MAX_ITERATION] =
				static_cast<tapkee::IndexType>(parameters.max_iteration);
			tapkee_parameters[tapkee::FA_EPSILON] =
				static_cast<tapkee::ScalarType>(parameters.fa_epsilon);
			break;
	}

	std::vector<int32_t> indices(N);
	for (size_t i=0; i<N; i++)
		indices[i] = i;

	tapkee::ReturnResult result = tapkee::embed(indices.begin(),indices.end(),
			kernel_callback,distance_callback,features_callback,tapkee_parameters);
	tapkee::DenseMatrix result_embedding = result.first;
	// destroy projecting function
	result.second.clear();

	SGMatrix<float64_t> feature_matrix(parameters.target_dimension,N);
	// TODO avoid copying
	for (uint32_t i=0; i<N; i++)
	{
		for (uint32_t j=0; j<parameters.target_dimension; j++)
		{
			feature_matrix(j,i) = result_embedding(i,j);
		}
	}
	return new CDenseFeatures<float64_t>(feature_matrix);
}

#endif
<commit_msg>Fixed compilation<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (c) 2012-2013 Sergey Lisitsyn
 */

#include <shogun/lib/tapkee/tapkee_shogun.hpp>

#ifdef HAVE_EIGEN3

#define TAPKEE_EIGEN_INCLUDE_FILE <shogun/mathematics/eigen3.h>
#ifdef HAVE_ARPACK
	#define TAPKEE_WITH_ARPACK
#endif
#define TAPKEE_USE_LGPL_COVERTREE
#include <shogun/lib/tapkee/tapkee.hpp>
#include <shogun/lib/tapkee/callback/pimpl_callbacks.hpp>

TAPKEE_CALLBACK_IS_KERNEL(pimpl_kernel_callback<CKernel>);
TAPKEE_CALLBACK_IS_DISTANCE(pimpl_distance_callback<CDistance>);

using namespace shogun;

class ShogunLoggerImplementation : public tapkee::LoggerImplementation
{
	virtual void message_info(const std::string& msg)
	{
		SG_SINFO((msg+"\n").c_str())
	}
	virtual void message_warning(const std::string& msg)
	{
		SG_SWARNING((msg+"\n").c_str())
	}
	virtual void message_error(const std::string& msg)
	{
		SG_SERROR((msg+"\n").c_str())
	}
	virtual void message_debug(const std::string& msg)
	{
		SG_SDEBUG((msg+"\n").c_str())
	}
	virtual void message_benchmark(const std::string& msg)
	{
		SG_SINFO((msg+"\n").c_str())
	}
};

struct ShogunFeatureVectorCallback
{
	ShogunFeatureVectorCallback(CDotFeatures* f) : features(f) { }
	inline void operator()(int i, tapkee::DenseVector& vector) const
	{
		vector.setZero();
		features->add_to_dense_vec(1.0,i,vector.data(),features->get_dim_feature_space());
	}
	CDotFeatures* features;
};

CDenseFeatures<float64_t>* shogun::tapkee_embed(const shogun::TAPKEE_PARAMETERS_FOR_SHOGUN& parameters)
{
	tapkee::LoggingSingleton::instance().set_logger_impl(new ShogunLoggerImplementation);
	tapkee::LoggingSingleton::instance().enable_benchmark();
	tapkee::LoggingSingleton::instance().enable_info();

	pimpl_kernel_callback<CKernel> kernel_callback(parameters.kernel);
	pimpl_distance_callback<CDistance> distance_callback(parameters.distance);
	ShogunFeatureVectorCallback features_callback(parameters.features);

	tapkee::ParametersMap tapkee_parameters;
#ifdef HAVE_ARPACK
	tapkee_parameters[tapkee::EIGEN_EMBEDDING_METHOD] = tapkee::ARPACK;
#else
	tapkee_parameters[tapkee::EIGEN_EMBEDDING_METHOD] = tapkee::EIGEN_DENSE_SELFADJOINT_SOLVER;
#endif
	tapkee_parameters[tapkee::NEIGHBORS_METHOD] = tapkee::COVER_TREE;
	tapkee_parameters[tapkee::TARGET_DIMENSION] = static_cast<tapkee::IndexType>(parameters.target_dimension);
	tapkee_parameters[tapkee::EIGENSHIFT] = static_cast<tapkee::ScalarType>(parameters.eigenshift);
	tapkee_parameters[tapkee::CHECK_CONNECTIVITY] = true;
	size_t N = 0;

	switch (parameters.method)
	{
		case SHOGUN_KERNEL_LOCALLY_LINEAR_EMBEDDING:
		case SHOGUN_LOCALLY_LINEAR_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_NEIGHBORHOOD_PRESERVING_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_LOCAL_TANGENT_SPACE_ALIGNMENT:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::KERNEL_LOCAL_TANGENT_SPACE_ALIGNMENT;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_LINEAR_LOCAL_TANGENT_SPACE_ALIGNMENT:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LINEAR_LOCAL_TANGENT_SPACE_ALIGNMENT;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_HESSIAN_LOCALLY_LINEAR_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::HESSIAN_LOCALLY_LINEAR_EMBEDDING;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.kernel->get_num_vec_lhs();
			break;
		case SHOGUN_DIFFUSION_MAPS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::DIFFUSION_MAP;
			tapkee_parameters[tapkee::DIFFUSION_MAP_TIMESTEPS] =
				static_cast<tapkee::IndexType>(parameters.n_timesteps);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LAPLACIAN_EIGENMAPS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LAPLACIAN_EIGENMAPS;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LOCALITY_PRESERVING_PROJECTIONS:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LOCALITY_PRESERVING_PROJECTIONS;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::GAUSSIAN_KERNEL_WIDTH] =
				static_cast<tapkee::ScalarType>(parameters.gaussian_kernel_width);
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_MULTIDIMENSIONAL_SCALING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::MULTIDIMENSIONAL_SCALING;
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LANDMARK_MULTIDIMENSIONAL_SCALING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LANDMARK_MULTIDIMENSIONAL_SCALING;
			tapkee_parameters[tapkee::LANDMARK_RATIO] =
				static_cast<tapkee::ScalarType>(parameters.landmark_ratio);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_ISOMAP:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::ISOMAP;
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_LANDMARK_ISOMAP:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::LANDMARK_ISOMAP;
			tapkee_parameters[tapkee::LANDMARK_RATIO] =
				static_cast<tapkee::ScalarType>(parameters.landmark_ratio);
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			N = parameters.distance->get_num_vec_lhs();
			break;
		case SHOGUN_STOCHASTIC_PROXIMITY_EMBEDDING:
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::STOCHASTIC_PROXIMITY_EMBEDDING;
			N = parameters.distance->get_num_vec_lhs();
			tapkee_parameters[tapkee::NUMBER_OF_NEIGHBORS] =
				static_cast<tapkee::IndexType>(parameters.n_neighbors);
			tapkee_parameters[tapkee::SPE_TOLERANCE] =
				static_cast<tapkee::ScalarType>(parameters.spe_tolerance);
			tapkee_parameters[tapkee::SPE_NUM_UPDATES] =
				static_cast<tapkee::IndexType>(parameters.spe_num_updates);
			tapkee_parameters[tapkee::MAX_ITERATION] =
				static_cast<tapkee::IndexType>(parameters.max_iteration);
			if (parameters.spe_global_strategy)
				tapkee_parameters[tapkee::SPE_GLOBAL_STRATEGY] = true;
			else
				tapkee_parameters[tapkee::SPE_GLOBAL_STRATEGY] = false;
			break;
		case SHOGUN_FACTOR_ANALYSIS:
			tapkee_parameters[tapkee::CURRENT_DIMENSION] =
				static_cast<tapkee::IndexType>(parameters.features->get_dim_feature_space());
			N = parameters.features->get_num_vectors();
			tapkee_parameters[tapkee::REDUCTION_METHOD] =
				tapkee::FACTOR_ANALYSIS;
			tapkee_parameters[tapkee::MAX_ITERATION] =
				static_cast<tapkee::IndexType>(parameters.max_iteration);
			tapkee_parameters[tapkee::FA_EPSILON] =
				static_cast<tapkee::ScalarType>(parameters.fa_epsilon);
			break;
	}

	std::vector<int32_t> indices(N);
	for (size_t i=0; i<N; i++)
		indices[i] = i;

	tapkee::ReturnResult result = tapkee::embed(indices.begin(),indices.end(),
			kernel_callback,distance_callback,features_callback,tapkee_parameters);
	tapkee::DenseMatrix result_embedding = result.first;
	// destroy projecting function
	result.second.clear();

	SGMatrix<float64_t> feature_matrix(parameters.target_dimension,N);
	// TODO avoid copying
	for (uint32_t i=0; i<N; i++)
	{
		for (uint32_t j=0; j<parameters.target_dimension; j++)
		{
			feature_matrix(j,i) = result_embedding(i,j);
		}
	}
	return new CDenseFeatures<float64_t>(feature_matrix);
}

#endif
<|endoftext|>


<commit_before>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "span_analyzer_config_xml_handler.h"

#include "appcommon/xml/color_xml_handler.h"
#include "wx/filename.h"

#include "span_analyzer_app.h"

SpanAnalyzerConfigXmlHandler::SpanAnalyzerConfigXmlHandler() {
}

SpanAnalyzerConfigXmlHandler::~SpanAnalyzerConfigXmlHandler() {
}

wxXmlNode* SpanAnalyzerConfigXmlHandler::CreateNode(
    const SpanAnalyzerConfig& config) {
  // variables used to create XML node
  wxXmlNode* node_root = nullptr;
  wxXmlNode* node_element = nullptr;
  wxXmlNode* sub_node = nullptr;
  std::string title;
  std::string content;

  // creates a node for the root
  node_root = new wxXmlNode(wxXML_ELEMENT_NODE, "span_analyzer_config");
  node_root->AddAttribute("version", "1");

  // adds child nodes for struct parameters

  // creates log level node
  title = "level_log";
  if (config.level_log == wxLOG_Message) {
    content = "Normal";
  } else if (config.level_log == wxLOG_Info) {
    content = "Verbose";
  } else {
    content = "";
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates filepath-data node
  title = "filepath_data";
  content = config.filepath_data;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates color-background node
  node_element = ColorXmlHandler::CreateNode(config.color_background,
                                             "background");
  node_root->AddChild(node_element);

  // creates options-plot-cable node
  title = "options_plot_cable";
  node_element = new wxXmlNode(wxXML_ELEMENT_NODE, title);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_core, "core");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_markers, "markers");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_shell, "shell");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_total, "total");
  node_element->AddChild(sub_node);

  title = "thickness_line";
  content = std::to_string(config.options_plot_profile.thickness_line);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  node_root->AddChild(node_element);

  // creates options-plot-profile node
  title = "options_plot_profile";
  node_element = new wxXmlNode(wxXML_ELEMENT_NODE, title);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_profile.color_catenary, "catenary");
  node_element->AddChild(sub_node);

  title = "scale_horizontal";
  content = std::to_string(config.options_plot_profile.scale_horizontal);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  title = "scale_vertical";
  content = std::to_string(config.options_plot_profile.scale_vertical);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  title = "thickness_line";
  content = std::to_string(config.options_plot_profile.thickness_line);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  node_root->AddChild(node_element);

  // creates perspective node
  title = "perspective";
  content = config.perspective;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates size-frame node
  title = "size_frame";
  content = "";
  node_element = CreateElementNodeWithContent(title, content);

  wxString str;
  str = std::to_string(config.size_frame.GetWidth());
  node_element->AddAttribute("x", str);
  str = std::to_string(config.size_frame.GetHeight());
  node_element->AddAttribute("y", str);
  node_root->AddChild(node_element);

  // creates units node
  title = "units";
  if (config.units == units::UnitSystem::kMetric) {
    content = wxString("Metric");
  } else if (config.units == units::UnitSystem::kImperial) {
    content = wxString("Imperial");
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // returns node
  return node_root;
}

bool SpanAnalyzerConfigXmlHandler::ParseNode(const wxXmlNode* root,
                                             const std::string& filepath,
                                             SpanAnalyzerConfig& config) {
  wxString message;

  // checks for valid root node
  if (root->GetName() != "span_analyzer_config") {
    message = FileAndLineNumber(filepath, root) +
              " Invalid root node. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // gets version attribute
  wxString version;
  if (root->GetAttribute("version", &version) == false) {
    message = FileAndLineNumber(filepath, root) +
              " Version attribute is missing. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // sends to proper parsing function
  if (version == "1") {
    return ParseNodeV1(root, filepath, config);
  } else {
    message = FileAndLineNumber(filepath, root) +
              " Invalid version number. Aborting node parse.";
    wxLogError(message);
    return false;
  }
}

bool SpanAnalyzerConfigXmlHandler::ParseNodeV1(const wxXmlNode* root,
                                               const std::string& filepath,
                                               SpanAnalyzerConfig& config) {
  bool status = true;
  wxString message;

  // evaluates each child node
  const wxXmlNode* node = root->GetChildren();
  while (node != nullptr) {
    const wxString title = node->GetName();
    const wxString content = ParseElementNodeWithContent(node);

    if ((title == "color") && (node->GetAttribute("name") == "background")) {
      status = ColorXmlHandler::ParseNode(node, filepath,
                                          config.color_background);
    } else if (title == "filepath_data") {
      if (content.empty() == false) {
        config.filepath_data = content;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Application data file isn't defined. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "level_log") {
      if (content == "Normal") {
        config.level_log = wxLOG_Message;
      } else if (content == "Verbose") {
        config.level_log = wxLOG_Info;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Logging level isn't recognized. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "options_plot_cable") {
      // gets sub-nodes
      wxXmlNode* sub_node = node->GetChildren();
      while (sub_node != nullptr) {
        wxString sub_title = sub_node->GetName();
        wxString sub_content = ParseElementNodeWithContent(sub_node);
        long value = -9999;

        if (sub_title == "color") {
          if (sub_node->GetAttribute("name") == "core") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_core);
          } else if (sub_node->GetAttribute("name") == "markers") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_markers);
          } else if (sub_node->GetAttribute("name") == "shell") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_shell);
          } else if (sub_node->GetAttribute("name") == "total") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_total);
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "XML node isn't recognized. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "thickness_line") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_cable.thickness_line = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid line thickness. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else {
          message = FileAndLineNumber(filepath, node)
                    + "XML node isn't recognized. Skipping.";
          wxLogError(message);
          status = false;
        }

        sub_node = sub_node->GetNext();
      }
    } else if (title == "options_plot_profile") {
      // gets sub-nodes
      wxXmlNode* sub_node = node->GetChildren();
      while (sub_node != nullptr) {
        wxString sub_title = sub_node->GetName();
        wxString sub_content = ParseElementNodeWithContent(sub_node);
        long value = -9999;

        if (sub_title == "color") {
          if (sub_node->GetAttribute("name") == "catenary") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_profile.color_catenary);
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "XML node isn't recognized. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "scale_horizontal") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.scale_horizontal = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid horizontal scale. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "scale_vertical") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.scale_vertical = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid vertical scale. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "thickness_line") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.thickness_line = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid line thickness. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else {
          message = FileAndLineNumber(filepath, node)
                    + "XML node isn't recognized. Skipping.";
          wxLogError(message);
          status = false;
        }

        sub_node = sub_node->GetNext();
      }
    } else if (title == "perspective") {
      config.perspective = content;
    } else if (title == "size_frame") {
      std::string str;
      str = node->GetAttribute("x");
      config.size_frame.SetWidth(std::stoi(str));
      str = node->GetAttribute("y");
      config.size_frame.SetHeight(std::stoi(str));
    } else if (title == "units") {
      if (content == "Metric") {
        config.units = units::UnitSystem::kMetric;
      } else if (content == "Imperial") {
        config.units = units::UnitSystem::kImperial;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Unit system isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else {
      message = FileAndLineNumber(filepath, node)
                + "XML node isn't recognized. Skipping.";
      wxLogError(message);
      status = false;
    }

    node = node->GetNext();
  }

  return status;
}
<commit_msg>ConfigXmlHandler fix.<commit_after>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "span_analyzer_config_xml_handler.h"

#include "appcommon/xml/color_xml_handler.h"
#include "wx/filename.h"

#include "span_analyzer_app.h"

SpanAnalyzerConfigXmlHandler::SpanAnalyzerConfigXmlHandler() {
}

SpanAnalyzerConfigXmlHandler::~SpanAnalyzerConfigXmlHandler() {
}

wxXmlNode* SpanAnalyzerConfigXmlHandler::CreateNode(
    const SpanAnalyzerConfig& config) {
  // variables used to create XML node
  wxXmlNode* node_root = nullptr;
  wxXmlNode* node_element = nullptr;
  wxXmlNode* sub_node = nullptr;
  std::string title;
  std::string content;

  // creates a node for the root
  node_root = new wxXmlNode(wxXML_ELEMENT_NODE, "span_analyzer_config");
  node_root->AddAttribute("version", "1");

  // adds child nodes for struct parameters

  // creates log level node
  title = "level_log";
  if (config.level_log == wxLOG_Message) {
    content = "Normal";
  } else if (config.level_log == wxLOG_Info) {
    content = "Verbose";
  } else {
    content = "";
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates filepath-data node
  title = "filepath_data";
  content = config.filepath_data;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates color-background node
  node_element = ColorXmlHandler::CreateNode(config.color_background,
                                             "background");
  node_root->AddChild(node_element);

  // creates options-plot-cable node
  title = "options_plot_cable";
  node_element = new wxXmlNode(wxXML_ELEMENT_NODE, title);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_core, "core");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_markers, "markers");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_shell, "shell");
  node_element->AddChild(sub_node);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_cable.color_total, "total");
  node_element->AddChild(sub_node);

  title = "thickness_line";
  content = std::to_string(config.options_plot_cable.thickness_line);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  node_root->AddChild(node_element);

  // creates options-plot-profile node
  title = "options_plot_profile";
  node_element = new wxXmlNode(wxXML_ELEMENT_NODE, title);

  sub_node = ColorXmlHandler::CreateNode(
      config.options_plot_profile.color_catenary, "catenary");
  node_element->AddChild(sub_node);

  title = "scale_horizontal";
  content = std::to_string(config.options_plot_profile.scale_horizontal);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  title = "scale_vertical";
  content = std::to_string(config.options_plot_profile.scale_vertical);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  title = "thickness_line";
  content = std::to_string(config.options_plot_profile.thickness_line);
  sub_node = CreateElementNodeWithContent(title, content);
  node_element->AddChild(sub_node);

  node_root->AddChild(node_element);

  // creates perspective node
  title = "perspective";
  content = config.perspective;
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // creates size-frame node
  title = "size_frame";
  content = "";
  node_element = CreateElementNodeWithContent(title, content);

  wxString str;
  str = std::to_string(config.size_frame.GetWidth());
  node_element->AddAttribute("x", str);
  str = std::to_string(config.size_frame.GetHeight());
  node_element->AddAttribute("y", str);
  node_root->AddChild(node_element);

  // creates units node
  title = "units";
  if (config.units == units::UnitSystem::kMetric) {
    content = wxString("Metric");
  } else if (config.units == units::UnitSystem::kImperial) {
    content = wxString("Imperial");
  }
  node_element = CreateElementNodeWithContent(title, content);
  node_root->AddChild(node_element);

  // returns node
  return node_root;
}

bool SpanAnalyzerConfigXmlHandler::ParseNode(const wxXmlNode* root,
                                             const std::string& filepath,
                                             SpanAnalyzerConfig& config) {
  wxString message;

  // checks for valid root node
  if (root->GetName() != "span_analyzer_config") {
    message = FileAndLineNumber(filepath, root) +
              " Invalid root node. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // gets version attribute
  wxString version;
  if (root->GetAttribute("version", &version) == false) {
    message = FileAndLineNumber(filepath, root) +
              " Version attribute is missing. Aborting node parse.";
    wxLogError(message);
    return false;
  }

  // sends to proper parsing function
  if (version == "1") {
    return ParseNodeV1(root, filepath, config);
  } else {
    message = FileAndLineNumber(filepath, root) +
              " Invalid version number. Aborting node parse.";
    wxLogError(message);
    return false;
  }
}

bool SpanAnalyzerConfigXmlHandler::ParseNodeV1(const wxXmlNode* root,
                                               const std::string& filepath,
                                               SpanAnalyzerConfig& config) {
  bool status = true;
  wxString message;

  // evaluates each child node
  const wxXmlNode* node = root->GetChildren();
  while (node != nullptr) {
    const wxString title = node->GetName();
    const wxString content = ParseElementNodeWithContent(node);

    if ((title == "color") && (node->GetAttribute("name") == "background")) {
      status = ColorXmlHandler::ParseNode(node, filepath,
                                          config.color_background);
    } else if (title == "filepath_data") {
      if (content.empty() == false) {
        config.filepath_data = content;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Application data file isn't defined. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "level_log") {
      if (content == "Normal") {
        config.level_log = wxLOG_Message;
      } else if (content == "Verbose") {
        config.level_log = wxLOG_Info;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Logging level isn't recognized. Keeping default "
                  "setting.";
        wxLogWarning(message);
      }
    } else if (title == "options_plot_cable") {
      // gets sub-nodes
      wxXmlNode* sub_node = node->GetChildren();
      while (sub_node != nullptr) {
        wxString sub_title = sub_node->GetName();
        wxString sub_content = ParseElementNodeWithContent(sub_node);
        long value = -9999;

        if (sub_title == "color") {
          if (sub_node->GetAttribute("name") == "core") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_core);
          } else if (sub_node->GetAttribute("name") == "markers") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_markers);
          } else if (sub_node->GetAttribute("name") == "shell") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_shell);
          } else if (sub_node->GetAttribute("name") == "total") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_cable.color_total);
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "XML node isn't recognized. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "thickness_line") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_cable.thickness_line = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid line thickness. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else {
          message = FileAndLineNumber(filepath, node)
                    + "XML node isn't recognized. Skipping.";
          wxLogError(message);
          status = false;
        }

        sub_node = sub_node->GetNext();
      }
    } else if (title == "options_plot_profile") {
      // gets sub-nodes
      wxXmlNode* sub_node = node->GetChildren();
      while (sub_node != nullptr) {
        wxString sub_title = sub_node->GetName();
        wxString sub_content = ParseElementNodeWithContent(sub_node);
        long value = -9999;

        if (sub_title == "color") {
          if (sub_node->GetAttribute("name") == "catenary") {
            status = ColorXmlHandler::ParseNode(
                sub_node, filepath,
                config.options_plot_profile.color_catenary);
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "XML node isn't recognized. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "scale_horizontal") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.scale_horizontal = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid horizontal scale. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "scale_vertical") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.scale_vertical = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid vertical scale. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else if (sub_title == "thickness_line") {
          if (sub_content.ToLong(&value) == true) {
            config.options_plot_profile.thickness_line = value;
          } else {
            message = FileAndLineNumber(filepath, node)
                      + "Invalid line thickness. Skipping.";
            wxLogError(message);
            status = false;
          }
        } else {
          message = FileAndLineNumber(filepath, node)
                    + "XML node isn't recognized. Skipping.";
          wxLogError(message);
          status = false;
        }

        sub_node = sub_node->GetNext();
      }
    } else if (title == "perspective") {
      config.perspective = content;
    } else if (title == "size_frame") {
      std::string str;
      str = node->GetAttribute("x");
      config.size_frame.SetWidth(std::stoi(str));
      str = node->GetAttribute("y");
      config.size_frame.SetHeight(std::stoi(str));
    } else if (title == "units") {
      if (content == "Metric") {
        config.units = units::UnitSystem::kMetric;
      } else if (content == "Imperial") {
        config.units = units::UnitSystem::kImperial;
      } else {
        message = FileAndLineNumber(filepath, node)
                  + "Unit system isn't recognized. Keeping default setting.";
        wxLogWarning(message);
      }
    } else {
      message = FileAndLineNumber(filepath, node)
                + "XML node isn't recognized. Skipping.";
      wxLogError(message);
      status = false;
    }

    node = node->GetNext();
  }

  return status;
}
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/native_object_base.hpp"
#include "flusspferd/tracer.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/string.hpp"
#include "flusspferd/call_context.hpp"
#include "flusspferd/root.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/function.hpp"
#include "flusspferd/current_context_scope.hpp"
#include "flusspferd/implementation/init.hpp"
#include <boost/unordered_map.hpp>
#include <boost/variant.hpp>

using namespace flusspferd;

class native_object_base::impl {
public:
  static void finalize(JSContext *ctx, JSObject *obj);
  static JSBool call_helper(JSContext *, JSObject *, uintN, jsval *, jsval *);
  static uint32 mark_op(JSContext *, JSObject *, void *);

  template<property_mode>
  static JSBool property_op(JSContext *, JSObject *, jsval, jsval *);

  static JSClass native_object_class;

public:
  typedef boost::variant<native_method_type, callback_type> method_variant;

  typedef boost::unordered_map<std::string, method_variant> native_method_map;

  native_method_map native_methods;

public:
  typedef boost::unordered_map<std::string, property_callback> property_callback_map;

  property_callback_map property_callbacks;
};

JSClass native_object_base::impl::native_object_class = {
  "NativeObject",
  JSCLASS_HAS_PRIVATE,
  &native_object_base::impl::property_op<native_object_base::property_add>,
  &native_object_base::impl::property_op<native_object_base::property_delete>,
  &native_object_base::impl::property_op<native_object_base::property_get>,
  &native_object_base::impl::property_op<native_object_base::property_set>,
  JS_EnumerateStub,
  JS_ResolveStub,
  JS_ConvertStub,
  &native_object_base::impl::finalize,
  0,
  0,
  &native_object_base::impl::call_helper,
  0,
  0,
  0,
  &native_object_base::impl::mark_op,
  0
};

native_object_base::native_object_base(object const &o) : p(new impl) {
  load_into(o);
}

native_object_base::~native_object_base() {}

void native_object_base::load_into(object const &o) {
  if (is_valid())
    throw exception("Cannot load native_object data into more than one object");

  object::operator=(o);

  if (is_valid()) {
    if (!JS_SetPrivate(Impl::current_context(), Impl::get_object(o), this))
      throw exception("Could not create native object (private data)");
  }
}

void native_object_base::invalid_method(call_context &) {
  throw exception("Invalid method");
}

native_object_base *native_object_base::get_native(object const &o_) {
  object o = o_;

  if (!o.is_valid())
    throw exception("Can not interpret 'null' as native object");

  JSContext *ctx = Impl::current_context();

  void *priv = JS_GetInstancePrivate(
      ctx, Impl::get_object(o), &impl::native_object_class, 0);

  if (!priv)
    throw exception("Object is not native");

  return static_cast<native_object_base*>(priv);
}

object native_object_base::do_create_object(object const &prototype_) {
  JSContext *ctx = Impl::current_context();

  object prototype = prototype_;

  JSObject *o = JS_NewObject(
      ctx,
      &impl::native_object_class,
      Impl::get_object(prototype),
      0);

  if (!o)
    throw exception("Could not create native object");

  return Impl::wrap_object(o);
}

void native_object_base::add_native_method(
    std::string const &name, unsigned arity)
{
  JSContext *ctx = Impl::current_context();

  JSFunction *func = JS_DefineFunction(
      ctx,
      this->object::get(),
      name.c_str(),
      &impl::call_helper,
      arity,
      0);

  if (!func)
    throw exception("Could not create native method " + name);
}

function native_object_base::create_native_method(
    std::string const &name, unsigned arity)
{
  JSContext *ctx = Impl::current_context();

  JSFunction *func = JS_NewFunction(
      ctx,
      &impl::call_helper,
      arity,
      0, // flags
      0, // parent
      name.c_str());

  if (!func)
    throw exception("Could not create native method " + name);

  return Impl::wrap_function(func);
}

function native_object_base::create_native_method(
    object &container, std::string const &name, unsigned arity)
{
  function fun = create_native_method(name, arity);
  container.define_property(
      name,
      fun,
      object::dont_enumerate);
  return fun;
}

void native_object_base::register_native_method(
  std::string const &name, native_method_type method)
{
  p->native_methods[name] = method;
}

void native_object_base::register_native_method_cb(
  std::string const &name, callback_type const &cb)
{
  p->native_methods[name] = cb;
}

void native_object_base::add_property_op(
  std::string const &name, property_callback callback)
{
  p->property_callbacks[name] = callback;
}

void native_object_base::impl::finalize(JSContext *ctx, JSObject *obj) {
  void *p = JS_GetPrivate(ctx, obj);

  if (p)
    delete static_cast<native_object_base*>(p);
}

JSBool native_object_base::impl::call_helper(
    JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  FLUSSPFERD_CALLBACK_BEGIN {
    current_context_scope scope(Impl::wrap_context(ctx));

    JSObject *function = JSVAL_TO_OBJECT(argv[-2]);

    native_object_base *self = 0;

    try {
      self = native_object_base::get_native(Impl::wrap_object(obj));
    } catch (exception &) {
      self = native_object_base::get_native(Impl::wrap_object(function));
    }

    call_context x;

    x.self = Impl::wrap_object(obj);
    x.self_native = self;
    x.arg = Impl::arguments_impl(argc, argv);
    x.result.bind(Impl::wrap_jsvalp(rval));
    x.function = Impl::wrap_object(function);

    std::string name;

    try {
      name = flusspferd::function(x.function).name().to_string();
    } catch (exception&) {}

    self->call_native_method(name, x);
  } FLUSSPFERD_CALLBACK_END;
}

template<native_object_base::property_mode mode>
JSBool native_object_base::impl::property_op(
    JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
  FLUSSPFERD_CALLBACK_BEGIN {
    current_context_scope scope(Impl::wrap_context(ctx));

    native_object_base *self =
      native_object_base::get_native(Impl::wrap_object(obj));

    value data(Impl::wrap_jsvalp(vp));
    self->property_op(mode, Impl::wrap_jsval(id), data);
  } FLUSSPFERD_CALLBACK_END;
}

uint32 native_object_base::impl::mark_op(
    JSContext *ctx, JSObject *obj, void *thing)
{
  current_context_scope scope(Impl::wrap_context(ctx));

  native_object_base *self =
    native_object_base::get_native(Impl::wrap_object(obj));

  tracer trc(thing);
  self->trace(trc);

  return 0;
}

void native_object_base::call_native_method(
    std::string const &name, call_context &x)
{
  impl::native_method_map::iterator it = p->native_methods.find(name);

  if (it != p->native_methods.end()) {
    impl::method_variant m = it->second;
    switch (m.which()) {
    case 0: // native_method_type
      {
        native_method_type native_method = boost::get<native_method_type>(m);
        if (native_method)
          (this->*native_method)(x);
      }
      break;
    case 1: // callback_type
      {
        callback_type const &callback = boost::get<callback_type>(m);
        if (callback)
          callback(x);
      }
    }
  }
}

void native_object_base::property_op(
    property_mode mode, value const &id, value &data)
{
  std::string name = id.to_string().to_string();
  impl::property_callback_map::iterator it = p->property_callbacks.find(name);

  if (it != p->property_callbacks.end()) {
    property_callback callback = it->second;

    if (callback)
      (this->*callback)(mode, data);
  }
}

void native_object_base::trace(tracer&) {}
void native_object_base::late_load() {}
<commit_msg>Core: fix crash<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/native_object_base.hpp"
#include "flusspferd/tracer.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/string.hpp"
#include "flusspferd/call_context.hpp"
#include "flusspferd/root.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/function.hpp"
#include "flusspferd/current_context_scope.hpp"
#include "flusspferd/implementation/init.hpp"
#include <boost/unordered_map.hpp>
#include <boost/variant.hpp>

using namespace flusspferd;

class native_object_base::impl {
public:
  static void finalize(JSContext *ctx, JSObject *obj);
  static JSBool call_helper(JSContext *, JSObject *, uintN, jsval *, jsval *);
  static uint32 mark_op(JSContext *, JSObject *, void *);

  template<property_mode>
  static JSBool property_op(JSContext *, JSObject *, jsval, jsval *);

  static JSClass native_object_class;

public:
  typedef boost::variant<native_method_type, callback_type> method_variant;

  typedef boost::unordered_map<std::string, method_variant> native_method_map;

  native_method_map native_methods;

public:
  typedef
    boost::unordered_map<std::string, property_callback> property_callback_map;

  property_callback_map property_callbacks;
};

JSClass native_object_base::impl::native_object_class = {
  "NativeObject",
  JSCLASS_HAS_PRIVATE,
  &native_object_base::impl::property_op<native_object_base::property_add>,
  &native_object_base::impl::property_op<native_object_base::property_delete>,
  &native_object_base::impl::property_op<native_object_base::property_get>,
  &native_object_base::impl::property_op<native_object_base::property_set>,
  JS_EnumerateStub,
  JS_ResolveStub,
  JS_ConvertStub,
  &native_object_base::impl::finalize,
  0,
  0,
  &native_object_base::impl::call_helper,
  0,
  0,
  0,
  &native_object_base::impl::mark_op,
  0
};

native_object_base::native_object_base(object const &o) : p(new impl) {
  load_into(o);
}

native_object_base::~native_object_base() {
  if (is_valid()) {
    JS_SetPrivate(Impl::current_context(), get(), 0);
  }
}

void native_object_base::load_into(object const &o) {
  if (is_valid())
    throw exception("Cannot load native_object data into more than one object");

  object::operator=(o);

  if (is_valid()) {
    if (!JS_SetPrivate(Impl::current_context(), Impl::get_object(o), this))
      throw exception("Could not create native object (private data)");
  }
}

void native_object_base::invalid_method(call_context &) {
  throw exception("Invalid method");
}

native_object_base *native_object_base::get_native(object const &o_) {
  object o = o_;

  if (!o.is_valid())
    throw exception("Can not interpret 'null' as native object");

  JSContext *ctx = Impl::current_context();

  void *priv = JS_GetInstancePrivate(
      ctx, Impl::get_object(o), &impl::native_object_class, 0);

  if (!priv)
    throw exception("Object is not native");

  return static_cast<native_object_base*>(priv);
}

object native_object_base::do_create_object(object const &prototype_) {
  JSContext *ctx = Impl::current_context();

  object prototype = prototype_;

  JSObject *o = JS_NewObject(
      ctx,
      &impl::native_object_class,
      Impl::get_object(prototype),
      0);

  if (!o)
    throw exception("Could not create native object");

  return Impl::wrap_object(o);
}

void native_object_base::add_native_method(
    std::string const &name, unsigned arity)
{
  JSContext *ctx = Impl::current_context();

  JSFunction *func = JS_DefineFunction(
      ctx,
      this->object::get(),
      name.c_str(),
      &impl::call_helper,
      arity,
      0);

  if (!func)
    throw exception("Could not create native method " + name);
}

function native_object_base::create_native_method(
    std::string const &name, unsigned arity)
{
  JSContext *ctx = Impl::current_context();

  JSFunction *func = JS_NewFunction(
      ctx,
      &impl::call_helper,
      arity,
      0, // flags
      0, // parent
      name.c_str());

  if (!func)
    throw exception("Could not create native method " + name);

  return Impl::wrap_function(func);
}

function native_object_base::create_native_method(
    object &container, std::string const &name, unsigned arity)
{
  function fun = create_native_method(name, arity);
  container.define_property(
      name,
      fun,
      object::dont_enumerate);
  return fun;
}

void native_object_base::register_native_method(
  std::string const &name, native_method_type method)
{
  p->native_methods[name] = method;
}

void native_object_base::register_native_method_cb(
  std::string const &name, callback_type const &cb)
{
  p->native_methods[name] = cb;
}

void native_object_base::add_property_op(
  std::string const &name, property_callback callback)
{
  p->property_callbacks[name] = callback;
}

void native_object_base::impl::finalize(JSContext *ctx, JSObject *obj) {
  void *p = JS_GetPrivate(ctx, obj);

  if (p)
    delete static_cast<native_object_base*>(p);
}

JSBool native_object_base::impl::call_helper(
    JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  FLUSSPFERD_CALLBACK_BEGIN {
    current_context_scope scope(Impl::wrap_context(ctx));

    JSObject *function = JSVAL_TO_OBJECT(argv[-2]);

    native_object_base *self = 0;

    try {
      self = native_object_base::get_native(Impl::wrap_object(obj));
    } catch (exception &) {
      self = native_object_base::get_native(Impl::wrap_object(function));
    }

    call_context x;

    x.self = Impl::wrap_object(obj);
    x.self_native = self;
    x.arg = Impl::arguments_impl(argc, argv);
    x.result.bind(Impl::wrap_jsvalp(rval));
    x.function = Impl::wrap_object(function);

    std::string name;

    try {
      name = flusspferd::function(x.function).name().to_string();
    } catch (exception&) {}

    self->call_native_method(name, x);
  } FLUSSPFERD_CALLBACK_END;
}

template<native_object_base::property_mode mode>
JSBool native_object_base::impl::property_op(
    JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
  FLUSSPFERD_CALLBACK_BEGIN {
    current_context_scope scope(Impl::wrap_context(ctx));

    native_object_base *self =
      native_object_base::get_native(Impl::wrap_object(obj));

    value data(Impl::wrap_jsvalp(vp));
    self->property_op(mode, Impl::wrap_jsval(id), data);
  } FLUSSPFERD_CALLBACK_END;
}

uint32 native_object_base::impl::mark_op(
    JSContext *ctx, JSObject *obj, void *thing)
{
  current_context_scope scope(Impl::wrap_context(ctx));

  native_object_base *self =
    native_object_base::get_native(Impl::wrap_object(obj));

  tracer trc(thing);
  self->trace(trc);

  return 0;
}

void native_object_base::call_native_method(
    std::string const &name, call_context &x)
{
  impl::native_method_map::iterator it = p->native_methods.find(name);

  if (it != p->native_methods.end()) {
    impl::method_variant m = it->second;
    switch (m.which()) {
    case 0: // native_method_type
      {
        native_method_type native_method = boost::get<native_method_type>(m);
        if (native_method)
          (this->*native_method)(x);
      }
      break;
    case 1: // callback_type
      {
        callback_type const &callback = boost::get<callback_type>(m);
        if (callback)
          callback(x);
      }
    }
  }
}

void native_object_base::property_op(
    property_mode mode, value const &id, value &data)
{
  std::string name = id.to_string().to_string();
  impl::property_callback_map::iterator it = p->property_callbacks.find(name);

  if (it != p->property_callbacks.end()) {
    property_callback callback = it->second;

    if (callback)
      (this->*callback)(mode, data);
  }
}

void native_object_base::trace(tracer&) {}
void native_object_base::late_load() {}
<|endoftext|>


<commit_before>
#include "swganh/simulation/galaxy_service.h"

#include "anh/crc.h"
#include "anh/service/service_manager.h"
#include "anh/database/database_manager.h"

#include "swganh/app/swganh_kernel.h"

#include "swganh/connection/connection_client.h"
#include "swganh/connection/connection_service.h"

#include "swganh/messages/select_character.h"

#include "swganh/network/remote_client.h"

#include "swganh/object/object.h"
#include "swganh/object/object_controller.h"
#include "swganh/object/object_manager.h"

// factories
#include "swganh/object/creature/creature_factory.h"
#include "swganh/object/creature/creature.h"
#include "swganh/object/tangible/tangible_factory.h"
#include "swganh/object/tangible/tangible.h"
#include "swganh/object/intangible/intangible_factory.h"
#include "swganh/object/intangible/intangible.h"
#include "swganh/object/player/player_factory.h"
#include "swganh/object/player/player.h"

#include "swganh/simulation/scene_manager.h"
#include "swganh/messages/cmd_start_scene.h"
#include "swganh/messages/cmd_scene_ready.h"
#include "swganh/messages/scene_create_object_by_crc.h"
#include "swganh/messages/scene_end_baselines.h"

using namespace std;
using namespace swganh::connection;
using namespace swganh::messages;
using namespace swganh::network;
using namespace swganh::object;
using namespace swganh::simulation;

using anh::app::KernelInterface;
using anh::service::ServiceDescription;
using swganh::base::BaseService;

namespace swganh {
namespace simulation {

class GalaxyServiceImpl {
public:
    const shared_ptr<ObjectManager>& GetObjectManager()
    {
        if (!object_manager_)
        {
            object_manager_ = make_shared<ObjectManager>();
        }

        return object_manager_;
    }

    const shared_ptr<SceneManager>& GetSceneManager()
    {
        if (!scene_manager_)
        {
            scene_manager_ = make_shared<SceneManager>();
        }

        return scene_manager_;
    }

	void RegisterObjectFactories(std::shared_ptr<anh::app::KernelInterface> kernel)
	{
		auto db_manager = kernel->GetDatabaseManager();
		GetObjectManager()->RegisterObjectType(tangible::Tangible::type, make_shared<tangible::TangibleFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(intangible::Intangible::type, make_shared<intangible::IntangibleFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(creature::Creature::type, make_shared<creature::CreatureFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(player::Player::type, make_shared<player::PlayerFactory>(db_manager));
	}

    shared_ptr<Object> LoadObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter != loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested object already loaded");
        }

        auto object = object_manager_->CreateObjectFromStorage(object_id);

        loaded_objects_.insert(make_pair(object_id, object));

        return object;
    }

    const shared_ptr<Object>& GetObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter == loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested an invalid object");
        }

        return find_iter->second;
    }

    void RemoveObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter == loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested an invalid object");
        }

        loaded_objects_.erase(find_iter);
    }

    shared_ptr<ObjectController> StartControllingObject(const shared_ptr<Object>& object, shared_ptr<RemoteClient> client)
    {
        auto find_iter = controlled_objects_.find(object->GetObjectId());

        if (find_iter != controlled_objects_.end())
        {
            throw swganh::object::InvalidObject("Object already has a controller");
        }

        auto controller = make_shared<ObjectController>(controller_handlers_, object, client);
		object->SetController(controller);

        controlled_objects_.insert(make_pair(object->GetObjectId(), controller));

        return controller;
    }

    void StopControllingObject(const shared_ptr<Object>& object)
    {
        auto find_iter = controlled_objects_.find(object->GetObjectId());

        if (find_iter == controlled_objects_.end())
        {
            throw swganh::object::InvalidObject("Object has no controller");
        }

        controlled_objects_.erase(find_iter);
    }

    void RegisterControllerHandler(uint32_t handler_id, swganh::object::ObjControllerHandler&& handler)
    {
        auto find_iter = controller_handlers_.find(handler_id);

        if (find_iter != controller_handlers_.end())
        {
            throw std::runtime_error("ObjControllerHandler already exists");
        }

        controller_handlers_.insert(make_pair(handler_id, move(handler)));
    }

    void UnregisterControllerHandler(uint32_t handler_id)
    {
        auto find_iter = controller_handlers_.find(handler_id);

        if (find_iter == controller_handlers_.end())
        {
            throw std::runtime_error("ObjControllerHandler does not exist");
        }

        controller_handlers_.erase(find_iter);
    }

    void HandleSelectCharacter(
        shared_ptr<ConnectionClient> client,
        const SelectCharacter& message)
    {
        auto object = LoadObjectById(message.character_id);
		StartControllingObject(object, client);
		// CmdStartScene
		swganh::messages::CmdStartScene start_scene;
		start_scene.ignore_layout = 0;
		start_scene.character_id = object->GetObjectId();

		start_scene.terrain_map = scene_manager_->GetScene(object->GetSceneId())->GetTerrainMap();
		start_scene.position = object->GetPosition();
		// TODO: Regex this beotch
		start_scene.shared_race_template = "object/creature/player/shared_human_male.iff";
		start_scene.galaxy_time = 0;
		client->GetSession()->SendMessage(start_scene);

		swganh::messages::SceneCreateObjectByCrc scene_create_object;
		scene_create_object.object_id = object->GetObjectId();
		scene_create_object.object_crc = anh::memcrc(object->GetTemplate());
		scene_create_object.position = object->GetPosition();
		scene_create_object.orientation = object->GetOrientation();
		client->GetSession()->SendMessage(scene_create_object);

		swganh::messages::SceneEndBaselines scene_end_baselines;
		scene_end_baselines.object_id = object->GetObjectId();
		client->GetSession()->SendMessage(scene_end_baselines);
    }

private:
    shared_ptr<ObjectManager> object_manager_;
    shared_ptr<SceneManager> scene_manager_;

    ObjControllerHandlerMap controller_handlers_;

    map<uint64_t, shared_ptr<Object>> loaded_objects_;
    map<uint64_t, shared_ptr<ObjectController>> controlled_objects_;
};

}}  // namespace swganh::simulation

GalaxyService::GalaxyService(shared_ptr<KernelInterface> kernel)
    : BaseService(kernel)
    , impl_(new GalaxyServiceImpl)
{}

GalaxyService::~GalaxyService()
{}

ServiceDescription GalaxyService::GetServiceDescription()
{
    ServiceDescription service_description(
        "GalaxyService",
        "galaxy",
        "0.1",
        "127.0.0.1",
        0,
        0,
        0);

    return service_description;
}

void GalaxyService::StartScene(const std::string& scene_label)
{
	impl_->GetSceneManager()->LoadSceneDescriptionsFromDatabase(kernel()->GetDatabaseManager()->getConnection("galaxy"));
    impl_->GetSceneManager()->StartScene(scene_label);
	// load factories
	RegisterObjectFactories(kernel());
}

void GalaxyService::StopScene(const std::string& scene_label)
{
    impl_->GetSceneManager()->StopScene(scene_label);
}
void GalaxyService::RegisterObjectFactories(shared_ptr<anh::app::KernelInterface> kernel)
{
	impl_->RegisterObjectFactories(kernel);
}

shared_ptr<Object> GalaxyService::LoadObjectById(uint64_t object_id)
{
    return impl_->LoadObjectById(object_id);
}

const shared_ptr<Object>& GalaxyService::GetObjectById(uint64_t object_id)
{
    return impl_->GetObjectById(object_id);
}

void GalaxyService::RemoveObjectById(uint64_t object_id)
{
    impl_->RemoveObjectById(object_id);
}

shared_ptr<ObjectController> GalaxyService::StartControllingObject(
    const shared_ptr<Object>& object,
    shared_ptr<RemoteClient> client)
{
    return impl_->StartControllingObject(object, client);
}

void GalaxyService::StopControllingObject(const shared_ptr<Object>& object)
{
    impl_->StopControllingObject(object);
}

void GalaxyService::RegisterControllerHandler(uint32_t handler_id, swganh::object::ObjControllerHandler&& handler)
{
    impl_->RegisterControllerHandler(handler_id, move(handler));
}

void GalaxyService::UnregisterControllerHandler(uint32_t handler_id)
{
    impl_->UnregisterControllerHandler(handler_id);
}

void GalaxyService::onStart()
{
    auto connection_service = std::static_pointer_cast<ConnectionService>(kernel()->GetServiceManager()->GetService("ConnectionService"));

    connection_service->RegisterMessageHandler<SelectCharacter>([=] (
        shared_ptr<ConnectionClient> client,
        const SelectCharacter& message)
    {
        impl_->HandleSelectCharacter(client, message);
    });
}
<commit_msg>Inserted 'shared_' into the shared_race_template string sent to the client for CmdStartScene.<commit_after>
#include "swganh/simulation/galaxy_service.h"

#include "anh/crc.h"
#include "anh/service/service_manager.h"
#include "anh/database/database_manager.h"

#include "swganh/app/swganh_kernel.h"

#include "swganh/connection/connection_client.h"
#include "swganh/connection/connection_service.h"

#include "swganh/messages/select_character.h"

#include "swganh/network/remote_client.h"

#include "swganh/object/object.h"
#include "swganh/object/object_controller.h"
#include "swganh/object/object_manager.h"

// factories
#include "swganh/object/creature/creature_factory.h"
#include "swganh/object/creature/creature.h"
#include "swganh/object/tangible/tangible_factory.h"
#include "swganh/object/tangible/tangible.h"
#include "swganh/object/intangible/intangible_factory.h"
#include "swganh/object/intangible/intangible.h"
#include "swganh/object/player/player_factory.h"
#include "swganh/object/player/player.h"

#include "swganh/simulation/scene_manager.h"
#include "swganh/messages/cmd_start_scene.h"
#include "swganh/messages/cmd_scene_ready.h"
#include "swganh/messages/scene_create_object_by_crc.h"
#include "swganh/messages/scene_end_baselines.h"

using namespace std;
using namespace swganh::connection;
using namespace swganh::messages;
using namespace swganh::network;
using namespace swganh::object;
using namespace swganh::simulation;

using anh::app::KernelInterface;
using anh::service::ServiceDescription;
using swganh::base::BaseService;

namespace swganh {
namespace simulation {

class GalaxyServiceImpl {
public:
    const shared_ptr<ObjectManager>& GetObjectManager()
    {
        if (!object_manager_)
        {
            object_manager_ = make_shared<ObjectManager>();
        }

        return object_manager_;
    }

    const shared_ptr<SceneManager>& GetSceneManager()
    {
        if (!scene_manager_)
        {
            scene_manager_ = make_shared<SceneManager>();
        }

        return scene_manager_;
    }

	void RegisterObjectFactories(std::shared_ptr<anh::app::KernelInterface> kernel)
	{
		auto db_manager = kernel->GetDatabaseManager();
		GetObjectManager()->RegisterObjectType(tangible::Tangible::type, make_shared<tangible::TangibleFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(intangible::Intangible::type, make_shared<intangible::IntangibleFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(creature::Creature::type, make_shared<creature::CreatureFactory>(db_manager));
		GetObjectManager()->RegisterObjectType(player::Player::type, make_shared<player::PlayerFactory>(db_manager));
	}

    shared_ptr<Object> LoadObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter != loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested object already loaded");
        }

        auto object = object_manager_->CreateObjectFromStorage(object_id);

        loaded_objects_.insert(make_pair(object_id, object));

        return object;
    }

    const shared_ptr<Object>& GetObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter == loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested an invalid object");
        }

        return find_iter->second;
    }

    void RemoveObjectById(uint64_t object_id)
    {
        auto find_iter = loaded_objects_.find(object_id);

        if (find_iter == loaded_objects_.end())
        {
            throw swganh::object::InvalidObject("Requested an invalid object");
        }

        loaded_objects_.erase(find_iter);
    }

    shared_ptr<ObjectController> StartControllingObject(const shared_ptr<Object>& object, shared_ptr<RemoteClient> client)
    {
        auto find_iter = controlled_objects_.find(object->GetObjectId());

        if (find_iter != controlled_objects_.end())
        {
            throw swganh::object::InvalidObject("Object already has a controller");
        }

        auto controller = make_shared<ObjectController>(controller_handlers_, object, client);
		object->SetController(controller);

        controlled_objects_.insert(make_pair(object->GetObjectId(), controller));

        return controller;
    }

    void StopControllingObject(const shared_ptr<Object>& object)
    {
        auto find_iter = controlled_objects_.find(object->GetObjectId());

        if (find_iter == controlled_objects_.end())
        {
            throw swganh::object::InvalidObject("Object has no controller");
        }

        controlled_objects_.erase(find_iter);
    }

    void RegisterControllerHandler(uint32_t handler_id, swganh::object::ObjControllerHandler&& handler)
    {
        auto find_iter = controller_handlers_.find(handler_id);

        if (find_iter != controller_handlers_.end())
        {
            throw std::runtime_error("ObjControllerHandler already exists");
        }

        controller_handlers_.insert(make_pair(handler_id, move(handler)));
    }

    void UnregisterControllerHandler(uint32_t handler_id)
    {
        auto find_iter = controller_handlers_.find(handler_id);

        if (find_iter == controller_handlers_.end())
        {
            throw std::runtime_error("ObjControllerHandler does not exist");
        }

        controller_handlers_.erase(find_iter);
    }

    void HandleSelectCharacter(
        shared_ptr<ConnectionClient> client,
        const SelectCharacter& message)
    {
        auto object = LoadObjectById(message.character_id);
		StartControllingObject(object, client);
		// CmdStartScene
        swganh::messages::CmdStartScene start_scene;
        start_scene.ignore_layout = 0;
        start_scene.character_id = object->GetObjectId();

        start_scene.terrain_map = scene_manager_->GetScene(object->GetSceneId())->GetTerrainMap();
        start_scene.position = object->GetPosition();

        std::string shared_template = object->GetStfNameFile();
        shared_template.insert(23, "shared_");
        start_scene.shared_race_template = shared_template;
        start_scene.galaxy_time = 0;
        client->GetSession()->SendMessage(start_scene);

		swganh::messages::SceneCreateObjectByCrc scene_create_object;
		scene_create_object.object_id = object->GetObjectId();
		scene_create_object.object_crc = anh::memcrc(object->GetTemplate());
		scene_create_object.position = object->GetPosition();
		scene_create_object.orientation = object->GetOrientation();
		client->GetSession()->SendMessage(scene_create_object);

		swganh::messages::SceneEndBaselines scene_end_baselines;
		scene_end_baselines.object_id = object->GetObjectId();
		client->GetSession()->SendMessage(scene_end_baselines);
    }

private:
    shared_ptr<ObjectManager> object_manager_;
    shared_ptr<SceneManager> scene_manager_;

    ObjControllerHandlerMap controller_handlers_;

    map<uint64_t, shared_ptr<Object>> loaded_objects_;
    map<uint64_t, shared_ptr<ObjectController>> controlled_objects_;
};

}}  // namespace swganh::simulation

GalaxyService::GalaxyService(shared_ptr<KernelInterface> kernel)
    : BaseService(kernel)
    , impl_(new GalaxyServiceImpl)
{}

GalaxyService::~GalaxyService()
{}

ServiceDescription GalaxyService::GetServiceDescription()
{
    ServiceDescription service_description(
        "GalaxyService",
        "galaxy",
        "0.1",
        "127.0.0.1",
        0,
        0,
        0);

    return service_description;
}

void GalaxyService::StartScene(const std::string& scene_label)
{
	impl_->GetSceneManager()->LoadSceneDescriptionsFromDatabase(kernel()->GetDatabaseManager()->getConnection("galaxy"));
    impl_->GetSceneManager()->StartScene(scene_label);
	// load factories
	RegisterObjectFactories(kernel());
}

void GalaxyService::StopScene(const std::string& scene_label)
{
    impl_->GetSceneManager()->StopScene(scene_label);
}
void GalaxyService::RegisterObjectFactories(shared_ptr<anh::app::KernelInterface> kernel)
{
	impl_->RegisterObjectFactories(kernel);
}

shared_ptr<Object> GalaxyService::LoadObjectById(uint64_t object_id)
{
    return impl_->LoadObjectById(object_id);
}

const shared_ptr<Object>& GalaxyService::GetObjectById(uint64_t object_id)
{
    return impl_->GetObjectById(object_id);
}

void GalaxyService::RemoveObjectById(uint64_t object_id)
{
    impl_->RemoveObjectById(object_id);
}

shared_ptr<ObjectController> GalaxyService::StartControllingObject(
    const shared_ptr<Object>& object,
    shared_ptr<RemoteClient> client)
{
    return impl_->StartControllingObject(object, client);
}

void GalaxyService::StopControllingObject(const shared_ptr<Object>& object)
{
    impl_->StopControllingObject(object);
}

void GalaxyService::RegisterControllerHandler(uint32_t handler_id, swganh::object::ObjControllerHandler&& handler)
{
    impl_->RegisterControllerHandler(handler_id, move(handler));
}

void GalaxyService::UnregisterControllerHandler(uint32_t handler_id)
{
    impl_->UnregisterControllerHandler(handler_id);
}

void GalaxyService::onStart()
{
    auto connection_service = std::static_pointer_cast<ConnectionService>(kernel()->GetServiceManager()->GetService("ConnectionService"));

    connection_service->RegisterMessageHandler<SelectCharacter>([=] (
        shared_ptr<ConnectionClient> client,
        const SelectCharacter& message)
    {
        impl_->HandleSelectCharacter(client, message);
    });
}
<|endoftext|>