<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH
#define DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH

#include <vector>
#include <map>
#include <string>
#include <iostream>

namespace Dune {
namespace Stuff {
namespace Common {

class ConvergenceStudy
{
public:
  ConvergenceStudy(const std::vector< std::string > only_these_norms = {});

  virtual ~ConvergenceStudy() {}

  virtual std::string identifier() const = 0;

  virtual size_t num_refinements() const = 0;

  virtual std::vector< std::string > provided_norms() const = 0;

  virtual size_t expected_rate(const std::string type) const = 0;

  virtual double norm_reference_solution(const std::string type) = 0;

  virtual size_t current_grid_size() const = 0;

  virtual double current_grid_width() const = 0;

  /**
   * \return The time it took to solve on this refinement.
   */
  virtual double compute_on_current_refinement() = 0;

  virtual double current_error_norm(const std::string type) = 0;

  virtual void refine() = 0;

  std::vector< std::string > used_norms() const;

  std::map< std::string, std::vector< double > > run(const bool relative = false,
                                                     std::ostream& out = std::cout,
                                                     const bool print_timings = true);

  virtual std::vector< double > expected_results(const std::string /*type*/) const;

private:
  std::vector< std::string > only_these_norms_;
}; // class ConvergenceStudy

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH
<commit_msg>[common] default convergence study output to DSC_LOG_INFO_0<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH
#define DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH

#include <vector>
#include <map>
#include <string>
#include <iostream>

#include <dune/stuff/common/logging.hh>

namespace Dune {
namespace Stuff {
namespace Common {

class ConvergenceStudy
{
public:
  ConvergenceStudy(const std::vector< std::string > only_these_norms = {});

  virtual ~ConvergenceStudy() {}

  virtual std::string identifier() const = 0;

  virtual size_t num_refinements() const = 0;

  virtual std::vector< std::string > provided_norms() const = 0;

  virtual size_t expected_rate(const std::string type) const = 0;

  virtual double norm_reference_solution(const std::string type) = 0;

  virtual size_t current_grid_size() const = 0;

  virtual double current_grid_width() const = 0;

  /**
   * \return The time it took to solve on this refinement.
   */
  virtual double compute_on_current_refinement() = 0;

  virtual double current_error_norm(const std::string type) = 0;

  virtual void refine() = 0;

  std::vector< std::string > used_norms() const;

  std::map< std::string, std::vector< double > > run(const bool relative = false,
                                                     std::ostream& out = DSC_LOG_INFO_0,
                                                     const bool print_timings = true);

  virtual std::vector< double > expected_results(const std::string /*type*/) const;

private:
  std::vector< std::string > only_these_norms_;
}; // class ConvergenceStudy

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_CONVERGENCE_STUDY_HH
<|endoftext|>


<commit_before>#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/common.hh>
#include <gazebo/sensors/SensorManager.hh>
#include <gazebo/sensors/SonarSensor.hh>
#include <iostream>
#include <string>
#include <microhttpd.h>
#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_PORT 9999

using namespace gazebo;

enum RodiCommand { SEE = 5, MOVE = 3 };

class RodiWeb {
private:
	/* Only See (5) and Move (3) commands are supported */
	std::string urlRegex = "^/(5|3(/-?([0-9][0-9]?|100)){2})/?$";
	struct MHD_Daemon* webServer;
	bool urlMatches(const char *url);
	static int requestCallback(void *cls, struct MHD_Connection *connection,
				    const char *url, const char *method,
				    const char *version, const char *upload_data,
				    size_t *upload_data_size, void **ptr);
	int getCommand(const char *url);
	void getMoveParams(const char *url, int *left, int *right);
public:
	RodiWeb(int port);
	~RodiWeb(void);
	virtual std::string processSee(void) = 0;
	virtual void processMove(int left, int right) = 0;
};

bool RodiWeb::urlMatches(const char *url)
{
	return boost::regex_match(std::string(url), boost::regex(urlRegex));
}

int RodiWeb::getCommand(const char *url)
{
	return url[1] - 48;
}

void RodiWeb::getMoveParams(const char *url, int *left, int *right)
{
	long temp;
	char *p;

	temp = strtol(url + 3, &p, 10);
	*left = temp;
	temp = strtol(p + 1, &p, 10);
	*right = temp;
}

int RodiWeb::requestCallback(void *cls, struct MHD_Connection *connection,
			      const char *url, const char *method,
			      const char *version, const char *upload_data,
			      size_t *upload_data_size, void **ptr)
{
	RodiWeb *server = (RodiWeb *)cls;
	static void *aptr;
	struct MHD_Response *response;
	std::string res;
	int command;
	int ret;
	int left, right;

	if (strcmp(method, "GET") != 0 || !server->urlMatches(url))
		return MHD_NO;

	if (aptr != *ptr) {
		*ptr = aptr;
		return MHD_YES;
	}

	*ptr = NULL;

	command = server->getCommand(url);

	switch (command) {
	case SEE:
		res = server->processSee();
		break;
	case MOVE:
		server->getMoveParams(url, &left, &right);
		server->processMove(left, right);
		break;
	}

	response = MHD_create_response_from_buffer(strlen(res.c_str()),
						   (void *)res.c_str(),
						   MHD_RESPMEM_MUST_COPY);

	ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
	MHD_destroy_response(response);
	return ret;
}

RodiWeb::RodiWeb(int port)
{
	webServer = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL,
				     NULL, &requestCallback, this,
				     MHD_OPTION_CONNECTION_TIMEOUT,
				     (unsigned int)120, MHD_OPTION_END);

	if (!webServer)
		throw;
}

RodiWeb::~RodiWeb(void)
{
	if (webServer)
		MHD_stop_daemon(webServer);
}

class RodiWebGazebo : public RodiWeb {
	using RodiWeb::RodiWeb;
private:
	physics::ModelPtr model;
	physics::JointPtr leftWheel;
	physics::JointPtr rightWheel;
	sensors::SonarSensorPtr sonar;
	event::ConnectionPtr updateConnection;
	int left, right;
public:
	virtual std::string processSee(void);
	virtual void processMove(int left, int right);
	void setWheelsVelocity(int left, int right);
	void setModel(physics::ModelPtr model);
	void OnUpdate(const common::UpdateInfo &info);
};

std::string RodiWebGazebo::processSee(void) {
	std::ostringstream stream;

#if GAZEBO_MAJOR_VERSION >= 7
	stream << (int)(sonar->Range() * 100);
#else
	stream << (int)(sonar->GetRange() * 100);
#endif
	return stream.str();
}

void RodiWebGazebo::processMove(int left, int right)
{
	this->left = left / 50;
	this->right = right / 50;
	this->setWheelsVelocity(this->left, this->right);
}

void RodiWebGazebo::setWheelsVelocity(int left, int right)
{
	this->leftWheel->SetVelocity(0, left);
	this->rightWheel->SetVelocity(0, right);
}

void RodiWebGazebo::setModel(physics::ModelPtr model)
{
	sensors::SensorManager *mgr = sensors::SensorManager::Instance();

	model = model;

	leftWheel = model->GetJoint("left_wheel_servo");
	rightWheel = model->GetJoint("right_wheel_servo");

#if GAZEBO_MAJOR_VERSION >= 7
	sonar = std::dynamic_pointer_cast<sensors::SonarSensor>(
		mgr->GetSensor("sonar"));
#else
	sonar = boost::dynamic_pointer_cast<sensors::SonarSensor>(
		mgr->GetSensor("sonar"));
#endif
	this->updateConnection = event::Events::ConnectWorldUpdateBegin(
		boost::bind(&RodiWebGazebo::OnUpdate, this, _1));
}

void RodiWebGazebo::OnUpdate(const common::UpdateInfo &info)
{
	if (this->left && this->right)
		this->setWheelsVelocity(this->left, this->right);
}

class ModelRodi : public ModelPlugin
{
private:
	physics::ModelPtr model;
	RodiWebGazebo *server;
public:
	void Load(physics::ModelPtr parent, sdf::ElementPtr sdf);
};

void ModelRodi::Load(physics::ModelPtr parent, sdf::ElementPtr sdf)
{
	int port = DEFAULT_PORT;
	this->model = parent;

	if (sdf->HasElement("port"))
		port = sdf->Get<int>("port");

	server = new RodiWebGazebo(port);
	server->setModel(this->model);
}

GZ_REGISTER_MODEL_PLUGIN(ModelRodi)
<commit_msg>plugins: Use proper values for the wheels joints angular velocity<commit_after>#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/common.hh>
#include <gazebo/sensors/SensorManager.hh>
#include <gazebo/sensors/SonarSensor.hh>
#include <iostream>
#include <string>
#include <microhttpd.h>
#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_PORT 9999

using namespace gazebo;

enum RodiCommand { SEE = 5, MOVE = 3 };

class RodiWeb {
private:
	/* Only See (5) and Move (3) commands are supported */
	std::string urlRegex = "^/(5|3(/-?([0-9][0-9]?|100)){2})/?$";
	struct MHD_Daemon* webServer;
	bool urlMatches(const char *url);
	static int requestCallback(void *cls, struct MHD_Connection *connection,
				    const char *url, const char *method,
				    const char *version, const char *upload_data,
				    size_t *upload_data_size, void **ptr);
	int getCommand(const char *url);
	void getMoveParams(const char *url, int *left, int *right);
public:
	RodiWeb(int port);
	~RodiWeb(void);
	virtual std::string processSee(void) = 0;
	virtual void processMove(int left, int right) = 0;
};

bool RodiWeb::urlMatches(const char *url)
{
	return boost::regex_match(std::string(url), boost::regex(urlRegex));
}

int RodiWeb::getCommand(const char *url)
{
	return url[1] - 48;
}

void RodiWeb::getMoveParams(const char *url, int *left, int *right)
{
	long temp;
	char *p;

	temp = strtol(url + 3, &p, 10);
	*left = temp;
	temp = strtol(p + 1, &p, 10);
	*right = temp;
}

int RodiWeb::requestCallback(void *cls, struct MHD_Connection *connection,
			      const char *url, const char *method,
			      const char *version, const char *upload_data,
			      size_t *upload_data_size, void **ptr)
{
	RodiWeb *server = (RodiWeb *)cls;
	static void *aptr;
	struct MHD_Response *response;
	std::string res;
	int command;
	int ret;
	int left, right;

	if (strcmp(method, "GET") != 0 || !server->urlMatches(url))
		return MHD_NO;

	if (aptr != *ptr) {
		*ptr = aptr;
		return MHD_YES;
	}

	*ptr = NULL;

	command = server->getCommand(url);

	switch (command) {
	case SEE:
		res = server->processSee();
		break;
	case MOVE:
		server->getMoveParams(url, &left, &right);
		server->processMove(left, right);
		break;
	}

	response = MHD_create_response_from_buffer(strlen(res.c_str()),
						   (void *)res.c_str(),
						   MHD_RESPMEM_MUST_COPY);

	ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
	MHD_destroy_response(response);
	return ret;
}

RodiWeb::RodiWeb(int port)
{
	webServer = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL,
				     NULL, &requestCallback, this,
				     MHD_OPTION_CONNECTION_TIMEOUT,
				     (unsigned int)120, MHD_OPTION_END);

