<commit_before>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2022 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "entity.hpp"
#include "variable.hpp"
#include "universe.hpp"
#include "family_templates.hpp"
#include "entity_factory.hpp"
#include "entity_variable_activation.hpp"
#include "entity_variable_read.hpp"
#include "entity_struct.hpp"
#include "variable_struct.hpp"
#include "code/ylikuutio/data/any_value.hpp"

// Include standard headers
#include <cstddef>       // std::size_t
#include <regex>         // std::regex, std::regex_match
#include <string>        // std::string

namespace yli::ontology
{
    class Scene;

    void Entity::bind_variable(yli::ontology::Variable* const variable)
    {
        if (variable != nullptr)
        {
            this->parent_of_variables.bind_child(variable);

            // `variable` with a local name needs to be added to `entity_map` as well.
            this->add_entity(variable->get_local_name(), variable);
        }
    }

    void Entity::unbind_variable(const std::size_t childID)
    {
        this->parent_of_variables.unbind_child(childID);
    }

    void Entity::bind_to_universe()
    {
        // Requirements:
        // `this->universe` must not be `nullptr`.
        yli::ontology::Universe* const universe = this->universe;

        if (universe == nullptr)
        {
            // When `Application` is created, `universe` is still `nullptr`.
            return;
        }

        // Get `entityID` from the `Universe` and set pointer to this `Entity`.
        universe->bind_entity(this);
    }

    void Entity::bind_to_new_parent(yli::ontology::Entity* /* new_parent */)
    {
        // Do nothing.
        // `yli::ontology` classes which support binding must `override`
        // this `yli::ontology::Entity` base class implementation.
    }

    Entity::Entity(yli::ontology::Universe* const universe, const yli::ontology::EntityStruct& entity_struct)
        : registry(),
        parent_of_variables(this, &this->registry, ""), // Do not index `parent_of_variables`, index only the variables.
        parent_of_any_struct_entities(this, &this->registry, "any_struct_entities"),
        universe { universe },
        is_variable { entity_struct.is_variable }
    {
        // constructor.

        // Get `entityID` from `Universe` and set pointer to this `Entity`.
        this->bind_to_universe();

        if (!this->is_variable && this->universe != nullptr && this->universe != this)
        {
            this->should_be_rendered = !this->universe->get_is_headless();

            yli::ontology::VariableStruct should_be_rendered_variable_struct;
            should_be_rendered_variable_struct.local_name = "should_be_rendered";
            should_be_rendered_variable_struct.activate_callback = &yli::ontology::activate_should_be_rendered;
            should_be_rendered_variable_struct.read_callback = &yli::ontology::read_should_be_rendered;
            should_be_rendered_variable_struct.should_call_activate_callback_now = true;
            this->create_variable(should_be_rendered_variable_struct, yli::data::AnyValue(this->should_be_rendered));
        }
    }

    Entity::~Entity()
    {
        // destructor.

        if (this->universe == nullptr)
        {
            // When leaving the `main` before binding `Application` to `Universe`,
            // `this->universe` is still `nullptr`.
            return;
        }

        this->universe->unbind_entity(this->entityID);

        if (!this->global_name.empty() && this->universe != nullptr)
        {
            // OK, this `Entity` had a global name, so it's global name shall be erased.
            this->universe->erase_entity(this->global_name);
        }

        // Local names must be erased in the destructors
        // of classes that inherit `yli::ontology::Entity`!
        // They can not be erased here in `Entity` destructor,
        // because `Entity` class does not keep track of the
        // parent. `Entity` only provides virtual function
        // `Entity::get_parent`, but that can not be called
        // from here.
    }

    void Entity::activate()
    {
    }

    std::size_t Entity::get_childID() const
    {
        return this->childID;
    }

    std::string Entity::get_type() const
    {
        return this->type_string;
    }

    bool Entity::get_can_be_erased() const
    {
        return this->can_be_erased;
    }

    yli::ontology::Universe* Entity::get_universe() const
    {
        return this->universe;
    }

    yli::ontology::EntityFactory* Entity::get_entity_factory() const
    {
        if (this->universe == nullptr)
        {
            return nullptr;
        }

        return this->universe->get_entity_factory();
    }

    bool Entity::has_child(const std::string& name) const
    {
        return this->registry.is_entity(name);
    }

    yli::ontology::Entity* Entity::get_entity(const std::string& name) const
    {
        // Requirements:
        // `name` must not be empty.
        // `name` must not begin with a dot.
        // `name` must not end with a dot.
        std::size_t first_dot_pos = name.find_first_of('.');

        if (first_dot_pos == std::string::npos)
        {
            // There are no dots in the name.

            if (!this->registry.is_entity(name))
            {
                return nullptr;
            }

            return this->registry.get_entity(name);
        }

        // OK, assumedly we have a multi-part name.

        const std::string first = std::string(name, 0, first_dot_pos);
        const std::string rest = std::string(name, ++first_dot_pos);

        if (first.empty())
        {
            // Name must not be empty.
            return nullptr;
        }

        if (!this->registry.is_entity(first))
        {
            return nullptr;
        }

        yli::ontology::Entity* entity = this->registry.get_entity(first);

        if (entity == nullptr)
        {
            return nullptr;
        }

        return entity->get_entity(rest);
    }

    std::string Entity::get_entity_names() const
    {
        return this->registry.get_entity_names();
    }

    void Entity::add_entity(const std::string& name, yli::ontology::Entity* const entity)
    {
        this->registry.add_entity(entity, name);
    }

    void Entity::erase_entity(const std::string& name)
    {
        this->registry.erase_entity(name);
    }

    void Entity::create_variable(const yli::ontology::VariableStruct& variable_struct, const yli::data::AnyValue& any_value)
    {
        if (this->universe == nullptr)
        {
            return;
        }

        yli::ontology::EntityFactory* const entity_factory = this->universe->get_entity_factory();

        if (entity_factory == nullptr)
        {
            return;
        }

        yli::ontology::VariableStruct new_variable_struct(variable_struct);
        new_variable_struct.parent = this;
        entity_factory->create_variable(new_variable_struct, any_value);
    }

    bool Entity::has_variable(const std::string& variable_name) const
    {
        return this->get(variable_name) != nullptr;
    }

    yli::ontology::Variable* Entity::get(const std::string& variable_name) const
    {
        return dynamic_cast<yli::ontology::Variable*>(this->registry.get_entity(variable_name));
    }

    bool Entity::set(const std::string& variable_name, const yli::data::AnyValue& variable_new_any_value)
    {
        yli::ontology::Variable* const variable = this->get(variable_name);

        if (variable == nullptr)
        {
            return false;
        }

        // OK, this is a valid variable name.
        // Set the variable value and activate it by
        // calling the corresponding activate callback.

        variable->set(variable_new_any_value);
        return true;
    }

    std::string Entity::help() const
    {
        std::string help_string = "TODO: create general helptext";
        return help_string;
    }

    std::string Entity::help(const std::string& variable_name) const
    {
        yli::ontology::Variable* const variable = this->get(variable_name);

        if (variable == nullptr)
        {
            return this->help();
        }

        return variable->help();
    }

    void Entity::prerender() const
    {
        // Requirements:
        // `this->prerender_callback` must not be `nullptr`.
        // `this->universe` must not be `nullptr`.

        if (this->prerender_callback != nullptr &&
                this->universe != nullptr)
        {
            this->prerender_callback(this->universe);
        }
    }

    void Entity::postrender() const
    {
        // Requirements:
        // `this->postrender_callback` must not be `nullptr`.
        // `this->universe` must not be `nullptr`.

        if (this->postrender_callback != nullptr &&
                this->universe != nullptr)
        {
            this->postrender_callback(this->universe);
        }
    }

    std::string Entity::get_global_name() const
    {
        return this->global_name;
    }

    std::size_t Entity::get_number_of_all_children() const
    {
        return this->parent_of_variables.get_number_of_children() +
            this->get_number_of_non_variable_children();
    }

    std::size_t Entity::get_number_of_all_descendants() const
    {
        return yli::ontology::get_number_of_descendants(this->parent_of_variables.child_pointer_vector) +
            yli::ontology::get_number_of_descendants(this->parent_of_any_struct_entities.child_pointer_vector) +
            this->get_number_of_descendants();
    }

    std::size_t Entity::get_number_of_variables() const
    {
        return this->parent_of_variables.get_number_of_children();
    }

    std::size_t Entity::get_number_of_non_variable_children() const
    {
        return this->parent_of_any_struct_entities.get_number_of_children() +
            this->get_number_of_children();
    }

    std::string Entity::get_local_name() const
    {
        return this->local_name;
    }

    void Entity::set_global_name(const std::string& global_name)
    {
        // Requirements:
        // `this->universe` must not be `nullptr`.
        // `global_name` must not be already in use.

        if (global_name.empty())
        {
            return;
        }

        if (!std::regex_match(global_name, std::regex("[a-zA-Z][a-zA-Z0-9_-]*")))
        {
            return;
        }

        if (this->universe == nullptr)
        {
            return;
        }

        if (this->universe->has_child(global_name))
        {
            // The global name is already in use.
            return;
        }

        // Erase old global name.
        this->universe->erase_entity(this->global_name);

        // Set new global name.
        this->global_name = global_name;
        this->universe->add_entity(global_name, this);

        if (this->universe == this->get_parent())
        {
            // `Universe` is the parent of this `Entity`.
            // Therefore, local name and global name
            // are the same for this `Entity`.
            this->local_name = global_name;
        }
    }

    void Entity::set_local_name(const std::string& local_name)
    {
        if (local_name.empty())
        {
            return;
        }

        if (!std::regex_match(local_name, std::regex("[a-zA-Z][a-zA-Z0-9_-]*")))
        {
            return;
        }

        yli::ontology::Entity* const parent = this->get_parent();

        if (parent == nullptr)
        {
            return;
        }

        if (parent->has_child(local_name))
        {
            // The name is in use.
            return;
        }

        // Erase old local name.
        parent->erase_entity(this->local_name);

        // Set new local name.
        parent->add_entity(local_name, this);
        this->local_name = local_name;

        if (parent == this->universe)
        {
            // Special case: this `Entity` is a child of the `Universe`!
            // Therefore, the local name is also the global name,
            // and vice versa. This means that the requested
            // global name must not be in use.
            this->global_name = local_name;
        }
    }
}
<commit_msg>`Entity::get_entity`: check if name is empty or begins or ends with `.`<commit_after>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2022 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "entity.hpp"
#include "variable.hpp"
#include "universe.hpp"
#include "family_templates.hpp"
#include "entity_factory.hpp"
#include "entity_variable_activation.hpp"
#include "entity_variable_read.hpp"
#include "entity_struct.hpp"
#include "variable_struct.hpp"
#include "code/ylikuutio/data/any_value.hpp"

// Include standard headers
#include <cstddef>       // std::size_t
#include <regex>         // std::regex, std::regex_match
#include <string>        // std::string

namespace yli::ontology
{
    class Scene;

    void Entity::bind_variable(yli::ontology::Variable* const variable)
    {
        if (variable != nullptr)
        {
            this->parent_of_variables.bind_child(variable);

            // `variable` with a local name needs to be added to `entity_map` as well.
            this->add_entity(variable->get_local_name(), variable);
        }
    }

    void Entity::unbind_variable(const std::size_t childID)
    {
        this->parent_of_variables.unbind_child(childID);
    }

    void Entity::bind_to_universe()
    {
        // Requirements:
        // `this->universe` must not be `nullptr`.
        yli::ontology::Universe* const universe = this->universe;

        if (universe == nullptr)
        {
            // When `Application` is created, `universe` is still `nullptr`.
            return;
        }

        // Get `entityID` from the `Universe` and set pointer to this `Entity`.
        universe->bind_entity(this);
    }

    void Entity::bind_to_new_parent(yli::ontology::Entity* /* new_parent */)
    {
        // Do nothing.
        // `yli::ontology` classes which support binding must `override`
        // this `yli::ontology::Entity` base class implementation.
    }

    Entity::Entity(yli::ontology::Universe* const universe, const yli::ontology::EntityStruct& entity_struct)
        : registry(),
        parent_of_variables(this, &this->registry, ""), // Do not index `parent_of_variables`, index only the variables.
        parent_of_any_struct_entities(this, &this->registry, "any_struct_entities"),
        universe { universe },
        is_variable { entity_struct.is_variable }
    {
        // constructor.

        // Get `entityID` from `Universe` and set pointer to this `Entity`.
        this->bind_to_universe();

        if (!this->is_variable && this->universe != nullptr && this->universe != this)
        {
            this->should_be_rendered = !this->universe->get_is_headless();

            yli::ontology::VariableStruct should_be_rendered_variable_struct;
            should_be_rendered_variable_struct.local_name = "should_be_rendered";
            should_be_rendered_variable_struct.activate_callback = &yli::ontology::activate_should_be_rendered;
            should_be_rendered_variable_struct.read_callback = &yli::ontology::read_should_be_rendered;
            should_be_rendered_variable_struct.should_call_activate_callback_now = true;
            this->create_variable(should_be_rendered_variable_struct, yli::data::AnyValue(this->should_be_rendered));
        }
    }

    Entity::~Entity()
    {
        // destructor.

        if (this->universe == nullptr)
        {
            // When leaving the `main` before binding `Application` to `Universe`,
            // `this->universe` is still `nullptr`.
            return;
        }

        this->universe->unbind_entity(this->entityID);

        if (!this->global_name.empty() && this->universe != nullptr)
        {
            // OK, this `Entity` had a global name, so it's global name shall be erased.
            this->universe->erase_entity(this->global_name);
        }

        // Local names must be erased in the destructors
        // of classes that inherit `yli::ontology::Entity`!
        // They can not be erased here in `Entity` destructor,
        // because `Entity` class does not keep track of the
        // parent. `Entity` only provides virtual function
        // `Entity::get_parent`, but that can not be called
        // from here.
    }

    void Entity::activate()
    {
    }

    std::size_t Entity::get_childID() const
    {
        return this->childID;
    }

    std::string Entity::get_type() const
    {
        return this->type_string;
    }

    bool Entity::get_can_be_erased() const
    {
        return this->can_be_erased;
    }

    yli::ontology::Universe* Entity::get_universe() const
    {
        return this->universe;
    }

    yli::ontology::EntityFactory* Entity::get_entity_factory() const
    {
        if (this->universe == nullptr)
        {
            return nullptr;
        }

        return this->universe->get_entity_factory();
    }

    bool Entity::has_child(const std::string& name) const
    {
        return this->registry.is_entity(name);
    }

    yli::ontology::Entity* Entity::get_entity(const std::string& name) const
    {
        // Requirements:
        // `name` must not be empty.
        // `name` must not begin with a dot.
        // `name` must not end with a dot.

        if (name.empty() || name.front() == '.' || name.back() == '.')
        {
            return nullptr;
        }

        std::size_t first_dot_pos = name.find_first_of('.');

        if (first_dot_pos == std::string::npos)
        {
            // There are no dots in the name.

            if (!this->registry.is_entity(name))
            {
                return nullptr;
            }

            return this->registry.get_entity(name);
        }

        // OK, assumedly we have a multi-part name.

        const std::string first = std::string(name, 0, first_dot_pos);
        const std::string rest = std::string(name, ++first_dot_pos);

        if (first.empty())
        {
            // Name must not be empty.
            return nullptr;
        }

        if (!this->registry.is_entity(first))
        {
            return nullptr;
        }

        yli::ontology::Entity* entity = this->registry.get_entity(first);

        if (entity == nullptr)
        {
            return nullptr;
        }

        return entity->get_entity(rest);
    }

    std::string Entity::get_entity_names() const
    {
        return this->registry.get_entity_names();
    }

    void Entity::add_entity(const std::string& name, yli::ontology::Entity* const entity)
    {
        this->registry.add_entity(entity, name);
    }

    void Entity::erase_entity(const std::string& name)
    {
        this->registry.erase_entity(name);
    }

    void Entity::create_variable(const yli::ontology::VariableStruct& variable_struct, const yli::data::AnyValue& any_value)
    {
        if (this->universe == nullptr)
        {
            return;
        }

        yli::ontology::EntityFactory* const entity_factory = this->universe->get_entity_factory();

        if (entity_factory == nullptr)
        {
            return;
        }

        yli::ontology::VariableStruct new_variable_struct(variable_struct);
        new_variable_struct.parent = this;
        entity_factory->create_variable(new_variable_struct, any_value);
    }

    bool Entity::has_variable(const std::string& variable_name) const
    {
        return this->get(variable_name) != nullptr;
    }

    yli::ontology::Variable* Entity::get(const std::string& variable_name) const
    {
        return dynamic_cast<yli::ontology::Variable*>(this->registry.get_entity(variable_name));
    }

    bool Entity::set(const std::string& variable_name, const yli::data::AnyValue& variable_new_any_value)
    {
        yli::ontology::Variable* const variable = this->get(variable_name);

        if (variable == nullptr)
        {
            return false;
        }

        // OK, this is a valid variable name.
        // Set the variable value and activate it by
        // calling the corresponding activate callback.

        variable->set(variable_new_any_value);
        return true;
    }

    std::string Entity::help() const
    {
        std::string help_string = "TODO: create general helptext";
        return help_string;
    }

    std::string Entity::help(const std::string& variable_name) const
    {
        yli::ontology::Variable* const variable = this->get(variable_name);

        if (variable == nullptr)
        {
            return this->help();
        }

        return variable->help();
    }