	if (!webServer)
		throw;
}

RodiWeb::~RodiWeb(void)
{
	if (webServer)
		MHD_stop_daemon(webServer);
}

class RodiWebGazebo : public RodiWeb {
	using RodiWeb::RodiWeb;
private:
	physics::ModelPtr model;
	physics::JointPtr leftWheel;
	physics::JointPtr rightWheel;
	sensors::SonarSensorPtr sonar;
	event::ConnectionPtr updateConnection;
	double left, right;
public:
	virtual std::string processSee(void);
	virtual void processMove(int left, int right);
	void setWheelsVelocity(int left, int right);
	void setModel(physics::ModelPtr model);
	void OnUpdate(const common::UpdateInfo &info);
};

std::string RodiWebGazebo::processSee(void) {
	std::ostringstream stream;

#if GAZEBO_MAJOR_VERSION >= 7
	stream << (int)(sonar->Range() * 100);
#else
	stream << (int)(sonar->GetRange() * 100);
#endif
	return stream.str();
}

void RodiWebGazebo::processMove(int left, int right)
{
	/* The values are porcentages of the servos maximum operating angle */
	this->left = 3.14 * left / 100;
	this->right =3.14 * right / 100;
	this->setWheelsVelocity(this->left, this->right);
}

void RodiWebGazebo::setWheelsVelocity(int left, int right)
{
	this->leftWheel->SetVelocity(0, left);
	this->rightWheel->SetVelocity(0, right);
}

void RodiWebGazebo::setModel(physics::ModelPtr model)
{
	sensors::SensorManager *mgr = sensors::SensorManager::Instance();

	model = model;

	leftWheel = model->GetJoint("left_wheel_servo");
	rightWheel = model->GetJoint("right_wheel_servo");

#if GAZEBO_MAJOR_VERSION >= 7
	sonar = std::dynamic_pointer_cast<sensors::SonarSensor>(
		mgr->GetSensor("sonar"));
#else
	sonar = boost::dynamic_pointer_cast<sensors::SonarSensor>(
		mgr->GetSensor("sonar"));
#endif
	this->updateConnection = event::Events::ConnectWorldUpdateBegin(
		boost::bind(&RodiWebGazebo::OnUpdate, this, _1));
}

void RodiWebGazebo::OnUpdate(const common::UpdateInfo &info)
{
	if (this->left && this->right)
		this->setWheelsVelocity(this->left, this->right);
}

class ModelRodi : public ModelPlugin
{
private:
	physics::ModelPtr model;
	RodiWebGazebo *server;
public:
	void Load(physics::ModelPtr parent, sdf::ElementPtr sdf);
};

void ModelRodi::Load(physics::ModelPtr parent, sdf::ElementPtr sdf)
{
	int port = DEFAULT_PORT;
	this->model = parent;

	if (sdf->HasElement("port"))
		port = sdf->Get<int>("port");

	server = new RodiWebGazebo(port);
	server->setModel(this->model);
}

GZ_REGISTER_MODEL_PLUGIN(ModelRodi)
<|endoftext|>


<commit_before>#include "PreviewDialog.h"
#include "PreviewCanvas.h"
#include "Symbol.h"

namespace anim
{

PreviewDialog::PreviewDialog(wxWindow* parent, const Symbol* symbol)
 	: wxDialog(parent, wxID_ANY, "Preview", wxDefaultPosition, wxSize(800, 600), wxCLOSE_BOX | wxCAPTION)
	, m_symbol(symbol)
{
	initLayout();
}

PreviewDialog::~PreviewDialog()
{
//	delete m_stage;
}

void PreviewDialog::initLayout()
{
	wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
	buildToolBar(sizer);
	buildEditPanel(sizer);
	SetSizer(sizer);
}

void PreviewDialog::buildToolBar(wxSizer* topSizer)
{
	wxBoxSizer* toolSizer = new wxBoxSizer(wxVERTICAL);

	wxCheckBox* circulateCheck = new wxCheckBox(this, wxID_ANY, wxT("ѭ"));
	circulateCheck->SetValue(true);
	Connect(circulateCheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(PreviewDialog::onSetCirculate));
	toolSizer->Add(circulateCheck, 0);

	wxCheckBox* stopCheck = new wxCheckBox(this, wxID_ANY, wxT("ͣ"));
	stopCheck->SetValue(false);
	Connect(stopCheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(PreviewDialog::onSetStop));
	toolSizer->Add(stopCheck, 0);

	topSizer->Add(toolSizer, 0);
}

void PreviewDialog::buildEditPanel(wxSizer* topSizer)
{
	m_stage = new d2d::EditPanel(this, this);
	m_stage->setEditOP(new d2d::ZoomViewOP(m_stage, false));
	m_stage->setCanvas(new PreviewCanvas(m_stage, m_symbol));
	topSizer->Add(m_stage, 1, wxEXPAND);
}

void PreviewDialog::onSetCirculate(wxCommandEvent& event)
{
	PreviewCanvas* canvas = static_cast<PreviewCanvas*>(m_stage->getCanvas());
	assert(canvas);
	PreviewCanvas::PlaySetting& setting = canvas->getPlaySetting();
	setting.isCirculate = event.IsChecked();

	m_stage->Refresh();
	m_stage->SetFocus();
}

void PreviewDialog::onSetStop(wxCommandEvent& event)
{
	PreviewCanvas* canvas = static_cast<PreviewCanvas*>(m_stage->getCanvas());
	assert(canvas);
	PreviewCanvas::PlaySetting& setting = canvas->getPlaySetting();
	setting.isStop = event.IsChecked();

	m_stage->Refresh();
	m_stage->SetFocus();
}

} // anim<commit_msg>[CHANGED] complex打开的anim去掉左边工具栏<commit_after>#include "PreviewDialog.h"
#include "PreviewCanvas.h"
#include "Symbol.h"

namespace anim
{

PreviewDialog::PreviewDialog(wxWindow* parent, const Symbol* symbol)
 	: wxDialog(parent, wxID_ANY, "Preview", wxDefaultPosition, wxSize(800, 600), wxCLOSE_BOX | wxCAPTION)
	, m_symbol(symbol)
{
	initLayout();
}

PreviewDialog::~PreviewDialog()
{
//	delete m_stage;
}

void PreviewDialog::initLayout()
{
	wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
//	buildToolBar(sizer);
	buildEditPanel(sizer);
	SetSizer(sizer);
}

void PreviewDialog::buildToolBar(wxSizer* topSizer)
{
	wxBoxSizer* toolSizer = new wxBoxSizer(wxVERTICAL);

	wxCheckBox* circulateCheck = new wxCheckBox(this, wxID_ANY, wxT("ѭ"));
	circulateCheck->SetValue(true);
	Connect(circulateCheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(PreviewDialog::onSetCirculate));
	toolSizer->Add(circulateCheck, 0);

	wxCheckBox* stopCheck = new wxCheckBox(this, wxID_ANY, wxT("ͣ"));
	stopCheck->SetValue(false);
	Connect(stopCheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(PreviewDialog::onSetStop));
	toolSizer->Add(stopCheck, 0);

	topSizer->Add(toolSizer, 0);
}

void PreviewDialog::buildEditPanel(wxSizer* topSizer)
{
	m_stage = new d2d::EditPanel(this, this);
	m_stage->setEditOP(new d2d::ZoomViewOP(m_stage, false));
	m_stage->setCanvas(new PreviewCanvas(m_stage, m_symbol));
	topSizer->Add(m_stage, 1, wxEXPAND);
}

void PreviewDialog::onSetCirculate(wxCommandEvent& event)
{
	PreviewCanvas* canvas = static_cast<PreviewCanvas*>(m_stage->getCanvas());
	assert(canvas);
	PreviewCanvas::PlaySetting& setting = canvas->getPlaySetting();
	setting.isCirculate = event.IsChecked();

	m_stage->Refresh();
	m_stage->SetFocus();
}

void PreviewDialog::onSetStop(wxCommandEvent& event)
{
	PreviewCanvas* canvas = static_cast<PreviewCanvas*>(m_stage->getCanvas());
	assert(canvas);
	PreviewCanvas::PlaySetting& setting = canvas->getPlaySetting();
	setting.isStop = event.IsChecked();

	m_stage->Refresh();
	m_stage->SetFocus();
}

} // anim<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2017 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file return_code.H
 * @brief definitions for fapi2 return codes
 */

#ifndef __FAPI2_RETURN_CODE__
#define __FAPI2_RETURN_CODE__

#include <stdint.h>
#include <return_code_defs.H>

#ifndef FAPI2_NO_FFDC
    #include <ffdc.H>
#endif

namespace fapi2
{
///
/// @brief Class representing a FAPI2 ReturnCode
///
// Remove the inheritance relationship with FirstFailureData if
// the platform doesn't support FFDC.
#if defined (FAPI2_NO_FFDC) || defined (MINIMUM_FFDC)
class ReturnCode
#else
class ReturnCode : public FirstFailureData<ReturnCode>
#endif
{
    public:

        ///
        /// @brief Constructor.
        /// @param[in] i_rc the rc to set
        ///
        ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
            iv_rc(i_rc)
        {};

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint32_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint64_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief Returns true iff iv_rc != SUCCESS
        /// @return true or false
        ///
        inline operator bool() const
        {
            return iv_rc != FAPI2_RC_SUCCESS;
        }

        ///
        /// @brief Assignement operator
        ///
#ifdef DOXYGEN
        inline ReturnCode& operator=(const uint32_t& rhs);
        inline ReturnCode& operator=(const ReturnCodes& rhs);
#endif

        inline bool operator==(const uint32_t& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator==(const ReturnCodes& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator!=(const uint32_t& rhs) const
        {
            return rhs != iv_rc;
        }

        inline bool operator!=(const ReturnCodes& rhs) const
        {
            return rhs != iv_rc;
        }

        ///
        /// @brief Enumeration of return code creators
        ///
        enum returnCodeCreator
        {
            CREATOR_FAPI = 1,
            CREATOR_PLAT = 2,
            CREATOR_HWP = 3,
        };

        ///
        /// @brief Gets the creator of the return code
        /// @return ReturnCodeCreator
        ///
        inline returnCodeCreator getCreator(void) const
        {
            returnCodeCreator l_creator = CREATOR_HWP;

            if (iv_rc & FAPI2_RC_FAPI2_MASK)
            {
                l_creator = CREATOR_FAPI;
            }
            else if (iv_rc & FAPI2_RC_PLAT_MASK)
            {
                l_creator = CREATOR_PLAT;
            }

            return l_creator;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const ReturnCodes i_rc) const
        {
            return static_cast<uint32_t>(i_rc) == iv_rc;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const uint32_t i_rc) const
        {
            return i_rc == iv_rc;
        }

    private:
        uint32_t iv_rc;
};

/// This implementation assumes no exception handling and leverages thread-local
/// storage. For platforms without thread support, a global variable will
/// suffice for the error state.

extern thread_local uint64_t pib_error_mask;     /// the pib mask
extern thread_local uint64_t operational_state;  /// the operational mode
#ifndef PLAT_NO_THREAD_LOCAL_STORAGE
    extern thread_local ReturnCode current_err;      /// the current error state
#else
    extern ReturnCode current_err;
#endif

}

#endif
<commit_msg>update fapi2::ReturnCode<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2017 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file return_code.H
 * @brief definitions for fapi2 return codes
 */

#ifndef __FAPI2_RETURN_CODE__
#define __FAPI2_RETURN_CODE__

#include <stdint.h>
#include <return_code_defs.H>

#ifndef FAPI2_NO_FFDC
    #include <ffdc.H>
#endif

namespace fapi2
{
///
/// @brief Class representing a FAPI2 ReturnCode
///
// Remove the inheritance relationship with FirstFailureData if
// the platform doesn't support FFDC.
#if defined (FAPI2_NO_FFDC) || defined (MINIMUM_FFDC)
class ReturnCode
#else
class ReturnCode : public FirstFailureData<ReturnCode>
#endif
{
    public:

        ///
        /// @brief Constructor.
        /// @param[in] i_rc the rc to set
        ///
        ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
            iv_rc(i_rc)
        {};

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint32_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief integral type conversion function. Returns the error code
        /// @return The error code
        ///
        inline operator uint64_t() const
        {
            return iv_rc;
        }

        ///
        /// @brief Returns true iff iv_rc != SUCCESS
        /// @return true or false
        ///
        inline operator bool() const
        {
            return iv_rc != FAPI2_RC_SUCCESS;
        }

        ///
        /// @brief Assignement operator
        ///
#ifdef DOXYGEN
        inline ReturnCode& operator=(const uint32_t& rhs);
        inline ReturnCode& operator=(const ReturnCodes& rhs);
#endif

        inline bool operator==(const uint32_t& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator==(const ReturnCodes& rhs) const
        {
            return rhs == iv_rc;
        }

        inline bool operator!=(const uint32_t& rhs) const
        {
            return rhs != iv_rc;
        }

        inline bool operator!=(const ReturnCodes& rhs) const
        {
            return rhs != iv_rc;
        }

        ///
        /// @brief Enumeration of return code creators
        ///
        enum returnCodeCreator
        {
            CREATOR_FAPI = 1,
            CREATOR_PLAT = 2,
            CREATOR_HWP = 3,
        };

        ///
        /// @brief Gets the creator of the return code
        /// @return ReturnCodeCreator
        ///
        inline returnCodeCreator getCreator(void) const
        {
            returnCodeCreator l_creator = CREATOR_HWP;

            if (iv_rc & FAPI2_RC_FAPI2_MASK)
            {
                l_creator = CREATOR_FAPI;
            }
            else if (iv_rc & FAPI2_RC_PLAT_MASK)
            {
                l_creator = CREATOR_PLAT;
            }

            return l_creator;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const ReturnCodes i_rc) const
        {
            return static_cast<uint32_t>(i_rc) == iv_rc;
        }

        ///
        /// @brief explicit check for RC value
        /// @return true if this instance has a matching RC
        ///
        inline bool isRC(const uint32_t i_rc) const
        {
            return i_rc == iv_rc;
        }

        ///
        /// @brief set the underlying return code to the given value
        /// @param[in] i_rc the target return code
        ///
        inline void setRC(const uint32_t i_rc)
        {
            iv_rc = i_rc;
        }

    private:
        uint32_t iv_rc;
};

/// This implementation assumes no exception handling and leverages thread-local
/// storage. For platforms without thread support, a global variable will
/// suffice for the error state.

extern thread_local uint64_t pib_error_mask;     /// the pib mask
extern thread_local uint64_t operational_state;  /// the operational mode
#ifndef PLAT_NO_THREAD_LOCAL_STORAGE
    extern thread_local ReturnCode current_err;      /// the current error state
#else
    extern ReturnCode current_err;
#endif

}

#endif
<|endoftext|>


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

#if defined(_MSC_VER)
#pragma warning(4:4503)
#endif

// interface header
#include "KeyManager.h"

// system headers
#include <assert.h>
#include <ctype.h>
#include <string.h> // strstr, etc
#include <string>   // std::string
#include <vector>

// local implementation headers
#include "BzfEvent.h"

// initialize the singleton
template <>
KeyManager* Singleton<KeyManager>::_instance = (KeyManager*)0;

const char*		KeyManager::buttonNames[] = {
  "???",
  "Pause",
  "Home",
  "End",
  "Left Arrow",
  "Right Arrow",
  "Up Arrow",
  "Down Arrow",
  "Page Up",
  "Page Down",
  "Insert",
  "Backspace",
  "Delete",
  "Kp0",
  "Kp1",
  "Kp2",
  "Kp3",
  "Kp4",
  "Kp5",
  "Kp6",
  "Kp7",
  "Kp8",
  "Kp9",
  "Kp_Period",
  "Kp_Divide",
  "Kp_Multiply",
  "Kp_Minus",
  "Kp_Plus",
  "Kp_Enter",
  "Kp_Equals",
  "F1",
  "F2",
  "F3",
  "F4",
  "F5",
  "F6",
  "F7",
  "F8",
  "F9",
  "F10",
  "F11",
  "F12",
  "Help",
  "Print",
  "Sysreq",
  "Break",
  "Menu",
  "Power",
  "Euro",
  "Undo",
  "Left Mouse",
  "Middle Mouse",
  "Right Mouse",
  "Wheel Up",
  "Wheel Down",
  "Mouse Button 6",
  "Mouse Button 7",
  "Mouse Button 8",
  "Mouse Button 9",
  "Mouse Button 10",
  "Joystick Button 1",
  "Joystick Button 2",
  "Joystick Button 3",
  "Joystick Button 4",
  "Joystick Button 5",
  "Joystick Button 6",
  "Joystick Button 7",
  "Joystick Button 8",
  "Joystick Button 9",
  "Joystick Button 10",
  "LastButton"  // should always be last item listed
};
const char*		KeyManager::asciiNames[][2] = {
  { "Tab",		"\t" },
  { "Backspace",	"\b" },
  { "Enter",		"\r" },
  { "Space",		" "  }
};

KeyManager::KeyManager()
{
  unsigned int i;

  // prep string to key map
  BzfKeyEvent key;
  key.ascii  = 0;
  key.shift  = 0;
  for (i = BzfKeyEvent::Pause; i < BzfKeyEvent::LastButton; ++i) {
    key.button = static_cast<BzfKeyEvent::Button>(i);
    stringToEvent.insert(std::make_pair(std::string(buttonNames[i]), key));
  }
  key.button = BzfKeyEvent::NoButton;
  for (i = 0; i < countof(asciiNames); ++i) {
    key.ascii = asciiNames[i][1][0];
    stringToEvent.insert(std::make_pair(std::string(asciiNames[i][0]), key));
  }
  char buffer[2];
  buffer[1] = 0;
  for (i = 0x21; i < 0x7f; ++i) {
    buffer[0] = key.ascii = static_cast<char>(i);
    stringToEvent.insert(std::make_pair(std::string(buffer), key));
  }
}

KeyManager::~KeyManager()
{
}

void			KeyManager::bind(const BzfKeyEvent& key,
					 bool press, const std::string& cmd)
{
  if (press) {
    pressEventToCommand.erase(key);
    pressEventToCommand.insert(std::make_pair(key, cmd));
  } else {
    releaseEventToCommand.erase(key);
    releaseEventToCommand.insert(std::make_pair(key, cmd));
  }
  notify(key, press, cmd);
}

void			KeyManager::unbind(const BzfKeyEvent& key,
					   bool press)
{
  notify(key, press, "");
}

void			KeyManager::unbindCommand(const char* command)
{
  EventToCommandMap::iterator index;

	index = pressEventToCommand.begin();
	while(index != pressEventToCommand.end())
	{
		if (index->second == command)
		{
			unbind(index->first, true);
			index = pressEventToCommand.erase(index);
		}
		else
			index++;
	}

	index = releaseEventToCommand.begin();
	while(index != releaseEventToCommand.end())
	{
		if (index->second == command)
		{
			unbind(index->first, true);
			index = releaseEventToCommand.erase(index);

		}
		else
			index++;
	}
}

std::string		KeyManager::get(const BzfKeyEvent& key,
					bool press) const
{
  const EventToCommandMap* map = press ? &pressEventToCommand :
    &releaseEventToCommand;
  EventToCommandMap::const_iterator index = map->find(key);
  if (index == map->end())
    return "";
  else
    return index->second;
}

std::vector<std::string> KeyManager::getKeysFromCommand(std::string command, bool press) const
{
  std::vector<std::string> keys;
  EventToCommandMap::const_iterator index;
  if (press) {
    for (index = pressEventToCommand.begin(); index != pressEventToCommand.end(); ++index) {
      if (index->second == command) {
	keys.push_back(this->keyEventToString(index->first));
      }
    }
  } else {
    for (index = releaseEventToCommand.begin(); index != releaseEventToCommand.end(); ++index) {
      if (index->second == command) {
	keys.push_back(this->keyEventToString(index->first));
      }
    }
  }
  return keys;
}

std::string		KeyManager::keyEventToString(
					const BzfKeyEvent& key) const
{
  std::string name;
  if (key.shift & BzfKeyEvent::ShiftKey)
    name += "Shift+";
  if (key.shift & BzfKeyEvent::ControlKey)
    name += "Ctrl+";
  if (key.shift & BzfKeyEvent::AltKey)
    name += "Alt+";
  switch (key.ascii) {
    case 0:
      return name + buttonNames[key.button];
    case '\b':
      return name + "Backspace";
    case '\t':
      return name + "Tab";
    case '\r':
      return name + "Enter";
    case ' ':
      return name + "Space";
    default:
      if (!isspace(key.ascii))
	return name + std::string(&key.ascii, 1);
      return name + "???";
  }
}

bool			KeyManager::stringToKeyEvent(
				const std::string& name, BzfKeyEvent& key) const
{
  // find last + in name
  const char* shiftDelimiter = strrchr(name.c_str(), '+');

  // split name into shift part and key name part
  std::string shiftPart, keyPart;
  if (shiftDelimiter == NULL) {
    keyPart = name;
  } else {
    shiftPart  = "+";
    shiftPart += name.substr(0, shiftDelimiter - name.c_str() + 1);
    keyPart    = shiftDelimiter + 1;
  }

  // find key name
  StringToEventMap::const_iterator index = stringToEvent.find(keyPart);
  if (index == stringToEvent.end())
    return false;

  // get key event sans shift state
  key = index->second;

  // apply shift state
  if (strstr(shiftPart.c_str(), "+Shift+") != NULL ||
      strstr(shiftPart.c_str(), "+shift+") != NULL)
    key.shift |= BzfKeyEvent::ShiftKey;
  if (strstr(shiftPart.c_str(), "+Ctrl+") != NULL ||
      strstr(shiftPart.c_str(), "+ctrl+") != NULL)
    key.shift |= BzfKeyEvent::ControlKey;
  if (strstr(shiftPart.c_str(), "+Alt+") != NULL ||
      strstr(shiftPart.c_str(), "+alt+") != NULL)
    key.shift |= BzfKeyEvent::AltKey;

  // success
  return true;
}

void			KeyManager::iterate(
				IterateCallback callback, void* userData)
{
  assert(callback != NULL);

  EventToCommandMap::const_iterator index;
  for (index = pressEventToCommand.begin(); index != pressEventToCommand.end(); ++index)
    (*callback)(keyEventToString(index->first), true, index->second, userData);
  for (index = releaseEventToCommand.begin(); index != releaseEventToCommand.end(); ++index)
    (*callback)(keyEventToString(index->first), false, index->second, userData);
}

void			KeyManager::addCallback(
				ChangeCallback callback, void* userData)
{
  callbacks.add(callback, userData);
}

void			KeyManager::removeCallback(
				ChangeCallback callback, void* userData)
{
  callbacks.remove(callback, userData);
}

void			KeyManager::notify(
				const BzfKeyEvent& key,
				bool press, const std::string& cmd)
{
  CallbackInfo info;
  info.name  = keyEventToString(key);
  info.press = press;
  info.cmd   = cmd;
  callbacks.iterate(&onCallback, &info);
}

bool			KeyManager::onCallback(
				ChangeCallback callback,
				void* userData,
				void* vinfo)
{
  CallbackInfo* info = reinterpret_cast<CallbackInfo*>(vinfo);
  callback(info->name, info->press, info->cmd, userData);
  return true;
}

bool			KeyManager::KeyEventLess::operator()(
				const BzfKeyEvent& a,
				const BzfKeyEvent& b) const
{
  if (a.ascii == 0 && b.ascii == 0) {
    if (a.button < b.button)
      return true;
    if (a.button > b.button)
      return false;

    // check shift
    if (a.shift < b.shift)
      return true;
  } else if (a.ascii == 0 && b.ascii != 0) {
    return true;
  } else if (a.ascii != 0 && b.ascii == 0) {
    return false;
  } else {
    if (toupper(a.ascii) < toupper(b.ascii))
      return true;
    if (toupper(a.ascii) > toupper(b.ascii))
      return false;

    // check shift state without shift key
    if ((a.shift & ~BzfKeyEvent::ShiftKey) < (b.shift & ~BzfKeyEvent::ShiftKey))
      return true;
  }

  return false;
}

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

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

#if defined(_MSC_VER)
#pragma warning(4:4503)
#endif

// interface header
#include "KeyManager.h"

// system headers
#include <assert.h>
#include <ctype.h>
#include <string.h> // strstr, etc
#include <string>   // std::string
#include <vector>

// local implementation headers
#include "BzfEvent.h"

// initialize the singleton
template <>
KeyManager* Singleton<KeyManager>::_instance = (KeyManager*)0;

const char*		KeyManager::buttonNames[] = {
  "???",
  "Pause",
  "Home",
  "End",
  "Left Arrow",
  "Right Arrow",
  "Up Arrow",
  "Down Arrow",
  "Page Up",
  "Page Down",
  "Insert",
  "Backspace",
  "Delete",
  "Kp0",
  "Kp1",
  "Kp2",
  "Kp3",
  "Kp4",
  "Kp5",
  "Kp6",
  "Kp7",
  "Kp8",
  "Kp9",
  "Kp_Period",
  "Kp_Divide",
  "Kp_Multiply",
  "Kp_Minus",
  "Kp_Plus",
  "Kp_Enter",
  "Kp_Equals",
  "F1",
  "F2",
  "F3",
  "F4",
  "F5",
  "F6",
  "F7",
  "F8",
  "F9",
  "F10",
  "F11",
  "F12",
  "Help",
  "Print",
  "Sysreq",
  "Break",
  "Menu",
  "Power",
  "Euro",
  "Undo",
  "Left Mouse",
  "Middle Mouse",
  "Right Mouse",
  "Wheel Up",
  "Wheel Down",
  "Mouse Button 6",
  "Mouse Button 7",
  "Mouse Button 8",
  "Mouse Button 9",
  "Mouse Button 10",
  "Joystick Button 1",
  "Joystick Button 2",
  "Joystick Button 3",
  "Joystick Button 4",
  "Joystick Button 5",
  "Joystick Button 6",
  "Joystick Button 7",
  "Joystick Button 8",
  "Joystick Button 9",
  "Joystick Button 10",
  "LastButton"  // should always be last item listed
};
const char*		KeyManager::asciiNames[][2] = {
  { "Tab",		"\t" },
  { "Backspace",	"\b" },
  { "Enter",		"\r" },
  { "Space",		" "  }
};

KeyManager::KeyManager()
{
  unsigned int i;

  // prep string to key map
  BzfKeyEvent key;
  key.ascii  = 0;
  key.shift  = 0;
  for (i = BzfKeyEvent::Pause; i < BzfKeyEvent::LastButton; ++i) {
    key.button = static_cast<BzfKeyEvent::Button>(i);
    stringToEvent.insert(std::make_pair(std::string(buttonNames[i]), key));
  }
  key.button = BzfKeyEvent::NoButton;
  for (i = 0; i < countof(asciiNames); ++i) {
    key.ascii = asciiNames[i][1][0];
    stringToEvent.insert(std::make_pair(std::string(asciiNames[i][0]), key));
  }
  char buffer[2];
  buffer[1] = 0;
  for (i = 0x21; i < 0x7f; ++i) {
    buffer[0] = key.ascii = static_cast<char>(i);
    stringToEvent.insert(std::make_pair(std::string(buffer), key));
  }
}

KeyManager::~KeyManager()
{
}

void			KeyManager::bind(const BzfKeyEvent& key,
					 bool press, const std::string& cmd)
{
  if (press) {
    pressEventToCommand.erase(key);
    pressEventToCommand.insert(std::make_pair(key, cmd));
  } else {
    releaseEventToCommand.erase(key);
    releaseEventToCommand.insert(std::make_pair(key, cmd));
  }
  notify(key, press, cmd);
}

void			KeyManager::unbind(const BzfKeyEvent& key,
					   bool press)
{
  notify(key, press, "");
}

void			KeyManager::unbindCommand(const char* command)
{
  EventToCommandMap::iterator index;

	index = pressEventToCommand.begin();
	while(index != pressEventToCommand.end())
	{
		if (index->second == command)
		{
			unbind(index->first, true);
			index = pressEventToCommand.erase(index);
		}
		else
			index++;
	}

	index = releaseEventToCommand.begin();
	while(index != releaseEventToCommand.end())
	{
		if (index->second == command)
		{
			unbind(index->first, true);
			index = releaseEventToCommand.erase(index);
		}
		else
			index++;
	}
}

std::string		KeyManager::get(const BzfKeyEvent& key,
					bool press) const
{
  const EventToCommandMap* map = press ? &pressEventToCommand :
    &releaseEventToCommand;
  EventToCommandMap::const_iterator index = map->find(key);
  if (index == map->end())
    return "";
  else
    return index->second;
}

std::vector<std::string> KeyManager::getKeysFromCommand(std::string command, bool press) const
{
  std::vector<std::string> keys;
  EventToCommandMap::const_iterator index;
  if (press) {
    for (index = pressEventToCommand.begin(); index != pressEventToCommand.end(); ++index) {
      if (index->second == command) {
	keys.push_back(this->keyEventToString(index->first));
      }
    }
  } else {
    for (index = releaseEventToCommand.begin(); index != releaseEventToCommand.end(); ++index) {
      if (index->second == command) {
	keys.push_back(this->keyEventToString(index->first));
      }
    }
  }
  return keys;
}

std::string		KeyManager::keyEventToString(
					const BzfKeyEvent& key) const
{
  std::string name;
  if (key.shift & BzfKeyEvent::ShiftKey)
    name += "Shift+";
  if (key.shift & BzfKeyEvent::ControlKey)
    name += "Ctrl+";
  if (key.shift & BzfKeyEvent::AltKey)
    name += "Alt+";
  switch (key.ascii) {
    case 0:
      return name + buttonNames[key.button];
    case '\b':
      return name + "Backspace";
    case '\t':
      return name + "Tab";
    case '\r':
      return name + "Enter";
    case ' ':
      return name + "Space";
    default:
      if (!isspace(key.ascii))
	return name + std::string(&key.ascii, 1);
      return name + "???";
  }
}

bool			KeyManager::stringToKeyEvent(
				const std::string& name, BzfKeyEvent& key) const
{
  // find last + in name
  const char* shiftDelimiter = strrchr(name.c_str(), '+');

  // split name into shift part and key name part
  std::string shiftPart, keyPart;
  if (shiftDelimiter == NULL) {
    keyPart = name;
  } else {
    shiftPart  = "+";
    shiftPart += name.substr(0, shiftDelimiter - name.c_str() + 1);
    keyPart    = shiftDelimiter + 1;
  }

  // find key name
  StringToEventMap::const_iterator index = stringToEvent.find(keyPart);
  if (index == stringToEvent.end())
    return false;

  // get key event sans shift state
  key = index->second;

  // apply shift state
  if (strstr(shiftPart.c_str(), "+Shift+") != NULL ||
      strstr(shiftPart.c_str(), "+shift+") != NULL)
    key.shift |= BzfKeyEvent::ShiftKey;
  if (strstr(shiftPart.c_str(), "+Ctrl+") != NULL ||
      strstr(shiftPart.c_str(), "+ctrl+") != NULL)
    key.shift |= BzfKeyEvent::ControlKey;
  if (strstr(shiftPart.c_str(), "+Alt+") != NULL ||
      strstr(shiftPart.c_str(), "+alt+") != NULL)
    key.shift |= BzfKeyEvent::AltKey;

  // success
  return true;
}

void			KeyManager::iterate(
				IterateCallback callback, void* userData)
{
  assert(callback != NULL);

  EventToCommandMap::const_iterator index;
  for (index = pressEventToCommand.begin(); index != pressEventToCommand.end(); ++index)
    (*callback)(keyEventToString(index->first), true, index->second, userData);
  for (index = releaseEventToCommand.begin(); index != releaseEventToCommand.end(); ++index)
    (*callback)(keyEventToString(index->first), false, index->second, userData);
}

void			KeyManager::addCallback(
				ChangeCallback callback, void* userData)
{
  callbacks.add(callback, userData);
}

void			KeyManager::removeCallback(
				ChangeCallback callback, void* userData)
{
  callbacks.remove(callback, userData);
}

void			KeyManager::notify(
				const BzfKeyEvent& key,
				bool press, const std::string& cmd)
{
  CallbackInfo info;
  info.name  = keyEventToString(key);
  info.press = press;
  info.cmd   = cmd;
  callbacks.iterate(&onCallback, &info);
}

bool			KeyManager::onCallback(
				ChangeCallback callback,
				void* userData,
				void* vinfo)
{
  CallbackInfo* info = reinterpret_cast<CallbackInfo*>(vinfo);
  callback(info->name, info->press, info->cmd, userData);
  return true;
}

bool			KeyManager::KeyEventLess::operator()(
				const BzfKeyEvent& a,
				const BzfKeyEvent& b) const
{
  if (a.ascii == 0 && b.ascii == 0) {
    if (a.button < b.button)
      return true;
    if (a.button > b.button)
      return false;

    // check shift
    if (a.shift < b.shift)
      return true;
  } else if (a.ascii == 0 && b.ascii != 0) {
    return true;
  } else if (a.ascii != 0 && b.ascii == 0) {
    return false;
  } else {
    if (toupper(a.ascii) < toupper(b.ascii))
      return true;
    if (toupper(a.ascii) > toupper(b.ascii))
      return false;

    // check shift state without shift key
    if ((a.shift & ~BzfKeyEvent::ShiftKey) < (b.shift & ~BzfKeyEvent::ShiftKey))
      return true;
  }

  return false;
}

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

<|endoftext|>


<commit_before>#include "precompiled.h"

#include "winrtangle.h"
#include "angleutils.h"
#include <windows.h>
#include <crtdbg.h>

using namespace Microsoft::WRL;

#define TRACE OutputDebugString
#define ASSERT _ASSERTE

class WinPhone8XamlD3DWindow : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWinPhone8XamlD3DWindow>
{
public:
    WinPhone8XamlD3DWindow()
        : m_device(nullptr)
        , m_context(nullptr)
        , m_renderTarget(nullptr)
    {
        TRACE((LPCWSTR)"WinPhone8XamlD3DWindow()\n");
    }

    ~WinPhone8XamlD3DWindow()
    {
        release();
        TRACE((LPCWSTR)"~WinPhone8XamlD3DWindow()\n");
    }

    //
    // IWinPhone8XamlD3DWindow
    //

    virtual ID3D11Device1* __stdcall GetDevice() const override
    {
        if(m_device)
        {
            m_device->AddRef();
        }
        return m_device;
    }

   virtual  ID3D11DeviceContext1* __stdcall GetContext() const override
    {
        if(m_context)
        {
            m_context->AddRef();
        }
        return m_context;
    }

    virtual ID3D11RenderTargetView* __stdcall GetRenderTarget() const override
    {
        if(m_renderTarget)
        {
            m_renderTarget->AddRef();
        }
        return m_renderTarget;
    }

    virtual void __stdcall Update(ID3D11Device1* device, ID3D11DeviceContext1* context, ID3D11RenderTargetView* renderTarget) override
    {
        release();

        if(device)
        {
            device->AddRef();
        }

        if(context)
        {
            context->AddRef();
        }

        if(renderTarget)
        {
            renderTarget->AddRef();
        }

        m_device = device;
        m_context = context;
        m_renderTarget = renderTarget;
    }

    virtual HRESULT getBackBuffer(ID3D11Texture2D** buffer) const override
    {
        HRESULT result = S_OK;
        *buffer = NULL;

        ComPtr<ID3D11Resource> renderTargetViewResource;
        ComPtr<ID3D11Texture2D> texture2d;

        if(m_renderTarget)
        {
            m_renderTarget->GetResource(&renderTargetViewResource);

            if(renderTargetViewResource != NULL)
            {
                result = renderTargetViewResource.As(&texture2d);
                if(SUCCEEDED(result))
                {
                    *buffer = texture2d.Get();
                    (*buffer)->AddRef();
                }
            }
        }

	    return result;
    }

private:

    void release()
    {
        SafeRelease(m_device);
        SafeRelease(m_context);
        SafeRelease(m_renderTarget);
    }

    ID3D11Device1* m_device;
    ID3D11DeviceContext1* m_context;
    ID3D11RenderTargetView* m_renderTarget;
};

HRESULT __stdcall CreateWinPhone8XamlWindow(IWinPhone8XamlD3DWindow ** result)
{
    ASSERT(result);
    *result = nullptr;

    ComPtr<IWinPhone8XamlD3DWindow> iWindow = Make<WinPhone8XamlD3DWindow>();

    if (!iWindow)
    {
        return E_OUTOFMEMORY;
    }

    *result = iWindow.Detach();
    return S_OK;
}

class WinrtEglWindow : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWinrtEglWindow>
{
public:
    WinrtEglWindow(IUnknown* windowInterface, ANGLE_D3D_FEATURE_LEVEL featureLevel)
        : m_featureLevel(featureLevel)
        , m_windowInterface(NULL)
        , m_device(NULL)
    {
        windowInterface->AddRef();
        m_windowInterface = windowInterface;

        TRACE((LPCWSTR)"WinrtEglWindow()\n");
    }

    ~WinrtEglWindow()
    {
        release();
        TRACE((LPCWSTR)"~WinrtEglWindow()\n");
    }

    void release()
    {
        SafeRelease(m_windowInterface);
        SafeRelease(m_device);
    }

    //
    // IWinrtEglWindow
    //

    virtual void __stdcall SetAngleD3DDevice(ID3D11Device* device) override
    {
        SafeRelease(m_device);
        if (device)
        {
            device->AddRef();
            m_device = device;
        }
    }

    virtual ID3D11Device* __stdcall GetAngleD3DDevice() const override
    {
        if (m_device)
        {
            m_device->AddRef();
        }

        return m_device;
    }

    virtual ANGLE_D3D_FEATURE_LEVEL __stdcall GetAngleD3DFeatureLevel() const override
    {
        return m_featureLevel;
    }

    virtual D3D_FEATURE_LEVEL __stdcall getD3DFeatureLevel() const override
    {
	    D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;

	    switch(m_featureLevel)
	    {
		    case ANGLE_D3D_FEATURE_LEVEL_ANY:
		    case ANGLE_D3D_FEATURE_LEVEL_11_0:
			    level = D3D_FEATURE_LEVEL_11_0;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_10_1:
			    level = D3D_FEATURE_LEVEL_10_1;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_10_0:
			    level = D3D_FEATURE_LEVEL_10_0;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_3:
			    level = D3D_FEATURE_LEVEL_9_3;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_2:
			    level = D3D_FEATURE_LEVEL_9_2;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_1:
			    level = D3D_FEATURE_LEVEL_9_1;
			    break;
	    }

	    return level;
    }

    virtual IUnknown* __stdcall GetWindowInterface() const override
    {
        if(m_windowInterface)
        {
            m_windowInterface->AddRef();
        }
        return m_windowInterface;
    }

private:
    ANGLE_D3D_FEATURE_LEVEL m_featureLevel;
    IUnknown* m_windowInterface;
    ID3D11Device* m_device;
};

HRESULT __stdcall CreateWinrtEglWindow(IUnknown* windowInterface, ANGLE_D3D_FEATURE_LEVEL featureLevel, IWinrtEglWindow ** result)
{
    ASSERT(result);
    *result = NULL;

    ComPtr<IWinrtEglWindow> iWindow = Make<WinrtEglWindow>(windowInterface, featureLevel);

    if (!iWindow)
    {
        return E_OUTOFMEMORY;
    }

    *result = iWindow.Detach();
    return S_OK;
}

<commit_msg>check if windowInterface is not null<commit_after>#include "precompiled.h"

#include "winrtangle.h"
#include "angleutils.h"
#include <windows.h>
#include <crtdbg.h>

using namespace Microsoft::WRL;

#define TRACE OutputDebugString
#define ASSERT _ASSERTE

class WinPhone8XamlD3DWindow : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWinPhone8XamlD3DWindow>
{
public:
    WinPhone8XamlD3DWindow()
        : m_device(nullptr)
        , m_context(nullptr)
        , m_renderTarget(nullptr)
    {
        TRACE((LPCWSTR)"WinPhone8XamlD3DWindow()\n");
    }

    ~WinPhone8XamlD3DWindow()
    {
        release();
        TRACE((LPCWSTR)"~WinPhone8XamlD3DWindow()\n");
    }

    //
    // IWinPhone8XamlD3DWindow
    //

    virtual ID3D11Device1* __stdcall GetDevice() const override
    {
        if(m_device)
        {
            m_device->AddRef();
        }
        return m_device;
    }

   virtual  ID3D11DeviceContext1* __stdcall GetContext() const override
    {
        if(m_context)
        {
            m_context->AddRef();
        }
        return m_context;
    }

    virtual ID3D11RenderTargetView* __stdcall GetRenderTarget() const override
    {
        if(m_renderTarget)
        {
            m_renderTarget->AddRef();
        }
        return m_renderTarget;
    }

    virtual void __stdcall Update(ID3D11Device1* device, ID3D11DeviceContext1* context, ID3D11RenderTargetView* renderTarget) override
    {
        release();

        if(device)
        {
            device->AddRef();
        }

        if(context)
        {
            context->AddRef();
        }

        if(renderTarget)
        {
            renderTarget->AddRef();
        }

        m_device = device;
        m_context = context;
        m_renderTarget = renderTarget;
    }

    virtual HRESULT getBackBuffer(ID3D11Texture2D** buffer) const override
    {
        HRESULT result = S_OK;
        *buffer = NULL;

        ComPtr<ID3D11Resource> renderTargetViewResource;
        ComPtr<ID3D11Texture2D> texture2d;

        if(m_renderTarget)
        {
            m_renderTarget->GetResource(&renderTargetViewResource);

            if(renderTargetViewResource != NULL)
            {
                result = renderTargetViewResource.As(&texture2d);
                if(SUCCEEDED(result))
                {
                    *buffer = texture2d.Get();
                    (*buffer)->AddRef();
                }
            }
        }

	    return result;
    }

private:

    void release()
    {
        SafeRelease(m_device);
        SafeRelease(m_context);
        SafeRelease(m_renderTarget);
    }

    ID3D11Device1* m_device;
    ID3D11DeviceContext1* m_context;
    ID3D11RenderTargetView* m_renderTarget;
};

HRESULT __stdcall CreateWinPhone8XamlWindow(IWinPhone8XamlD3DWindow ** result)
{
    ASSERT(result);
    *result = nullptr;

    ComPtr<IWinPhone8XamlD3DWindow> iWindow = Make<WinPhone8XamlD3DWindow>();

    if (!iWindow)
    {
        return E_OUTOFMEMORY;
    }

    *result = iWindow.Detach();
    return S_OK;
}

class WinrtEglWindow : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWinrtEglWindow>
{
public:
    WinrtEglWindow(IUnknown* windowInterface, ANGLE_D3D_FEATURE_LEVEL featureLevel)
        : m_featureLevel(featureLevel)
        , m_windowInterface(NULL)
        , m_device(NULL)
    {
        if (windowInterface != NULL)
		{
 			windowInterface->AddRef();
 			m_windowInterface = windowInterface;
		}
        TRACE((LPCWSTR)"WinrtEglWindow()\n");
    }

    ~WinrtEglWindow()
    {
        release();
        TRACE((LPCWSTR)"~WinrtEglWindow()\n");
    }

    void release()
    {
        SafeRelease(m_windowInterface);
        SafeRelease(m_device);
    }

    //
    // IWinrtEglWindow
    //

    virtual void __stdcall SetAngleD3DDevice(ID3D11Device* device) override
    {
        SafeRelease(m_device);
        if (device)
        {
            device->AddRef();
            m_device = device;
        }
    }

    virtual ID3D11Device* __stdcall GetAngleD3DDevice() const override
    {
        if (m_device)
        {
            m_device->AddRef();
        }

        return m_device;
    }

    virtual ANGLE_D3D_FEATURE_LEVEL __stdcall GetAngleD3DFeatureLevel() const override
    {
        return m_featureLevel;
    }

    virtual D3D_FEATURE_LEVEL __stdcall getD3DFeatureLevel() const override
    {
	    D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;

	    switch(m_featureLevel)
	    {
		    case ANGLE_D3D_FEATURE_LEVEL_ANY:
		    case ANGLE_D3D_FEATURE_LEVEL_11_0:
			    level = D3D_FEATURE_LEVEL_11_0;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_10_1:
			    level = D3D_FEATURE_LEVEL_10_1;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_10_0:
			    level = D3D_FEATURE_LEVEL_10_0;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_3:
			    level = D3D_FEATURE_LEVEL_9_3;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_2:
			    level = D3D_FEATURE_LEVEL_9_2;
			    break;
		    case ANGLE_D3D_FEATURE_LEVEL_9_1:
			    level = D3D_FEATURE_LEVEL_9_1;
			    break;
	    }

	    return level;
    }

    virtual IUnknown* __stdcall GetWindowInterface() const override
    {
        if(m_windowInterface)
        {
            m_windowInterface->AddRef();
        }
        return m_windowInterface;
    }

private:
    ANGLE_D3D_FEATURE_LEVEL m_featureLevel;
    IUnknown* m_windowInterface;
    ID3D11Device* m_device;
};

HRESULT __stdcall CreateWinrtEglWindow(IUnknown* windowInterface, ANGLE_D3D_FEATURE_LEVEL featureLevel, IWinrtEglWindow ** result)
{
    ASSERT(result);
    *result = NULL;

    ComPtr<IWinrtEglWindow> iWindow = Make<WinrtEglWindow>(windowInterface, featureLevel);

    if (!iWindow)
    {
        return E_OUTOFMEMORY;
    }

    *result = iWindow.Detach();
    return S_OK;
}

<|endoftext|>


<commit_before>#ifndef _SDD_ORDER_ORDER_HH_
#define _SDD_ORDER_ORDER_HH_

#include <initializer_list>
#include <iostream>
#include <memory> // shared_ptr, unique_ptr
#include <vector>

#include <boost/optional.hpp>

#include "sdd/conf/variable_traits.hh"

namespace sdd { namespace order {

/// @cond INTERNAL_DOC

/*-------------------------------------------------------------------------------------------*/

// Forward declaration of an order's node.
template <typename C>
struct order_builder_node;

/*-------------------------------------------------------------------------------------------*/

/// @brief Represent an order of identifiers.
template <typename C>
using order_builder_ptr_type = std::shared_ptr<order_builder_node<C>>;

/*-------------------------------------------------------------------------------------------*/

/// @brief An element of a linked list of nodes, associating a (library) variable to an (user)
/// identifier.
///
/// We create our own type rather than using std::list. This is beacause we don't want the user
/// to add identifier to an order which has already been added as a nested order.
template <typename C>
struct order_builder_node
{
  /// @brief A variable type.
  typedef typename C::Variable variable_type;

  /// @brief An identifier type.
  typedef typename C::Identifier identifier_type;

  /// @brief The library variable.
  ///
  /// A variable is automatically assigned to an identifier by the library.
  const variable_type variable;

  /// @brief The user identifier.
  ///
  /// When nullptr, it's an artificial node. That is, a node generated by the library.
  const std::unique_ptr<identifier_type> identifier;

  /// @brief The nested order.
  ///
  /// If nullptr, this node is a flat node.
  const order_builder_ptr_type<C> nested;

  /// @brief The node's next variable.
  ///
  /// If nullptr, this node is the last one.
  const order_builder_ptr_type<C> next;

  /// @brief Constructor.
  order_builder_node( const variable_type& var, std::unique_ptr<identifier_type>&& id
                    , order_builder_ptr_type<C> nst, order_builder_ptr_type<C> nxt)
    : variable(var)
    , identifier(std::move(id))
    , nested(nst)
    , next(nxt)
  {
  }
};

/// @endcond

/*-------------------------------------------------------------------------------------------*/

/// @brief
template <typename C>
class order_builder
{
public:

  /// @brief The type of a variable.
  typedef typename C::Variable variable_type;

  /// @brief The type of an identifier.
  typedef typename C::Identifier identifier_type;

/// @cond INTERNAL_DOC
private:

  /// @brief The concrete order.
  order_builder_ptr_type<C> order_ptr_;

public:

  /// @brief Constructor.
  order_builder(const order_builder_ptr_type<C>& ptr)
    : order_ptr_(ptr)
  {
  }

  /// @brief Get the concrete order.
  const order_builder_ptr_type<C>&
  ptr()
  const noexcept
  {
    return order_ptr_;
  }

/// @endcond

  /// @brief Default constructor.
  order_builder()
    : order_ptr_(nullptr)
  {
  }

  /// @brief Constructor from a list of identifiers.
  template <typename InputIterator>
  order_builder(InputIterator begin, InputIterator end)
    : order_builder()
  {
    std::vector<identifier_type> tmp(begin, end);
    for (auto rcit = tmp.crbegin(); rcit != tmp.crend(); ++rcit)
    {
      add(*rcit);
    }
  }

  /// @brief Constructor from a list of identifiers.
  order_builder(std::initializer_list<identifier_type> list)
    : order_builder(list.begin(), list.end())
  {
  }

  /// @brief Copy operator.
  order_builder&
  operator=(const order_builder& other)
  {
    order_ptr_ = other.order_ptr_;
    return *this;
  }

  /// @brief Tell if this order is empty.
  ///
  /// It's unsafe to call any other method, except add(), if this order is empty.
  bool
  empty()
  const noexcept
  {
    return not order_ptr_;
  }

  /// @brief Get the variable of this order's head.
  const variable_type&
  variable()
  const noexcept
  {
    return order_ptr_->variable;
  }

  /// @brief Get the idetifier of this order's head.
  const identifier_type&
  identifier()
  const noexcept
  {
    return *order_ptr_->identifier;
  }

  /// @brief Get this order's head's next order.
  order_builder
  next()
  const noexcept
  {
    return order_builder(order_ptr_->next);
  }

  /// @brief Get this order's head's nested order.
  order_builder
  nested()
  const noexcept
  {
    return order_builder(order_ptr_->nested);
  }

//  /// @brief Get the variable of an identifier
//  variable_type
//  identifier_variable(const identifier_type& id)
//  const
//  {
//    /// TODO: implement using an index
//    std::function<boost::optional<variable_type>(const order_ptr_type<C>&)> helper;
//    helper = [&helper, &id](const order_ptr_type<C>& ptr)
//    -> boost::optional<variable_type>
//    {
//      if (not ptr)
//      {
//        return boost::optional<variable_type>();
//      }
//      if (ptr->identifier and id == *ptr->identifier)
//      {
//        return ptr->variable;
//      }
//      if (ptr->nested)
//      {
//        const auto res = helper(ptr->nested);
//        if (res)
//        {
//          return res;
//        }
//      }
//      return helper(ptr->next);
//    };
//
//    const auto res = helper(order_ptr_);
//    if (res)
//    {
//      return *res;
//    }
//    else
//    {
//      throw std::runtime_error("Identifier not found.");
//    }
//  }

  order_builder&
  add(const identifier_type& id)
  {
    return add(id, nullptr);
  }

  order_builder&
  add(const identifier_type& id, const order_builder& nested)
  {
    return add(id, nested.order_ptr_);
  }

  order_builder&
  radd(const identifier_type& id)
  {
    // add à la fin de l'ordre
    // utiliser concat?
  }

  order_builder&
  radd(const identifier_type& id, const order_builder& nested)
  {
    // add à la fin de l'ordre
    // utiliser concat?
  }

  void
  concat(const order_builder& next)
  {
    order_builder_ptr_type<C> current = order_ptr_;
    while (current->next)
    {
      current = current->next;
    }
    current->next = next.order_ptr_;
  }

private:

  order_builder&
  add(const identifier_type& id, order_builder_ptr_type<C> nested_ptr)
  {
    const variable_type var = empty()
                            ? conf::variable_traits<variable_type>::first()
                            : conf::variable_traits<variable_type>::next(variable());

    typedef std::unique_ptr<identifier_type> optional_id_type;

    order_ptr_ =
      std::make_shared<order_builder_node<C>>( var
                                             , optional_id_type(new identifier_type(id))
                                             , nested_ptr
                                             , order_ptr_);
    return *this;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @related order_builder
//template <typename C>
//std::ostream&
//operator<<(std::ostream& os, const order_builder<C>& o)
//{
//  if (not o.empty())
//  {
//    os << o.identifier();
//    if (not o.nested().empty())
//    {
//      os << " | (" << o.nested() << ")";
//    }
//    if (not o.next().empty())
//    {
//      os << " >> " << o.next();
//    }
//  }
//  return os;
//}

/*-------------------------------------------------------------------------------------------*/

//template <typename C>
//class order;
//
//template <typename C>
//using order_ptr_type = std::shared_ptr<order<C>>;
//
//template <typename C>
//struct order_node
//{
//  /// @brief
//  typedef typename C::Identifier identifier_type;
//
//  /// @brief
//  typedef typename C::Variable variable_type;
//
//  /// @brief
//  const identifier_type identifier_;
//
//  /// @brief
//  const variable_type variable_;
//
//  /// @brief Absolute position, when seeing the order as flatten.
//  ///
//  /// Used to establish a total order on identifiers.
//  const std::size_t pos_;
//
//  /// @brief The set of identifiers containing this identifier.
//  const std::vector<identifier_type> parents_
//
//  /// @brief The nested order, if any, at this identifier.
//  const order_ptr_type nested_;
//};

/*-------------------------------------------------------------------------------------------*/

/// @brief
template <typename C>
class order
{
public:

  /// @brief
  typedef typename C::Identifier identifier_type;

  /// @brief
  typedef typename C::Variable variable_type;

private:

  /// @brief
//  typedef std::vector<order_node<C>> node_vec_type;

  /// @brief
//  typedef std::shared_ptr<node_vec_type> node_vec_ptr_type;

  /// @brief
//  typedef std::unordered_map<identifier_type, const order_node*> index_type;

  /// @brief
//  typedef std::shared_ptr<index_type> index_ptr_type;

public:

  order(const order_builder<C>& builder)
//    : order_ptr_(construct_order_ptr(builder))
//    , index_ptr_(construct_indexptr(order_ptr_))
  {
  }

  bool
  compare(const identifier_type& lhs, const identifier_type& rhs)
  const
  {

  }

  bool
  contains(const identifier_type& upper, const identifier_type& nested)
  const
  {
  }

  /// @brief Get the variable of an identifier
  variable_type
  identifier_variable(const identifier_type& id)
  const
  {

  }

  const variable_type&
  variable()
  const noexcept
  {
  }

  const identifier_type&
  identifier()
  const noexcept
  {
  }

  order
  next()
  const noexcept
  {

  }

  order
  nested()
  const noexcept
  {

  }

  bool
  empty()
  const noexcept
  {

  }

private:

//  static
//  order_ptr_type<C>
//  construct_order_ptr(const order_builder& ob)
//  {
//
//  }
//
//  static
//  std::unordered_map<identifier_type, const order_node*>
//  construct_index(const order_ptr_type<C>& o_ptr)
//  {
//
//  }
};

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::order

#endif // _SDD_ORDER_ORDER_HH_
<commit_msg>New order implementation using a two steps method.<commit_after>#ifndef _SDD_ORDER_ORDER_HH_
#define _SDD_ORDER_ORDER_HH_

#include <initializer_list>
#include <iostream>
#include <memory>  // shared_ptr, unique_ptr
#include <sstream>
#include <utility> // pair
#include <vector>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/ordered_index.hpp>

#include "sdd/conf/variable_traits.hh"

namespace sdd { namespace order {

namespace bmi = boost::multi_index;

/*-------------------------------------------------------------------------------------------*/

/// @brief Prepare an order to build.
template <typename C>
class order_builder
{
public:

  /// @brief The type of a variable.
  typedef typename C::Variable variable_type;

  /// @brief The type of an identifier.
  typedef typename C::Identifier identifier_type;

private:

  // Pre-declaration of a node.
  struct node;

  /// @brief The type of a pointer to a node.
  ///
  /// It's the actual reprensation of an order to build
  typedef std::shared_ptr<node> node_ptr;

  /// @brief The building block of an order_builder.
  struct node
  {
    /// @brief The user identifier.
    ///
    /// When nullptr, it's an artificial node. That is, a node generated by the library.
    const std::unique_ptr<identifier_type> identifier;

    /// @brief The nested order.
    ///
    /// If nullptr, this node is a flat node.
    const node_ptr nested;

    /// @brief The node's next variable.
    ///
    /// If nullptr, this node is the last one.
    const node_ptr next;

    /// @brief Constructor.
    node( std::unique_ptr<identifier_type>&& id, const node_ptr& nst, const node_ptr& nxt)
      : identifier(std::move(id))
      , nested(nst)
      , next(nxt)
    {
    }
  };

  /// @brief The concrete order.
  node_ptr order_ptr_;

public:

  /// @brief Default constructor.
  order_builder()
    : order_ptr_(nullptr)
  {
  }

  /// @brief Constructor from a list of identifiers.
  template <typename InputIterator>
  order_builder(InputIterator begin, InputIterator end)
    : order_builder()
  {
    std::vector<identifier_type> tmp(begin, end);
    for (auto rcit = tmp.crbegin(); rcit != tmp.crend(); ++rcit)
    {
      add(*rcit);
    }
  }

  /// @brief Constructor from a list of identifiers.
  order_builder(std::initializer_list<identifier_type> list)
    : order_builder(list.begin(), list.end())
  {
  }

  /// @brief Tell if this order is empty.
  ///
  /// It's unsafe to call any other method, except add(), if this order is empty.
  bool
  empty()
  const noexcept
  {
    return not order_ptr_;
  }

  /// @brief Get the idetifier of this order's head.
  const identifier_type&
  identifier()
  const noexcept
  {
    return *order_ptr_->identifier;
  }

  /// @brief Get this order's head's next order.
  order_builder
  next()
  const noexcept
  {
    return order_builder(order_ptr_->next);
  }

  /// @brief Get this order's head's nested order.
  order_builder
  nested()
  const noexcept
  {
    return order_builder(order_ptr_->nested);
  }

  /// @brief Add a flat identifier at the top of this order.
  order_builder&
  add(const identifier_type& id)
  {
    return add(id, nullptr);
  }

  /// @brief Add a nested identifier at the top of this order.
  order_builder&
  add(const identifier_type& id, const order_builder& nested)
  {
    return add(id, nested.order_ptr_);
  }

  /// @brief Concatenate an order at the end of this one.
  void
  concat(const order_builder& next)
  {
    node_ptr current = order_ptr_;
    while (current->next)
    {
      current = current->next;
    }
    current->next = next.order_ptr_;
  }

private:

  /// @brief Constructor from an already existing pointer.
  order_builder(const node_ptr& ptr)
    : order_ptr_(ptr)
  {
  }

  /// @brief Actual implementation of add.
  order_builder&
  add(const identifier_type& id, const node_ptr& nested_ptr)
  {
    typedef std::unique_ptr<identifier_type> optional_id_type;

    order_ptr_ =
      std::make_shared<node>( optional_id_type(new identifier_type(id))
                            , nested_ptr
                            , order_ptr_);
    return *this;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Represent an order of identifiers, possibly with some hierarchy.
///
/// It helps associate a variable (generated by the library) in an SDD to an identifiers
/// (provided to the user). An identifier should appear only once by order.
template <typename C>
class order
{
public:

  /// @brief A user's identifier type.
  typedef typename C::Identifier identifier_type;

  /// @brief A library's variable type.
  typedef typename C::Variable variable_type;

private:

  /// @brief A node in an order.
  ///
  /// An order is actually represented as a linked list of node.
  struct node
  {
    /// @brief The (user's) identifier of this node.
    const identifier_type identifier;

    /// @brief The (library's) variable of this node.
    const variable_type variable;

    /// @brief Absolute position, when seeing the order as flatten.
    ///
    /// Used to establish a total order on identifiers.
    const unsigned int position;

    /// @brief A pointer to following order's head.
    const node* next;

    /// @brief A pointer to the nested order's head.
    const node* nested;

    /// @brief The path to this node.
    const std::shared_ptr<std::vector<identifier_type>> path_ptr;

    /// @brief Constructor.
    node( const identifier_type& id, const variable_type& var, unsigned int pos
        , const node* nxt, const node* nst
        , const std::shared_ptr<std::vector<identifier_type>>& path)
      : identifier(id)
      , variable(var)
      , position(pos)
      , next(nxt)
      , nested(nst)
      , path_ptr(path)
    {
    }

    /// @brief Compare two node using their abolute position.
    bool
    operator<(const node& other)
    const noexcept
    {
      return position < other.position;
    }
  };

  /// @brief Tag to access nodes using their absolute positions.
  struct by_position {};

  /// @brief Tag to access nodes using their identifiers.
  struct by_identifier {};

  /// @brief The type of the container of nodes.
  ///
  /// A boost::multi_index::multi_index_container is used in order to be able to access nodes
  /// using different criterions.
  typedef bmi::multi_index_container
          < node
          , bmi::indexed_by
            < // sort by node::operator<
              bmi::ordered_unique< bmi::tag<by_position>
                                 , bmi::identity<node>
                                 >

              // retrieve using identifier's hash
            , bmi::hashed_unique< bmi::tag<by_identifier>
                                , bmi::member<node, const identifier_type, &node::identifier>
                                , std::hash<identifier_type>
                                >
            >
          > nodes_type;

  /// @brief The concrete order.
  const std::shared_ptr<nodes_type> nodes_ptr_;

  /// @brief The first node in the order.
  const node* head_;

public:

  /// @brief Constructor.
  order(const order_builder<C>& builder)
    : nodes_ptr_(mk_nodes_ptr(builder))
    , head_(mk_head())
  {
  }

  /// @brief Tell if lhs is before rhs in this order.
  ///
  /// Here, 'before' mean that the order is seen as flatten and thus that an hierarchical
  /// identifier is located before its nested identifiers.
  bool
  compare(const identifier_type& lhs, const identifier_type& rhs)
  const
  {
    const auto& identifiers = nodes_ptr_->template get<by_identifier>();

    const auto lhs_search = identifiers.find(lhs);
    if (lhs_search == identifiers.end())
    {
      std::stringstream ss;
      ss << "Identifier " << lhs << " not found";
      throw std::runtime_error(ss.str());
    }

    const auto rhs_search = identifiers.find(rhs);
    if (rhs_search == identifiers.end())
    {
      std::stringstream ss;
      ss << "Identifier " << rhs << " not found";
      throw std::runtime_error(ss.str());
    }

    return lhs_search->position < rhs_search->position;
  }

  /// @brief Tell if upper contains nested in its possibily contained hierarchy.
  bool
  contains(const identifier_type& upper, const identifier_type& nested)
  const noexcept
  {
    const auto& identifiers = nodes_ptr_->template get<by_identifier>();

    const auto search = identifiers.find(nested);
    if (search == identifiers.end())
    {
      return false;
    }
    else
    {
      return search->path.find(upper) != search->path.end();
    }
  }

  /// @brief Get the variable of an identifier
  variable_type
  identifier_variable(const identifier_type& id)
  const
  {
    const auto& identifiers = nodes_ptr_->template get<by_identifier>();
    const auto search = identifiers.find(id);
    if (search == identifiers.end())
    {
      std::stringstream ss;
      ss << "Identifier " << id << " not found";
      throw std::runtime_error(ss.str());
    }
    return search->variable;
  }

  /// @brief Get the variable of this order's head.
  const variable_type&
  variable()
  const
  {
    if (head_)
    {
      return head_->variable;
    }
    else
    {
      throw std::runtime_error("Calling variable() on an empty order.");
    }
  }

  /// @brief Get the identifier of this order's head.
  const identifier_type&
  identifier()
  const
  {
    if (head_)
    {
      return head_->identifier;
    }
    else
    {
      throw std::runtime_error("Calling identifier() on an empty order.");
    }
  }

  /// @brief Get the next order of this order's head.
  order
  next()
  const
  {
    if (head_)
    {
      return order(nodes_ptr_, head_->next);
    }
    else
    {
      throw std::runtime_error("Calling next() on an empty order.");
    }
  }

  /// @brief Get the nested order of this order's head.
  order
  nested()
  const
  {
    if (head_)
    {
      return order(nodes_ptr_, head_->nested);
    }
    else
    {
      throw std::runtime_error("Calling nested() on an empty order.");
    }
  }

  /// @brief Tell if this order is empty.
  bool
  empty()
  const noexcept
  {
    return head_ == nullptr;
  }

private:

  /// @brief Construct whith a shallow copy an already existing order.
  order(const std::shared_ptr<nodes_type>& ptr, const node* head)
    : nodes_ptr_(ptr)
    , head_(head)
  {
  }

  /// @brief Create the concrete order using an order_builder.
  static
  std::shared_ptr<nodes_type>
  mk_nodes_ptr(const order_builder<C>& builder)
  {
    std::shared_ptr<nodes_type> nodes_ptr = std::make_shared<nodes_type>();

    if (builder.empty())
    {
      return nodes_ptr;
    }

    unsigned int pos = 0;

    // To enable recursion in the lambda.
    std::function<
      std::pair<const node*, variable_type>
      (const order_builder<C>&, const std::shared_ptr<std::vector<identifier_type>>&)
    > helper;

    helper = [&helper, &nodes_ptr, &pos]
    (const order_builder<C>& ob, const std::shared_ptr<std::vector<identifier_type>>& path)
    -> std::pair<const node*, unsigned int>
    {
      constexpr variable_type first_variable = conf::variable_traits<variable_type>::first();

      const unsigned int old_pos = pos++;

      std::pair<const node*, variable_type> nested(nullptr, first_variable);
      std::pair<const node*, variable_type> next(nullptr, first_variable);

      if (not ob.nested().empty())
      {
        const auto new_path = std::make_shared<std::vector<identifier_type>>(*path);
        new_path->push_back(ob.identifier());
        new_path->shrink_to_fit();
        nested = helper(ob.nested(), new_path);
      }

      if (not ob.next().empty())
      {
        next = helper(ob.next(), path);
      }

      const auto& variable = next.second;
      const node n(ob.identifier(), variable, old_pos, next.first, nested.first, path);

      const auto insertion = nodes_ptr->insert(n);
      if (not insertion.second)
      {
        std::stringstream ss;
        ss << "Duplicate identifier " << ob.identifier();
        throw std::runtime_error(ss.str());
      }
      return std::make_pair( &*(insertion.first)
                           , conf::variable_traits<variable_type>::next(variable));
    };

    helper(builder, std::make_shared<std::vector<identifier_type>>());

    return nodes_ptr;
  }

  /// @brief Get the first node in the order.
  const node*
  mk_head()
  const noexcept
  {
    const auto& positions = nodes_ptr_->template get<by_position>();
    const auto begin = positions.begin();
    return begin == positions.end() ? nullptr : &*begin;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Textual representation of an order.
/// @related order
template <typename C>
std::ostream&
operator<<(std::ostream& os, const order<C>& ord)
{
  std::function<std::ostream&(const order<C>&, unsigned int)> helper;
  helper = [&helper, &os](const order<C>& o, unsigned int indent)
  -> std::ostream&
  {
    if (not o.empty())
    {
      const std::string spaces(indent, ' ');
      os << spaces << o.identifier()  << std::endl;
      if (not o.nested().empty())
      {
        helper(o.nested(), indent + 2);
      }
      if (not o.next().empty())
      {
        helper(o.next(), indent);
      }
    }
    return os;
  };
  return helper(ord, 0);
}

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::order

#endif // _SDD_ORDER_ORDER_HH_
<|endoftext|>


<commit_before>#include <StdAfx.h>
#include <UI/Controls/PaneHeader/PaneHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/strings.h>
#include <core/utility/output.h>

namespace controls
{
	void PaneHeader::Initialize(_In_ CWnd* pParent, _In_opt_ HDC hdc, _In_ UINT nid)
	{
		if (pParent) m_hWndParent = pParent->m_hWnd;
		// Assign a nID to the collapse button that is IDD_COLLAPSE more than the control's nID
		m_nIDCollapse = nid + IDD_COLLAPSE;
		// TODO: We don't save our header's nID here, but we could if we wanted

		EC_B_S(Create(
			WS_CHILD | WS_CLIPSIBLINGS | ES_READONLY | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), pParent, nid));
		::SetWindowTextW(m_hWnd, m_szLabel.c_str());
		ui::SubclassLabel(m_hWnd);

		EC_B_S(m_rightLabel.Create(
			WS_CHILD | WS_CLIPSIBLINGS | ES_READONLY | WS_VISIBLE | WS_TABSTOP,
			CRect(0, 0, 0, 0),
			pParent,
			IDD_COUNTLABEL));
		ui::SubclassLabel(m_rightLabel.m_hWnd);
		StyleLabel(m_rightLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderText);

		if (m_bCollapsible)
		{
			StyleLabel(m_hWnd, ui::uiLabelStyle::PaneHeaderLabel);

			EC_B_S(m_CollapseButton.Create(
				nullptr,
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
				CRect(0, 0, 0, 0),
				pParent,
				m_nIDCollapse));
			StyleButton(
				m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		}

		const auto sizeText = ui::GetTextExtentPoint32(hdc, m_szLabel);
		m_iLabelWidth = sizeText.cx;
		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::Initialize m_iLabelWidth:%d \"%ws\"\n",
			m_iLabelWidth,
			m_szLabel.c_str());

		// If we need an action button, go ahead and create it
		if (m_nIDAction)
		{
			EC_B_S(m_actionButton.Create(
				strings::wstringTotstring(m_szActionButton).c_str(),
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
				CRect(0, 0, 0, 0),
				pParent,
				m_nIDAction));
			StyleButton(m_actionButton.m_hWnd, ui::uiButtonStyle::Unstyled);
		}

		m_bInitialized = true;
	}

	// Draw our collapse button and label, if needed.
	// Draws everything to GetFixedHeight()
	void PaneHeader::DeferWindowPos(_In_ HDWP hWinPosInfo, const _In_ int x, const _In_ int y, const _In_ int width)
	{
		const auto height = GetFixedHeight();
		auto curX = x;
		const auto actionButtonWidth = m_actionButtonWidth ? m_actionButtonWidth + 2 * m_iMargin : 0;
		const auto actionButtonAndGutterWidth = actionButtonWidth ? actionButtonWidth + m_iSideMargin : 0;
		if (m_bCollapsible)
		{
			::DeferWindowPos(
				hWinPosInfo,
				m_CollapseButton.GetSafeHwnd(),
				nullptr,
				curX,
				y,
				width - actionButtonAndGutterWidth,
				height,
				SWP_NOZORDER);
			curX += m_iButtonHeight;
		}

		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::DeferWindowPos x:%d width:%d labelpos:%d labelwidth:%d \n",
			x,
			width,
			curX,
			m_iLabelWidth);

		::DeferWindowPos(hWinPosInfo, GetSafeHwnd(), nullptr, curX, y, m_iLabelWidth, height, SWP_NOZORDER);

		if (!m_bCollapsed)
		{
			// Drop the count on top of the label we drew above
			EC_B_S(::DeferWindowPos(
				hWinPosInfo,
				m_rightLabel.GetSafeHwnd(),
				nullptr,
				x + width - m_rightLabelWidth - actionButtonAndGutterWidth,
				y,
				m_rightLabelWidth,
				height,
				SWP_NOZORDER));
		}

		if (m_nIDAction)
		{
			// Drop the action button next to the label we drew above
			EC_B_S(::DeferWindowPos(
				hWinPosInfo,
				m_actionButton.GetSafeHwnd(),
				nullptr,
				x + width - actionButtonWidth,
				y,
				actionButtonWidth,
				height,
				SWP_NOZORDER));
		}
	}

	int PaneHeader::GetMinWidth()
	{
		auto cx = m_iLabelWidth;
		if (m_bCollapsible) cx += m_iButtonHeight;
		if (m_rightLabelWidth)
		{
			cx += m_iSideMargin;
			cx += m_rightLabelWidth;
		}

		if (m_actionButtonWidth)
		{
			cx += m_iSideMargin;
			cx += m_actionButtonWidth + 2 * m_iMargin;
		}

		return cx;
	}

	void PaneHeader::SetRightLabel(const std::wstring szLabel)
	{
		if (!m_bInitialized) return;
		EC_B_S(::SetWindowTextW(m_rightLabel.m_hWnd, szLabel.c_str()));

		const auto hdc = ::GetDC(m_rightLabel.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szLabel);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_rightLabel.GetSafeHwnd(), hdc);
		m_rightLabelWidth = sizeText.cx;
	}

	void PaneHeader::SetActionButton(const std::wstring szActionButton)
	{
		// Don't bother if we never enabled the button
		if (m_nIDAction == 0) return;

		EC_B_S(::SetWindowTextW(m_actionButton.GetSafeHwnd(), szActionButton.c_str()));

		m_szActionButton = szActionButton;
		const auto hdc = ::GetDC(m_actionButton.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szActionButton);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_actionButton.GetSafeHwnd(), hdc);
		m_actionButtonWidth = sizeText.cx;
	}

	bool PaneHeader::HandleChange(UINT nID)
	{
		// Collapse buttons have a nID IDD_COLLAPSE higher than nID of the pane they toggle.
		// So if we get asked about one that matches, we can assume it's time to toggle our collapse.
		if (m_nIDCollapse == nID)
		{
			OnToggleCollapse();
			return true;
		}

		return false;
	}

	void PaneHeader::OnToggleCollapse()
	{
		m_bCollapsed = !m_bCollapsed;

		StyleButton(m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		WC_B_S(m_rightLabel.ShowWindow(m_bCollapsed ? SW_HIDE : SW_SHOW));

		// Trigger a redraw
		::PostMessage(m_hWndParent, WM_COMMAND, IDD_RECALCLAYOUT, NULL);
	}

	void PaneHeader::SetMargins(
		int iMargin,
		int iSideMargin,
		int iLabelHeight, // Height of the label
		int iButtonHeight) // Height of button
	{
		m_iMargin = iMargin;
		m_iSideMargin = iSideMargin;
		m_iLabelHeight = iLabelHeight;
		m_iButtonHeight = iButtonHeight;
	}
} // namespace controls<commit_msg>move styling up with creation<commit_after>#include <StdAfx.h>
#include <UI/Controls/PaneHeader/PaneHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/strings.h>
#include <core/utility/output.h>

namespace controls
{
	void PaneHeader::Initialize(_In_ CWnd* pParent, _In_opt_ HDC hdc, _In_ UINT nid)
	{
		if (pParent) m_hWndParent = pParent->m_hWnd;
		// Assign a nID to the collapse button that is IDD_COLLAPSE more than the control's nID
		m_nIDCollapse = nid + IDD_COLLAPSE;
		// TODO: We don't save our header's nID here, but we could if we wanted

		EC_B_S(Create(
			WS_CHILD | WS_CLIPSIBLINGS | ES_READONLY | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), pParent, nid));
		::SetWindowTextW(m_hWnd, m_szLabel.c_str());
		ui::SubclassLabel(m_hWnd);
		if (m_bCollapsible)
		{
			StyleLabel(m_hWnd, ui::uiLabelStyle::PaneHeaderLabel);
		}

		EC_B_S(m_rightLabel.Create(
			WS_CHILD | WS_CLIPSIBLINGS | ES_READONLY | WS_VISIBLE | WS_TABSTOP,
			CRect(0, 0, 0, 0),
			pParent,
			IDD_COUNTLABEL));
		ui::SubclassLabel(m_rightLabel.m_hWnd);
		StyleLabel(m_rightLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderText);

		if (m_bCollapsible)
		{
			EC_B_S(m_CollapseButton.Create(
				nullptr,
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
				CRect(0, 0, 0, 0),
				pParent,
				m_nIDCollapse));
			StyleButton(
				m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		}

		const auto sizeText = ui::GetTextExtentPoint32(hdc, m_szLabel);
		m_iLabelWidth = sizeText.cx;
		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::Initialize m_iLabelWidth:%d \"%ws\"\n",
			m_iLabelWidth,
			m_szLabel.c_str());

		// If we need an action button, go ahead and create it
		if (m_nIDAction)
		{
			EC_B_S(m_actionButton.Create(
				strings::wstringTotstring(m_szActionButton).c_str(),
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
				CRect(0, 0, 0, 0),
				pParent,
				m_nIDAction));
			StyleButton(m_actionButton.m_hWnd, ui::uiButtonStyle::Unstyled);
		}

		m_bInitialized = true;
	}

	// Draw our collapse button and label, if needed.
	// Draws everything to GetFixedHeight()
	void PaneHeader::DeferWindowPos(_In_ HDWP hWinPosInfo, const _In_ int x, const _In_ int y, const _In_ int width)
	{
		const auto height = GetFixedHeight();
		auto curX = x;
		const auto actionButtonWidth = m_actionButtonWidth ? m_actionButtonWidth + 2 * m_iMargin : 0;
		const auto actionButtonAndGutterWidth = actionButtonWidth ? actionButtonWidth + m_iSideMargin : 0;
		if (m_bCollapsible)
		{
			::DeferWindowPos(
				hWinPosInfo,
				m_CollapseButton.GetSafeHwnd(),
				nullptr,
				curX,
				y,
				width - actionButtonAndGutterWidth,
				height,
				SWP_NOZORDER);
			curX += m_iButtonHeight;
		}

		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::DeferWindowPos x:%d width:%d labelpos:%d labelwidth:%d \n",
			x,
			width,
			curX,
			m_iLabelWidth);

		::DeferWindowPos(hWinPosInfo, GetSafeHwnd(), nullptr, curX, y, m_iLabelWidth, height, SWP_NOZORDER);

		if (!m_bCollapsed)
		{
			// Drop the count on top of the label we drew above
			EC_B_S(::DeferWindowPos(
				hWinPosInfo,
				m_rightLabel.GetSafeHwnd(),
				nullptr,
				x + width - m_rightLabelWidth - actionButtonAndGutterWidth,
				y,
				m_rightLabelWidth,
				height,
				SWP_NOZORDER));
		}

		if (m_nIDAction)
		{
			// Drop the action button next to the label we drew above
			EC_B_S(::DeferWindowPos(
				hWinPosInfo,
				m_actionButton.GetSafeHwnd(),
				nullptr,
				x + width - actionButtonWidth,
				y,
				actionButtonWidth,
				height,
				SWP_NOZORDER));
		}
	}

	int PaneHeader::GetMinWidth()
	{
		auto cx = m_iLabelWidth;
		if (m_bCollapsible) cx += m_iButtonHeight;
		if (m_rightLabelWidth)
		{
			cx += m_iSideMargin;
			cx += m_rightLabelWidth;
		}

		if (m_actionButtonWidth)
		{
			cx += m_iSideMargin;
			cx += m_actionButtonWidth + 2 * m_iMargin;
		}

		return cx;
	}

	void PaneHeader::SetRightLabel(const std::wstring szLabel)
	{
		if (!m_bInitialized) return;
		EC_B_S(::SetWindowTextW(m_rightLabel.m_hWnd, szLabel.c_str()));

		const auto hdc = ::GetDC(m_rightLabel.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szLabel);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_rightLabel.GetSafeHwnd(), hdc);
		m_rightLabelWidth = sizeText.cx;
	}

	void PaneHeader::SetActionButton(const std::wstring szActionButton)
	{
		// Don't bother if we never enabled the button
		if (m_nIDAction == 0) return;

		EC_B_S(::SetWindowTextW(m_actionButton.GetSafeHwnd(), szActionButton.c_str()));

		m_szActionButton = szActionButton;
		const auto hdc = ::GetDC(m_actionButton.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szActionButton);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_actionButton.GetSafeHwnd(), hdc);
		m_actionButtonWidth = sizeText.cx;
	}

	bool PaneHeader::HandleChange(UINT nID)
	{
		// Collapse buttons have a nID IDD_COLLAPSE higher than nID of the pane they toggle.
		// So if we get asked about one that matches, we can assume it's time to toggle our collapse.
		if (m_nIDCollapse == nID)
		{
			OnToggleCollapse();
			return true;
		}

		return false;
	}

	void PaneHeader::OnToggleCollapse()
	{
		m_bCollapsed = !m_bCollapsed;

		StyleButton(m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		WC_B_S(m_rightLabel.ShowWindow(m_bCollapsed ? SW_HIDE : SW_SHOW));

		// Trigger a redraw
		::PostMessage(m_hWndParent, WM_COMMAND, IDD_RECALCLAYOUT, NULL);
	}

	void PaneHeader::SetMargins(
		int iMargin,
		int iSideMargin,
		int iLabelHeight, // Height of the label
		int iButtonHeight) // Height of button
	{
		m_iMargin = iMargin;
		m_iSideMargin = iSideMargin;
		m_iLabelHeight = iLabelHeight;
		m_iButtonHeight = iButtonHeight;
	}
} // namespace controls<|endoftext|>


<commit_before>//
//
//
//

#include <cassert>
#include <Svmpp.h>

using namespace std;
using namespace svmpp;

int main(int _argc, char **_argv) {

}<commit_msg>Codded rbfKernel test<commit_after>//
//
//
//

#include <cassert>
#include <cmath>
#include <Svmpp.h>

using namespace std;
using namespace svmpp;

int main(int _argc, char **_argv) {

	TrainSet set;

	for (unsigned i = 0; i < 90; i++) {
		set.addEntry({2*cos(4*(i*3.1416/180)), 2*sin(4*(i*3.1416/180))}, 0);
	}

	for (unsigned i = 0; i < 90; i++) {
		set.addEntry({0.5*cos(4*(i*3.1416/180)), 0.5*sin(4*(i*3.1416/180))}, 1);
	}

	Svm svm;

	// Setting parameters
	Svm::Params params;
	params.svm_type = C_SVC;
	params.kernel_type = RBF;
	params.cache_size = 100;
	params.gamma = 0.01;
	params.C = 10;
	params.eps = 1e-5;
	params.p = 0.1;
	params.shrinking = 0;
	params.probability = 0;
	params.nr_weight = 0;
	params.weight_label = nullptr;
	params.weight = nullptr;

	svm.train(params, set);

	// Evaluate data
	Query query1({0,0});
	double res1 = svm.predict(query1);
	assert(res1 == 1);

	Query query2({3,3});
	double res2 = svm.predict(query2);
	assert(res2 == 0);

}<|endoftext|>