    void Entity::prerender() const
    {
        // Requirements:
        // `this->prerender_callback` must not be `nullptr`.
        // `this->universe` must not be `nullptr`.

        if (this->prerender_callback != nullptr &&
                this->universe != nullptr)
        {
            this->prerender_callback(this->universe);
        }
    }

    void Entity::postrender() const
    {
        // Requirements:
        // `this->postrender_callback` must not be `nullptr`.
        // `this->universe` must not be `nullptr`.

        if (this->postrender_callback != nullptr &&
                this->universe != nullptr)
        {
            this->postrender_callback(this->universe);
        }
    }

    std::string Entity::get_global_name() const
    {
        return this->global_name;
    }

    std::size_t Entity::get_number_of_all_children() const
    {
        return this->parent_of_variables.get_number_of_children() +
            this->get_number_of_non_variable_children();
    }

    std::size_t Entity::get_number_of_all_descendants() const
    {
        return yli::ontology::get_number_of_descendants(this->parent_of_variables.child_pointer_vector) +
            yli::ontology::get_number_of_descendants(this->parent_of_any_struct_entities.child_pointer_vector) +
            this->get_number_of_descendants();
    }

    std::size_t Entity::get_number_of_variables() const
    {
        return this->parent_of_variables.get_number_of_children();
    }

    std::size_t Entity::get_number_of_non_variable_children() const
    {
        return this->parent_of_any_struct_entities.get_number_of_children() +
            this->get_number_of_children();
    }

    std::string Entity::get_local_name() const
    {
        return this->local_name;
    }

    void Entity::set_global_name(const std::string& global_name)
    {
        // Requirements:
        // `this->universe` must not be `nullptr`.
        // `global_name` must not be already in use.

        if (global_name.empty())
        {
            return;
        }

        if (!std::regex_match(global_name, std::regex("[a-zA-Z][a-zA-Z0-9_-]*")))
        {
            return;
        }

        if (this->universe == nullptr)
        {
            return;
        }

        if (this->universe->has_child(global_name))
        {
            // The global name is already in use.
            return;
        }

        // Erase old global name.
        this->universe->erase_entity(this->global_name);

        // Set new global name.
        this->global_name = global_name;
        this->universe->add_entity(global_name, this);

        if (this->universe == this->get_parent())
        {
            // `Universe` is the parent of this `Entity`.
            // Therefore, local name and global name
            // are the same for this `Entity`.
            this->local_name = global_name;
        }
    }

    void Entity::set_local_name(const std::string& local_name)
    {
        if (local_name.empty())
        {
            return;
        }

        if (!std::regex_match(local_name, std::regex("[a-zA-Z][a-zA-Z0-9_-]*")))
        {
            return;
        }

        yli::ontology::Entity* const parent = this->get_parent();

        if (parent == nullptr)
        {
            return;
        }

        if (parent->has_child(local_name))
        {
            // The name is in use.
            return;
        }

        // Erase old local name.
        parent->erase_entity(this->local_name);

        // Set new local name.
        parent->add_entity(local_name, this);
        this->local_name = local_name;

        if (parent == this->universe)
        {
            // Special case: this `Entity` is a child of the `Universe`!
            // Therefore, the local name is also the global name,
            // and vice versa. This means that the requested
            // global name must not be in use.
            this->global_name = local_name;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add new QuatTraits unit tests<commit_after><|endoftext|>


<commit_before>#if 1

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
#include <assert.h>
#include <windows.h>
#include <vector>

#include "graphics.h"
#include "sound.h"

#if _DEBUG
#pragma comment(lib, "Effekseer.Debug.lib" )
#else
#pragma comment(lib, "Effekseer.Release.lib" )
#endif

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
#define __DicrectX9	1
#define __OpenGL	0

#define __NormalMode 1
#define __PerformanceCheckMode 0

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Loop();
void Init();
void PlayEffect();

static HWND g_window_handle = NULL;
static int g_window_width = 800;
static int g_window_height = 600;

::Effekseer::Manager*					g_manager = NULL;
static ::Effekseer::Handle				g_handle = -1;
static ::Effekseer::Vector3D			g_position;
static ::Effekseer::Vector3D			g_focus;

static std::vector < ::Effekseer::Effect *>	g_effects;

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_LBUTTONDOWN:
			PlayEffect();
			break;
		default:
			return DefWindowProc(hWnd, msg, wParam, lParam);
	}
	return 0;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void InitWindow()
{
	WNDCLASS wndClass;
	wchar_t szClassNme[]      =  L"Effekseer";
	wndClass.style         = CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc   = WndProc;
	wndClass.cbClsExtra    = 0;
	wndClass.cbWndExtra    = 0;
	wndClass.hInstance     = GetModuleHandle(0);
	wndClass.hIcon         = NULL;
	wndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName  = NULL;
	wndClass.lpszClassName = szClassNme;
	RegisterClass(&wndClass);
	g_window_handle = CreateWindow(
		szClassNme,
		L"Effekseer Test Program (NbNƍĐ)",
		WS_SYSMENU,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		g_window_width,
		g_window_height,
		NULL,
		NULL,
		GetModuleHandle(0),
		NULL);
	ShowWindow( g_window_handle, true );
	UpdateWindow( g_window_handle );
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void MainLoop()
{
	for(;;)
	{
		MSG msg;
		if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE))
		{
			if( msg.message == WM_QUIT )
			{
				return ;
			}
			GetMessage (&msg,NULL,0,0);
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Loop();

			static int count = 0;

			//if (count < 50)
			{
				g_manager->Update();
			}

			count++;

			Rendering();
		}
	}
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
int main()
{
	InitWindow();

	g_manager = ::Effekseer::Manager::Create( 2000 );

	InitGraphics( g_window_handle, g_window_width, g_window_height );

	InitSound( g_window_handle );

	Init();

	MainLoop();

	g_manager->Destroy();

	for (size_t i = 0; i < g_effects.size(); i++)
	{
		ES_SAFE_RELEASE(g_effects[i]);
	}

	TermSound();

	TermGraphics();

	return 0;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Init()
{
	g_position = ::Effekseer::Vector3D( 10.0f, 5.0f, 10.0f );
	g_focus = ::Effekseer::Vector3D( 0.0f, 0.0f, 0.0f );

	SetCameraMatrix( ::Effekseer::Matrix44().LookAtRH( g_position, g_focus, ::Effekseer::Vector3D( 0.0f, 1.0f, 0.0f ) ) );

	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Laser01.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Laser02.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ribbon_Parent.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ribbon_Sword.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ring_Shape1.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ring_Shape2.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Sprite_FixedYAxis.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Track1.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"block.efk" ) );

	PlayEffect();
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Loop()
{
#if __NormalMode
	//g_manager->AddLocation( g_handle, ::Effekseer::Vector3D( 0.2f, 0.0f, 0.0f ) );
#endif

#if __PerformanceCheckMode
	static int count = 0;

	if( count % 10 == 1 && count < 100 )
	{
		auto updateTime = g_manager->GetUpdateTime();
		auto drawTime = g_manager->GetDrawTime();

		printf("UpdateTime %d, DrawTime %d\n", updateTime, drawTime );
	}

	count++;
#endif
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void PlayEffect()
{
#if __NormalMode
	static int target = 0;
	target = target % g_effects.size();
	g_handle = g_manager->Play( g_effects[target], 0, 0, 0 );
	target++;
	//g_manager->SetLocation( g_handle, -5.0f, 0.0f, -20.0f );

	::Effekseer::Matrix43 baseMat;
	baseMat.Scaling( 1.0f, 1.0f, 1.0f );
	g_manager->SetBaseMatrix( g_handle, baseMat );
#endif

#if __PerformanceCheckMode

	for( float y = -10.0f; y <= 10.0f; y += 2.0f )
	{
		for( float x = -10.0f; x <= 10.0f; x += 2.0f )
		{
			auto handle = g_manager->Play( g_effect, x, y, 0 );
			//g_manager->SetShown( handle, false );
		}
	}
	//g_manager->Play( g_effect, 0, 0, 0 );
#endif
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------

#endif<commit_msg>マルチバイトとUnicodeの影響を受ける部分を修正<commit_after>#if 1

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
#include <assert.h>
#include <windows.h>
#include <vector>

#include "graphics.h"
#include "sound.h"

#if _DEBUG
#pragma comment(lib, "Effekseer.Debug.lib" )
#else
#pragma comment(lib, "Effekseer.Release.lib" )
#endif

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
#define __DicrectX9	1
#define __OpenGL	0

#define __NormalMode 1
#define __PerformanceCheckMode 0

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Loop();
void Init();
void PlayEffect();

static HWND g_window_handle = NULL;
static int g_window_width = 800;
static int g_window_height = 600;

::Effekseer::Manager*					g_manager = NULL;
static ::Effekseer::Handle				g_handle = -1;
static ::Effekseer::Vector3D			g_position;
static ::Effekseer::Vector3D			g_focus;

static std::vector < ::Effekseer::Effect *>	g_effects;

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_LBUTTONDOWN:
			PlayEffect();
			break;
		default:
			return DefWindowProc(hWnd, msg, wParam, lParam);
	}
	return 0;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void InitWindow()
{
	WNDCLASSW wndClass;
	wchar_t szClassNme[]      =  L"Effekseer";
	wndClass.style         = CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc   = WndProc;
	wndClass.cbClsExtra    = 0;
	wndClass.cbWndExtra    = 0;
	wndClass.hInstance     = GetModuleHandle(0);
	wndClass.hIcon         = NULL;
	wndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName  = NULL;
	wndClass.lpszClassName = szClassNme;
	RegisterClassW(&wndClass);
	g_window_handle = CreateWindowW(
		szClassNme,
		L"Effekseer Test Program (NbNƍĐ)",
		WS_SYSMENU,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		g_window_width,
		g_window_height,
		NULL,
		NULL,
		GetModuleHandle(0),
		NULL);
	ShowWindow( g_window_handle, true );
	UpdateWindow( g_window_handle );
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void MainLoop()
{
	for(;;)
	{
		MSG msg;
		if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE))
		{
			if( msg.message == WM_QUIT )
			{
				return ;
			}
			GetMessage (&msg,NULL,0,0);
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Loop();

			static int count = 0;

			//if (count < 50)
			{
				g_manager->Update();
			}

			count++;

			Rendering();
		}
	}
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
int main()
{
	InitWindow();

	g_manager = ::Effekseer::Manager::Create( 2000 );

	InitGraphics( g_window_handle, g_window_width, g_window_height );

	InitSound( g_window_handle );

	Init();

	MainLoop();

	g_manager->Destroy();

	for (size_t i = 0; i < g_effects.size(); i++)
	{
		ES_SAFE_RELEASE(g_effects[i]);
	}

	TermSound();

	TermGraphics();

	return 0;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Init()
{
	g_position = ::Effekseer::Vector3D( 10.0f, 5.0f, 10.0f );
	g_focus = ::Effekseer::Vector3D( 0.0f, 0.0f, 0.0f );

	SetCameraMatrix( ::Effekseer::Matrix44().LookAtRH( g_position, g_focus, ::Effekseer::Vector3D( 0.0f, 1.0f, 0.0f ) ) );

	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Laser01.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Laser02.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ribbon_Parent.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ribbon_Sword.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ring_Shape1.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Ring_Shape2.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Sprite_FixedYAxis.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"Simple_Track1.efk" ) );
	g_effects.push_back( Effekseer::Effect::Create( g_manager, (const EFK_CHAR*)L"block.efk" ) );

	PlayEffect();
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void Loop()
{
#if __NormalMode
	//g_manager->AddLocation( g_handle, ::Effekseer::Vector3D( 0.2f, 0.0f, 0.0f ) );
#endif

#if __PerformanceCheckMode
	static int count = 0;

	if( count % 10 == 1 && count < 100 )
	{
		auto updateTime = g_manager->GetUpdateTime();
		auto drawTime = g_manager->GetDrawTime();

		printf("UpdateTime %d, DrawTime %d\n", updateTime, drawTime );
	}

	count++;
#endif
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void PlayEffect()
{
#if __NormalMode
	static int target = 0;
	target = target % g_effects.size();
	g_handle = g_manager->Play( g_effects[target], 0, 0, 0 );
	target++;
	//g_manager->SetLocation( g_handle, -5.0f, 0.0f, -20.0f );

	::Effekseer::Matrix43 baseMat;
	baseMat.Scaling( 1.0f, 1.0f, 1.0f );
	g_manager->SetBaseMatrix( g_handle, baseMat );
#endif

#if __PerformanceCheckMode

	for( float y = -10.0f; y <= 10.0f; y += 2.0f )
	{
		for( float x = -10.0f; x <= 10.0f; x += 2.0f )
		{
			auto handle = g_manager->Play( g_effect, x, y, 0 );
			//g_manager->SetShown( handle, false );
		}
	}
	//g_manager->Play( g_effect, 0, 0, 0 );
#endif
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------

#endif<|endoftext|>


<commit_before>#include "synapse.h"
#include "neuron.h"

Neuron::Neuron(float init_output_value, float init_threshold)
    : Soma(init_threshold)
{
    output_value = init_output_value;
}

void Neuron::add_synapse(Synapse& new_synapse)
{
    all_synapses.emplace_back(new_synapse);
}

void Neuron::set_output_value()
{
    float incoming_values = add_incoming_values();
    float activation_result = activate(incoming_values);
    output_value = activation_result;
}

float Neuron::get_output_value()
{
    return output_value;
}
<commit_msg>Update neuron.cpp<commit_after>#include "synapse.h"
#include "neuron.h"

Neuron::Neuron(float init_output_value, float init_threshold)
    : Soma(init_threshold), output_value(init_output_value)
{
}

void Neuron::add_synapse(Synapse& new_synapse)
{
    all_synapses.emplace_back(new_synapse);
}

void Neuron::set_output_value()
{
    float incoming_values = add_incoming_values();
    float activation_result = activate(incoming_values);
    output_value = activation_result;
}

float Neuron::get_output_value()
{
    return output_value;
}
<|endoftext|>


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

extern "C" {
    static void* launch_dispatcher_thread(void* arg);
}

static void* launch_dispatcher_thread(void *arg) {
    Dispatcher *dispatcher = (Dispatcher*) arg;
    try {
        dispatcher->run();
    } catch (std::exception& e) {
        getLogger()->log(EXTENSION_LOG_WARNING, NULL, "dispatcher exception caught: %s\n",
                         e.what());
    } catch(...) {
        getLogger()->log(EXTENSION_LOG_WARNING, NULL,
                         "Caught a fatal exception in the dispatcher thread\n");
    }
    return NULL;
}

void Dispatcher::start() {
    assert(state == dispatcher_running);
    if(pthread_create(&thread, NULL, launch_dispatcher_thread, this) != 0) {
        throw std::runtime_error("Error initializing dispatcher thread");
    }
}

void Dispatcher::run() {
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher starting\n");
    while (state == dispatcher_running) {
        LockHolder lh(mutex);
        if (queue.empty()) {
            // Wait forever as long as the state didn't change while
            // we grabbed the lock.
            if (state == dispatcher_running) {
                mutex.wait();
            }
        } else {
            TaskId task = queue.top();
            assert(task);
            LockHolder tlh(task->mutex);
            switch (task->state) {
            case task_sleeping:
                {
                    struct timeval tv;
                    gettimeofday(&tv, NULL);
                    if (less_tv(tv, task->waketime)) {
                        tlh.unlock();
                        mutex.wait(task->waketime);
                    } else {
                        task->state = task_running;
                    }
                }
                break;
            case task_running:
                queue.pop();
                lh.unlock();
                tlh.unlock();
                try {
                    if(task->run(*this, TaskId(task))) {
                        reschedule(task);
                    }
                } catch (std::exception& e) {
                    getLogger()->log(EXTENSION_LOG_WARNING, NULL, "exception caught in task %s: %s\n", task->name.c_str(),
                                     e.what());
                } catch(...) {
                    getLogger()->log(EXTENSION_LOG_WARNING, NULL, "fatal exception caught in task %s\n", task->name.c_str());
                }
                break;
            case task_dead:
                queue.pop();
                break;
            default:
                throw std::runtime_error("Unexpected state for task");
            }
        }
    }

    state = dispatcher_stopped;
    mutex.notify();
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher exited\n");
}

void Dispatcher::stop() {
    LockHolder lh(mutex);
    if (state == dispatcher_stopped || state == dispatcher_stopping) {
        return;
    }
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Stopping dispatcher\n");
    state = dispatcher_stopping;
    mutex.notify();
    lh.unlock();
    pthread_join(thread, NULL);
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher stopped\n");
}

void Dispatcher::schedule(shared_ptr<DispatcherCallback> callback,
                          TaskId *outtid,
                          const Priority &priority, double sleeptime) {
    LockHolder lh(mutex);
    TaskId task(new Task(callback, priority.getPriorityValue(), sleeptime));
    if (outtid) {
        *outtid = TaskId(task);
    }
    queue.push(task);
    mutex.notify();
}

void Dispatcher::wake(TaskId task, TaskId *outtid) {
    cancel(task);
    LockHolder lh(mutex);
    TaskId oldTask(task);
    TaskId newTask(new Task(*oldTask));
    if (outtid) {
        *outtid = TaskId(task);
    }
    queue.push(newTask);
    mutex.notify();
}
<commit_msg>Minor formatting changes.<commit_after>/*
 *     Copyright 2010 NorthScale, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include "config.h"
#include "dispatcher.hh"

extern "C" {
    static void* launch_dispatcher_thread(void* arg);
}

static void* launch_dispatcher_thread(void *arg) {
    Dispatcher *dispatcher = (Dispatcher*) arg;
    try {
        dispatcher->run();
    } catch (std::exception& e) {
        getLogger()->log(EXTENSION_LOG_WARNING, NULL,
                         "dispatcher exception caught: %s\n", e.what());
    } catch(...) {
        getLogger()->log(EXTENSION_LOG_WARNING, NULL,
                         "Caught a fatal exception in the dispatcher thread\n");
    }
    return NULL;
}

void Dispatcher::start() {
    assert(state == dispatcher_running);
    if(pthread_create(&thread, NULL, launch_dispatcher_thread, this) != 0) {
        throw std::runtime_error("Error initializing dispatcher thread");
    }
}

void Dispatcher::run() {
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher starting\n");
    while (state == dispatcher_running) {
        LockHolder lh(mutex);
        if (queue.empty()) {
            // Wait forever as long as the state didn't change while
            // we grabbed the lock.
            if (state == dispatcher_running) {
                mutex.wait();
            }
        } else {
            TaskId task = queue.top();
            assert(task);
            LockHolder tlh(task->mutex);
            switch (task->state) {
            case task_sleeping:
                {
                    struct timeval tv;
                    gettimeofday(&tv, NULL);
                    if (less_tv(tv, task->waketime)) {
                        tlh.unlock();
                        mutex.wait(task->waketime);
                    } else {
                        task->state = task_running;
                    }
                }
                break;
            case task_running:
                queue.pop();
                lh.unlock();
                tlh.unlock();
                try {
                    if(task->run(*this, TaskId(task))) {
                        reschedule(task);
                    }
                } catch (std::exception& e) {
                    getLogger()->log(EXTENSION_LOG_WARNING, NULL,
                                     "exception caught in task %s: %s\n",
                                     task->name.c_str(), e.what());
                } catch(...) {
                    getLogger()->log(EXTENSION_LOG_WARNING, NULL,
                                     "fatal exception caught in task %s\n",
                                     task->name.c_str());
                }
                break;
            case task_dead:
                queue.pop();
                break;
            default:
                throw std::runtime_error("Unexpected state for task");
            }
        }
    }

    state = dispatcher_stopped;
    mutex.notify();
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher exited\n");
}

void Dispatcher::stop() {
    LockHolder lh(mutex);
    if (state == dispatcher_stopped || state == dispatcher_stopping) {
        return;
    }
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Stopping dispatcher\n");
    state = dispatcher_stopping;
    mutex.notify();
    lh.unlock();
    pthread_join(thread, NULL);
    getLogger()->log(EXTENSION_LOG_DEBUG, NULL, "Dispatcher stopped\n");
}

void Dispatcher::schedule(shared_ptr<DispatcherCallback> callback,
                          TaskId *outtid,
                          const Priority &priority, double sleeptime) {
    LockHolder lh(mutex);
    TaskId task(new Task(callback, priority.getPriorityValue(), sleeptime));
    if (outtid) {
        *outtid = TaskId(task);
    }
    queue.push(task);
    mutex.notify();
}

void Dispatcher::wake(TaskId task, TaskId *outtid) {
    cancel(task);
    LockHolder lh(mutex);
    TaskId oldTask(task);
    TaskId newTask(new Task(*oldTask));
    if (outtid) {
        *outtid = TaskId(task);
    }
    queue.push(newTask);
    mutex.notify();
}
<|endoftext|>


<commit_before>/*
 * Exception.h
 *
 *  Created on: 08.03.2016
 *      Author: chaos
 */

#ifndef EXCEPTION_H_
#define EXCEPTION_H_

#include <ChaosCore/Exception.h>

namespace ca
{
	namespace gl
	{

		class Exception : public core::Exception
		{
		public:
			Exception(const char* message, int code, Exception* parent);
			Exception(const char* message, int code);
			Exception(const char* message);
			virtual ~Exception();
		};

	} /* namespace gl */
} /* namespace ca */

#endif /* EXCEPTION_H_ */
<commit_msg>[][Update] Renaming header macro<commit_after>/*
 * Exception.h
 *
 *  Created on: 08.03.2016
 *      Author: chaos
 */

#ifndef ChaosGL_Exception_h_
#define ChaosGL_Exception_h_

#include <ChaosCore/Exception.h>

namespace ca
{
	namespace gl
	{

		class Exception : public ca::core::Exception
		{
		public:
			Exception(const char* message, int code, Exception* parent);
			Exception(const char* message, int code);
			Exception(const char* message);
			virtual ~Exception();
		};

	} /* namespace gl */
} /* namespace ca */

#endif /* EXCEPTION_H_ */
<|endoftext|>


<commit_before>#include "MainScene.h"
#include "MainMenuLayer.h"
#include "BackgroundLayer.h"
#include "GameLayer.h"
USING_NS_CC;
#include "ElemsPreloadManager.h"

MainScene::MainScene()
	:_pSelfCamera(nullptr)
{
}

MainScene::~MainScene()
{
	CC_SAFE_RELEASE_NULL(_pSelfCamera);
}

// on "init" you need to initialize your instance
bool MainScene::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Scene::init() )
    {
        return false;
    }

	ElemsPreloadManager::registerMoveAbleElemTypes();

	Size winSize = Director::getInstance()->getWinSize();

	auto cameraBackground2D = Camera::createOrthographic(winSize.width, winSize.height, 0, 100);
	cameraBackground2D->setCameraFlag(CameraFlag::USER2);
	this->addChild(cameraBackground2D);
	cameraBackground2D->setDepth(-5);

	//todo ˳зʽ
	auto cameraMainUI = Camera::createOrthographic(winSize.width, winSize.height, 0, 100);
	cameraMainUI->setCameraFlag(CameraFlag::USER4);
	this->addChild(cameraMainUI);
	cameraMainUI->setDepth(5);

	auto camera3D = Camera::createPerspective(35, GLfloat(winSize.width) / GLfloat(winSize.height), 1, 1000);
	camera3D->setCameraFlag(CameraFlag::DEFAULT);
	camera3D->setPosition3D(Vec3(0, 15, 10));
	camera3D->lookAt(Vec3(0, 5, -60), Vec3(0, 1, 0));
	this->addChild(camera3D);

	//Զʹӽǣ̶λ
	auto pBgLayer = BackgroundLayer::create();
	this->addChild(pBgLayer, -20, "UI_Background");

	//˵棬ʹӽǣ̶λ
	auto pMenuLayer = MainMenuLayer::create();
	this->addChild(pMenuLayer, 20, "UI_MainMenu");

	//3D
	auto pGameLayer = GameLayer::create();
	this->addChild(pGameLayer, 0, "Game_Main");

	//ÿʹԼӽ
	pBgLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::USER2));

	pGameLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::DEFAULT));

	pMenuLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::USER4));

	//scheduleUpdate();

    return true;
}

//void MainScene::update(float dt)
//{
//
//}

<commit_msg>design the resolution ratio as 960*640;and set ResolutionPolicy as SHOW_ALL<commit_after>#include "MainScene.h"
#include "MainMenuLayer.h"
#include "BackgroundLayer.h"
#include "GameLayer.h"
USING_NS_CC;
#include "ElemsPreloadManager.h"

MainScene::MainScene()
	:_pSelfCamera(nullptr)
{
}

MainScene::~MainScene()
{
	CC_SAFE_RELEASE_NULL(_pSelfCamera);
}

// on "init" you need to initialize your instance
bool MainScene::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Scene::init() )
    {
        return false;
    }

	ElemsPreloadManager::registerMoveAbleElemTypes();

	auto glView = Director::getInstance()->getOpenGLView();

	Size designSize = Size(960, 640);

	glView->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::SHOW_ALL);

	auto cameraBackground2D = Camera::createOrthographic(designSize.width, designSize.height, 0, 100);
	cameraBackground2D->setCameraFlag(CameraFlag::USER2);
	this->addChild(cameraBackground2D);
	cameraBackground2D->setDepth(-5);

	//todo ˳зʽ
	auto cameraMainUI = Camera::createOrthographic(designSize.width, designSize.height, 0, 100);
	cameraMainUI->setCameraFlag(CameraFlag::USER4);
	this->addChild(cameraMainUI);
	cameraMainUI->setDepth(5);

	auto camera3D = Camera::createPerspective(35, GLfloat(designSize.width) / GLfloat(designSize.height), 1, 1000);
	camera3D->setCameraFlag(CameraFlag::DEFAULT);
	camera3D->setPosition3D(Vec3(0, 15, 10));
	camera3D->lookAt(Vec3(0, 5, -60), Vec3(0, 1, 0));
	this->addChild(camera3D);

	//Զʹӽǣ̶λ
	auto pBgLayer = BackgroundLayer::create();
	this->addChild(pBgLayer, -20, "UI_Background");

	//˵棬ʹӽǣ̶λ
	auto pMenuLayer = MainMenuLayer::create();
	this->addChild(pMenuLayer, 20, "UI_MainMenu");

	//3D
	auto pGameLayer = GameLayer::create();
	this->addChild(pGameLayer, 0, "Game_Main");

	//ÿʹԼӽ
	pBgLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::USER2));

	pGameLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::DEFAULT));

	pMenuLayer->setCameraMask(static_cast<unsigned short>(CameraFlag::USER4));

	//scheduleUpdate();

    return true;
}

//void MainScene::update(float dt)
//{
//
//}

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkIGTLMessageProvider.h"

#include "mitkIGTLDevice.h"
#include "mitkIGTLMessage.h"
#include "mitkIGTLMessageFactory.h"

#include "mitkCallbackFromGUIThread.h"

//Microservices
#include "usServiceReference.h"
#include "usModuleContext.h"
#include "usServiceEvent.h"
#include "mitkServiceInterface.h"
#include "usGetModuleContext.h"

//igt (remove this later)
#include "igtlBindMessage.h"
#include "igtlQuaternionTrackingDataMessage.h"
#include "igtlTrackingDataMessage.h"

#ifndef WIN32
#include <unistd.h>
#endif

mitk::IGTLMessageProvider::IGTLMessageProvider()
  : mitk::IGTLDeviceSource()
{
  this->SetName("IGTLMessageProvider");
  //m_MultiThreader = itk::MultiThreader::New();
  m_StreamingTimeMutex = itk::FastMutexLock::New();
  //m_StopStreamingThreadMutex = itk::FastMutexLock::New();
  //m_ThreadId = 0;
  m_IsStreaming = false;
}

mitk::IGTLMessageProvider::~IGTLMessageProvider()
{
  //// terminate worker thread on destruction
  //this->m_StopStreamingThreadMutex->Lock();
  //this->m_StopStreamingThread = true;
  //this->m_StopStreamingThreadMutex->Unlock();
  //if ( m_ThreadId >= 0)
  //{
  //  this->m_MultiThreader->TerminateThread(m_ThreadId);
  //}
   this->InvokeEvent(StreamingStartRequiredEvent());
}

void mitk::IGTLMessageProvider::Update()
{
   m_Measurement.AddMeasurement(1);
   Superclass::Update();
}

void mitk::IGTLMessageProvider::GenerateData()
{
  if (this->m_IGTLDevice.IsNull())
    return;

  m_Measurement.AddMeasurement(2);

  for (unsigned int index = 0; index < this->GetNumberOfIndexedInputs(); index++)
  {
    const IGTLMessage* msg = this->GetInput(index);
    if (msg == nullptr)
    {
       continue;
    }

    if ( !msg->IsDataValid() )
    {
      continue;
    }

    igtl::MessageBase::Pointer igtlMsg = msg->GetMessage();

    if ( igtlMsg.IsNotNull() )
    {
      //send the message
      this->m_IGTLDevice->SendMessage(igtlMsg);
    }
  }
}

void mitk::IGTLMessageProvider::CreateOutputs()
{
  //if outputs are set then delete them
  if (this->GetNumberOfOutputs() > 0)
  {
    for (int numOP = this->GetNumberOfOutputs() - 1; numOP >= 0; numOP--)
      this->RemoveOutput(numOP);
    this->Modified();
  }

  //fill the outputs if a valid OpenIGTLink device is set
  if (m_IGTLDevice.IsNull())
    return;

  this->SetNumberOfIndexedOutputs(1);
  if (this->GetOutput(0) == NULL)
  {
    DataObjectPointer newOutput = this->MakeOutput(0);
    this->SetNthOutput(0, newOutput);
    this->Modified();
  }
}

//void mitk::IGTLMessageProvider::UpdateOutputInformation()
//{
//  this->Modified();  // make sure that we need to be updated
//  Superclass::UpdateOutputInformation();
//}

void mitk::IGTLMessageProvider::OnIncomingMessage()
{

}

std::string RemoveRequestPrefixes(std::string requestType)
{
  return requestType.substr(4);
}

void mitk::IGTLMessageProvider::OnIncomingCommand()
{
  //get the next command
  igtl::MessageBase::Pointer curCommand = this->m_IGTLDevice->GetNextCommand();
  //extract the type
  const char * requestType = curCommand->GetDeviceType();
  //check the type
  std::string reqType(requestType);
  bool isGetMsg = !reqType.find("GET_");
  bool isSTTMsg = !reqType.find("STT_");
  bool isSTPMsg = !reqType.find("STP_");
  bool isRTSMsg = !reqType.find("RTS_");
  //get the type from the request type (remove STT_, STP_, GET_, RTS_)
  std::string type = RemoveRequestPrefixes(requestType);
  //check all microservices if there is a fitting source for the requested type
  mitk::IGTLMessageSource::Pointer source = this->GetFittingSource(type.c_str());
  //if there is no fitting source return a RTS message, if there is a RTS
  //type defined in the message factory send it
  if ( source.IsNull() )
  {
    if ( !this->GetIGTLDevice()->SendRTSMessage(type.c_str()) )
    {
      //sending RTS message failed, probably because the type is not in the
      //message factory
      MITK_WARN("IGTLMessageProvider") << "Tried to send a RTS message but did "
                                          "not succeed. Check if this type ( "
                                       << type << " ) was added to the message "
                                          "factory. ";
    }
  }
  else
  {
    if ( isGetMsg ) //if it is a single value push it into sending queue
    {
      //first it is necessary to update the source. This needs additional time
      //but is necessary. But are we really allowed to call this here? In which
      //thread are we? Is the source thread safe?
      source->Update();
      mitk::IGTLMessage::Pointer sourceOutput = source->GetOutput();
      if (sourceOutput.IsNotNull() && sourceOutput->IsDataValid())
      {
        igtl::MessageBase::Pointer sourceMsg = sourceOutput->GetMessage();
        if ( source.IsNotNull() )
        {
          this->GetIGTLDevice()->SendMessage(sourceMsg);
        }
      }
    }
    else if ( isSTTMsg )
    {
      //read the requested frames per second
      int fps = 10;

      //read the fps from the command
      igtl::MessageBase* curCommandPt = curCommand.GetPointer();
      if ( std::strcmp( curCommand->GetDeviceType(), "STT_BIND" ) == 0 )
      {
        fps = ((igtl::StartBindMessage*)curCommandPt)->GetResolution();
      }
      else if ( std::strcmp( curCommand->GetDeviceType(), "STT_QTDATA" ) == 0 )
      {
        fps = ((igtl::StartQuaternionTrackingDataMessage*)curCommandPt)->GetResolution();
      }
      else if ( std::strcmp( curCommand->GetDeviceType(), "STT_TDATA" ) == 0 )
      {
        fps = ((igtl::StartTrackingDataMessage*)curCommandPt)->GetResolution();
      }

      this->StartStreamingOfSource(source, fps);
    }
    else if ( isSTPMsg )
    {
      this->StopStreamingOfSource(source);
    }
    else
    {
      //do nothing
    }
  }
}

bool mitk::IGTLMessageProvider::IsStreaming()
{
  return m_IsStreaming;
}

void mitk::IGTLMessageProvider::StartStreamingOfSource(IGTLMessageSource* src,
                                                       unsigned int fps)
{
  if ( src == NULL )
    return;

  //so far the provider allows the streaming of a single source only
  //if the streaming thread is already running return a RTS message
  if ( !m_IsStreaming )
  {
    //if it is a stream establish a connection between the provider and the
    //source
    this->ConnectTo(src);

    // calculate the streaming time
    this->m_StreamingTimeMutex->Lock();
    this->m_StreamingTime = 1.0 / (double) fps * 1000.0;
    this->m_StreamingTimeMutex->Unlock();

    //// Create a command object. The function will be called later from the
    //// main thread
    this->m_StreamingCommand = ProviderCommand::New();
    m_StreamingCommand->SetCallbackFunction(this,
        &mitk::IGTLMessageProvider::InvokeStartStreamingEvent);

    //// For streaming we need a continues time signal, since there is no timer
    //// available we start a thread that generates a timing signal
    //// This signal is invoked from the other thread the update of the pipeline
    //// has to be executed from the main thread. Thus, we use the
    //// callbackfromGUIThread class to pass the execution to the main thread
    //this->m_ThreadId = m_MultiThreader->SpawnThread(this->TimerThread, this);

    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
          this->m_StreamingCommand);

    this->m_IsStreaming = true;
  }
  else
  {
    MITK_WARN("IGTLMessageProvider") << "This provider just supports the "
                                        "streaming of one source.";
  }
}

void mitk::IGTLMessageProvider::InvokeStartStreamingEvent()
{
  this->InvokeEvent(StreamingStartRequiredEvent());
}

void mitk::IGTLMessageProvider::InvokeStopStreamingEvent()
{
  this->InvokeEvent(StreamingStopRequiredEvent());
}

void mitk::IGTLMessageProvider::StopStreamingOfSource(IGTLMessageSource* src)
{
  //this is something bad!!! The streaming thread has to be stopped before the
  //source is disconnected otherwise it can cause a crash. This has to be added!!
  this->DisconnectFrom(src);

  //this->m_StopStreamingThreadMutex->Lock();
  //this->m_StopStreamingThread = true;
  //this->m_StopStreamingThreadMutex->Unlock();

  //// Create a command object. The function will be called later from the
  //// main thread
    this->m_StopStreamingCommand = ProviderCommand::New();
    m_StopStreamingCommand->SetCallbackFunction(this,
        &mitk::IGTLMessageProvider::InvokeStopStreamingEvent);

    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
          this->m_StopStreamingCommand);

  //does this flag needs a mutex???
  this->m_IsStreaming = false;
}

mitk::IGTLMessageSource::Pointer mitk::IGTLMessageProvider::GetFittingSource(const char* requestedType)
{
  //get the context
  us::ModuleContext* context = us::GetModuleContext();
  //define the interface name
  std::string interface = mitk::IGTLMessageSource::US_INTERFACE_NAME;
  //specify a filter that defines the requested type
  std::string filter = "(" + mitk::IGTLMessageSource::US_PROPKEY_DEVICETYPE +
      "=" + requestedType + ")";
  //find the fitting service
  std::vector<us::ServiceReferenceU> serviceReferences =
      context->GetServiceReferences(interface, filter);

  //check if a service reference was found. It is also possible that several
  //services were found. This is not checked here, just the first one is taken.
  if ( serviceReferences.size() )
  {
    mitk::IGTLMessageSource::Pointer curSource =
        context->GetService<mitk::IGTLMessageSource>(serviceReferences.front());

    if ( curSource.IsNotNull() )
      return curSource;
  }
  //no service reference was found or found service reference has no valid source
  return NULL;
}

void mitk::IGTLMessageProvider::Send(const mitk::IGTLMessage* msg)
{
  if (msg != NULL)
    this->m_IGTLDevice->SendMessage(msg);
}

void
mitk::IGTLMessageProvider::ConnectTo( mitk::IGTLMessageSource* UpstreamFilter )
{
  for (DataObjectPointerArraySizeType i = 0;
       i < UpstreamFilter->GetNumberOfOutputs(); i++)
  {
    this->SetInput(i, UpstreamFilter->GetOutput(i));
  }
}

void
mitk::IGTLMessageProvider::DisconnectFrom( mitk::IGTLMessageSource* UpstreamFilter )
{
  for (DataObjectPointerArraySizeType i = 0;
       i < UpstreamFilter->GetNumberOfOutputs(); i++)
  {
    this->RemoveInput(UpstreamFilter->GetOutput(i));
  }
}

//ITK_THREAD_RETURN_TYPE mitk::IGTLMessageProvider::TimerThread(void* pInfoStruct)
//{
//  // extract this pointer from thread info structure
//  struct itk::MultiThreader::ThreadInfoStruct * pInfo =
//      (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
//  mitk::IGTLMessageProvider* thisObject =
//      static_cast<mitk::IGTLMessageProvider*>(pInfo->UserData);
//
//  itk::SimpleMutexLock mutex;
//  mutex.Lock();
//
//  thisObject->m_StopStreamingThreadMutex->Lock();
//  thisObject->m_StopStreamingThread = false;
//  thisObject->m_StopStreamingThreadMutex->Unlock();
//
//  thisObject->m_StreamingTimeMutex->Lock();
//  unsigned int waitingTime = thisObject->m_StreamingTime;
//  thisObject->m_StreamingTimeMutex->Unlock();
//
//  while (true)
//  {
//    thisObject->m_StopStreamingThreadMutex->Lock();
//    bool stopThread = thisObject->m_StopStreamingThread;
//    thisObject->m_StopStreamingThreadMutex->Unlock();
//
//    if (stopThread)
//    {
//      break;
//    }
//
//    //wait for the time given
//    //I know it is not the nicest solution but we just need an approximate time
//    //sleeps for 20 ms
//    #if defined (WIN32) || defined (_WIN32)
//    Sleep(waitingTime);
//    #else
//    usleep(waitingTime * 1000);
//    #endif
//
//    // Ask to execute that command from the GUI thread
//    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
//          thisObject->m_StreamingCommand);
//  }
//
//  thisObject->m_ThreadId = 0;
//
//  mutex.Unlock();
//
//  return ITK_THREAD_RETURN_VALUE;
//}
<commit_msg>test precommit hook<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkIGTLMessageProvider.h"

#include "mitkIGTLDevice.h"
#include "mitkIGTLMessage.h"
#include "mitkIGTLMessageFactory.h"

#include "mitkCallbackFromGUIThread.h"

//Microservices
#include "usServiceReference.h"
#include "usModuleContext.h"
#include "usServiceEvent.h"
#include "mitkServiceInterface.h"
#include "usGetModuleContext.h"

//igt (remove this later)
#include "igtlBindMessage.h"
#include "igtlQuaternionTrackingDataMessage.h"
#include "igtlTrackingDataMessage.h"

#ifndef WIN32
#include <unistd.h>
#endif

mitk::IGTLMessageProvider::IGTLMessageProvider()
  : mitk::IGTLDeviceSource()
{
  this->SetName("IGTLMessageProvider");
  //m_MultiThreader = itk::MultiThreader::New();
  m_StreamingTimeMutex = itk::FastMutexLock::New();
  //m_StopStreamingThreadMutex = itk::FastMutexLock::New();
  //m_ThreadId = 0;
  m_IsStreaming = false;
}

mitk::IGTLMessageProvider::~IGTLMessageProvider()
{
  //// terminate worker thread on destruction
  //this->m_StopStreamingThreadMutex->Lock();
  //this->m_StopStreamingThread = true;
  //this->m_StopStreamingThreadMutex->Unlock();
  //if ( m_ThreadId >= 0)
  //{
  //  this->m_MultiThreader->TerminateThread(m_ThreadId);
  //}
   this->InvokeEvent(StreamingStartRequiredEvent());
}

void mitk::IGTLMessageProvider::Update()
{
   m_Measurement.AddMeasurement(1);
   Superclass::Update();
}

void mitk::IGTLMessageProvider::GenerateData()
{
  if (this->m_IGTLDevice.IsNull())
    return;

  m_Measurement.AddMeasurement(2);

  for (unsigned int index = 0; index < this->GetNumberOfIndexedInputs(); index++)
  {
    const IGTLMessage* msg = this->GetInput(index);
    if (msg == nullptr)
    {
       continue;
    }

    if ( !msg->IsDataValid() )
    {
      continue;
    }

    igtl::MessageBase::Pointer igtlMsg = msg->GetMessage();

    if ( igtlMsg.IsNotNull() )
    {
      //send the message
      this->m_IGTLDevice->SendMessage(igtlMsg);
    }
  }
}

void mitk::IGTLMessageProvider::CreateOutputs()
{
  //if outputs are set then delete them
  if (this->GetNumberOfOutputs() > 0)
  {
    for (int numOP = this->GetNumberOfOutputs() - 1; numOP >= 0; numOP--)
      this->RemoveOutput(numOP);
    this->Modified();
  }

  //fill the outputs if a valid OpenIGTLink device is set
  if (m_IGTLDevice.IsNull())
    return;

  this->SetNumberOfIndexedOutputs(1);
  if (this->GetOutput(0) == NULL)
  {
    DataObjectPointer newOutput = this->MakeOutput(0);
    this->SetNthOutput(0, newOutput);
    this->Modified();
  }
}

//void mitk::IGTLMessageProvider::UpdateOutputInformation()
//{
//  this->Modified();  // make sure that we need to be updated
//  Superclass::UpdateOutputInformation();
//}

void mitk::IGTLMessageProvider::OnIncomingMessage()
{

}

std::string RemoveRequestPrefixes(std::string requestType)
{
  return requestType.substr(4);
}

void mitk::IGTLMessageProvider::OnIncomingCommand()
{
  //get the next command
  igtl::MessageBase::Pointer curCommand = this->m_IGTLDevice->GetNextCommand();
  //extract the type
  const char * requestType = curCommand->GetDeviceType();
  //check the type
  std::string reqType(requestType);
  bool isGetMsg = !reqType.find("GET_");
  bool isSTTMsg = !reqType.find("STT_");
  bool isSTPMsg = !reqType.find("STP_");
  bool isRTSMsg = !reqType.find("RTS_");
  //get the type from the request type (remove STT_, STP_, GET_, RTS_)
  std::string type = RemoveRequestPrefixes(requestType);
  //check all microservices if there is a fitting source for the requested type
  mitk::IGTLMessageSource::Pointer source = this->GetFittingSource(type.c_str());
  //if there is no fitting source return a RTS message, if there is a RTS
  //type defined in the message factory send it
  if ( source.IsNull() )
  {
    if ( !this->GetIGTLDevice()->SendRTSMessage(type.c_str()) )
    {
      //sending RTS message failed, probably because the type is not in the
      //message factory
      MITK_WARN("IGTLMessageProvider") << "Tried to send a RTS message but did "
                                          "not succeed. Check if this type ( "
                                       << type << " ) was added to the message "
                                          "factory. ";
    }
  }
  else
  {
    if ( isGetMsg ) //if it is a single value push it into sending queue
    {
      //first it is necessary to update the source. This needs additional time
      //but is necessary. But are we really allowed to call this here? In which
      //thread are we? Is the source thread safe?
      source->Update();
      mitk::IGTLMessage::Pointer sourceOutput = source->GetOutput();
      if (sourceOutput.IsNotNull() && sourceOutput->IsDataValid())
      {
        igtl::MessageBase::Pointer sourceMsg = sourceOutput->GetMessage();
        if ( source.IsNotNull() )
        {
          this->GetIGTLDevice()->SendMessage(sourceMsg);
        }
      }
    }
    else if ( isSTTMsg )
    {
      //read the requested frames per second
      int fps = 10;

      //read the fps from the command
      igtl::MessageBase* curCommandPt = curCommand.GetPointer();
      if ( std::strcmp( curCommand->GetDeviceType(), "STT_BIND" ) == 0 )
      {
        fps = ((igtl::StartBindMessage*)curCommandPt)->GetResolution();
      }
      else if ( std::strcmp( curCommand->GetDeviceType(), "STT_QTDATA" ) == 0 )
      {
        fps = ((igtl::StartQuaternionTrackingDataMessage*)curCommandPt)->GetResolution();
      }
      else if ( std::strcmp( curCommand->GetDeviceType(), "STT_TDATA" ) == 0 )
      {
        fps = ((igtl::StartTrackingDataMessage*)curCommandPt)->GetResolution();
      }

      this->StartStreamingOfSource(source, fps);
    }
    else if ( isSTPMsg )
    {
      this->StopStreamingOfSource(source);
    }
    else
    {
      //do nothing
    }
  }
}

bool mitk::IGTLMessageProvider::IsStreaming()
{
  return m_IsStreaming;
}

void mitk::IGTLMessageProvider::StartStreamingOfSource(IGTLMessageSource* src,
                                                       unsigned int fps)
{
  if ( src == NULL )
    return;

  //so far the provider allows the streaming of a single source only
  //if the streaming thread is already running return a RTS message
  if ( !m_IsStreaming )
  {
    //if it is a stream establish a connection between the provider and the
    //source
    this->ConnectTo(src);

    // calculate the streaming time
    this->m_StreamingTimeMutex->Lock();
    this->m_StreamingTime = 1.0 / (double) fps * 1000.0;
    this->m_StreamingTimeMutex->Unlock();

    //// Create a command object. The function will be called later from the
    //// main thread
    this->m_StreamingCommand = ProviderCommand::New();
    m_StreamingCommand->SetCallbackFunction(this,
        &mitk::IGTLMessageProvider::InvokeStartStreamingEvent);

    //// For streaming we need a continues time signal, since there is no timer
    //// available we start a thread that generates a timing signal
    //// This signal is invoked from the other thread the update of the pipeline
    //// has to be executed from the main thread. Thus, we use the
    //// callbackfromGUIThread class to pass the execution to the main thread
    //this->m_ThreadId = m_MultiThreader->SpawnThread(this->TimerThread, this);

    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
          this->m_StreamingCommand);

    this->m_IsStreaming = true;
  }
  else
  {
    MITK_WARN("IGTLMessageProvider") << "This provider just supports the "
                                        "streaming of one source.";
  }
}

void mitk::IGTLMessageProvider::InvokeStartStreamingEvent()
{
  this->InvokeEvent(StreamingStartRequiredEvent());
}

void mitk::IGTLMessageProvider::InvokeStopStreamingEvent()
{
  this->InvokeEvent(StreamingStopRequiredEvent());
}

void mitk::IGTLMessageProvider::StopStreamingOfSource(IGTLMessageSource* src)
{
  //this is something bad!!! The streaming thread has to be stopped before the
  //source is disconnected otherwise it can cause a crash. This has to be added!!
  this->DisconnectFrom(src);

  //this->m_StopStreamingThreadMutex->Lock();
  //this->m_StopStreamingThread = true;
  //this->m_StopStreamingThreadMutex->Unlock();

  //// Create a command object. The function will be called later from the
  //// main thread
    this->m_StopStreamingCommand = ProviderCommand::New();
    m_StopStreamingCommand->SetCallbackFunction(this,
        &mitk::IGTLMessageProvider::InvokeStopStreamingEvent);

    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
          this->m_StopStreamingCommand);

  //does this flag needs a mutex???
  this->m_IsStreaming = false;
}

mitk::IGTLMessageSource::Pointer mitk::IGTLMessageProvider::GetFittingSource(const char* requestedType)
{
  //get the context
  us::ModuleContext* context = us::GetModuleContext();
  //define the interface name
  std::string interface = mitk::IGTLMessageSource::US_INTERFACE_NAME;
  //specify a filter that defines the requested type
  std::string filter = "(" + mitk::IGTLMessageSource::US_PROPKEY_DEVICETYPE +
      "=" + requestedType + ")";
  //find the fitting service
  std::vector<us::ServiceReferenceU> serviceReferences =
      context->GetServiceReferences(interface, filter);

  //check if a service reference was found. It is also possible that several
  //services were found. This is not checked here, just the first one is taken.
  if ( serviceReferences.size() )
  {
    mitk::IGTLMessageSource::Pointer curSource =
        context->GetService<mitk::IGTLMessageSource>(serviceReferences.front());

    if ( curSource.IsNotNull() )
      return curSource;
  }
  //no service reference was found or found service reference has no valid source
  return NULL;
}

void mitk::IGTLMessageProvider::Send(const mitk::IGTLMessage* msg)
{
  if (msg != NULL)
    this->m_IGTLDevice->SendMessage(msg);
}

void
mitk::IGTLMessageProvider::ConnectTo( mitk::IGTLMessageSource* UpstreamFilter )
{
  for (DataObjectPointerArraySizeType i = 0;
       i < UpstreamFilter->GetNumberOfOutputs(); i++)
  {
    this->SetInput(i, UpstreamFilter->GetOutput(i));
  }
}

void
mitk::IGTLMessageProvider::DisconnectFrom( mitk::IGTLMessageSource* UpstreamFilter )
{
  for (DataObjectPointerArraySizeType i = 0;
       i < UpstreamFilter->GetNumberOfOutputs(); i++)
  {
    this->RemoveInput(UpstreamFilter->GetOutput(i));
  }
}

void test()
{

}

//ITK_THREAD_RETURN_TYPE mitk::IGTLMessageProvider::TimerThread(void* pInfoStruct)
//{
//  // extract this pointer from thread info structure
//  struct itk::MultiThreader::ThreadInfoStruct * pInfo =
//      (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
//  mitk::IGTLMessageProvider* thisObject =
//      static_cast<mitk::IGTLMessageProvider*>(pInfo->UserData);
//
//  itk::SimpleMutexLock mutex;
//  mutex.Lock();
//
//  thisObject->m_StopStreamingThreadMutex->Lock();
//  thisObject->m_StopStreamingThread = false;
//  thisObject->m_StopStreamingThreadMutex->Unlock();
//
//  thisObject->m_StreamingTimeMutex->Lock();
//  unsigned int waitingTime = thisObject->m_StreamingTime;
//  thisObject->m_StreamingTimeMutex->Unlock();
//
//  while (true)
//  {
//    thisObject->m_StopStreamingThreadMutex->Lock();
//    bool stopThread = thisObject->m_StopStreamingThread;
//    thisObject->m_StopStreamingThreadMutex->Unlock();
//
//    if (stopThread)
//    {
//      break;
//    }
//
//    //wait for the time given
//    //I know it is not the nicest solution but we just need an approximate time
//    //sleeps for 20 ms
//    #if defined (WIN32) || defined (_WIN32)
//    Sleep(waitingTime);
//    #else
//    usleep(waitingTime * 1000);
//    #endif
//
//    // Ask to execute that command from the GUI thread
//    mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(
//          thisObject->m_StreamingCommand);
//  }
//
//  thisObject->m_ThreadId = 0;
//
//  mutex.Unlock();
//
//  return ITK_THREAD_RETURN_VALUE;
//}
<|endoftext|>