<commit_before>#include <StdAfx.h>
#include <MrMapi/MMNamedProps.h>
#include <MrMapi/mmcli.h>
#include <core/mapi/processor/mapiProcessor.h>
#include <core/mapi/extraPropTags.h>
#include <core/smartview/SmartView.h>
#include <core/utility/strings.h>
#include <core/utility/registry.h>
#include <core/utility/output.h>
#include <core/mapi/mapiFunctions.h>

void PrintGuid(const GUID& lpGuid)
{
	wprintf(
		L"%.8lX-%.4X-%.4X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X",
		lpGuid.Data1,
		lpGuid.Data2,
		lpGuid.Data3,
		lpGuid.Data4[0],
		lpGuid.Data4[1],
		lpGuid.Data4[2],
		lpGuid.Data4[3],
		lpGuid.Data4[4],
		lpGuid.Data4[5],
		lpGuid.Data4[6],
		lpGuid.Data4[7]);
}

class NamedPropEntry
{
public:

	NamedPropEntry(ULONG propTag, LPGUID lpGuid, LPWSTR name)
	{
		this->Kind = MNID_STRING;
		this->PropTag = propTag;
		this->PropSetGuid = *lpGuid;
		this->PropName = name;
	}

	NamedPropEntry(ULONG propTag, LPGUID lpGuid, ULONG id)
	{
		this->Kind = MNID_ID;
		this->PropTag = propTag;
		this->PropSetGuid = *lpGuid;
		this->PropId = id;
	}

	ULONG PropTag = 0;
	GUID PropSetGuid = { 0 };
	ULONG Kind = 0;
	std::wstring PropName;
	ULONG PropId = 0;
};

void DoNamedProps(_In_opt_ LPMDB lpMDB)
{
	auto hRes = S_OK;
	wprintf(L"Dumping named properties...\n");

	ULONG cPropNames = 0;
	LPSPropTagArray pProps = nullptr;
	LPMAPINAMEID* pNames = nullptr;
	hRes = WC_MAPI(lpMDB->GetNamesFromIDs(&pProps, nullptr, 0, &cPropNames, &pNames));

	if (SUCCEEDED(hRes))
	{
		wprintf(L"\n");
		std::vector<NamedPropEntry> props;
		for (std::uint32_t i = 0; i < cPropNames; i++)
		{
			switch (pNames[i]->ulKind)
			{
			case MNID_STRING:
				props.emplace_back(pProps->aulPropTag[i], pNames[i]->lpguid, pNames[i]->Kind.lpwstrName);
				break;
			case MNID_ID:
				props.emplace_back(pProps->aulPropTag[i], pNames[i]->lpguid, pNames[i]->Kind.lID);
				break;
			}
		}

		std::sort(props.begin(), props.end(), [](NamedPropEntry& i, NamedPropEntry& j) {
			// If the Property set GUIDs don't match, sort by that
			auto res = memcmp(&i.PropSetGuid, &j.PropSetGuid, sizeof(GUID));
			if (res) return res < 0;

			// If they are different kinds, use that next
			if (i.Kind != j.Kind)
			{
				return i.Kind < j.Kind;
			}

			switch (i.Kind)
			{
			case MNID_ID:
				return i.PropId < j.PropId;
			case MNID_STRING:
				return i.PropName < j.PropName;
			}

			// This shouldn't ever actually hit
			return i.PropTag < j.PropTag;
		});

		for (size_t i = 0; i < props.size(); i++)
		{
			wprintf(L"[%08x] (", props[i].PropTag);
			PrintGuid(props[i].PropSetGuid);
			switch (props[i].Kind)
			{
			case MNID_ID:
				wprintf(L":0x%08x)\n", props[i].PropId);
				break;

			case MNID_STRING:
				wprintf(L":%ws)\n", props[i].PropName.c_str());
				break;
			}
		}
	}
	else
	{
		wprintf(L"FAILED. Error 0x%x\n", hRes);
	}

	if (pProps) MAPIFreeBuffer(pProps);
	if (pNames) MAPIFreeBuffer(pNames);
}<commit_msg>formatting<commit_after>#include <StdAfx.h>
#include <MrMapi/MMNamedProps.h>
#include <MrMapi/mmcli.h>
#include <core/mapi/processor/mapiProcessor.h>
#include <core/mapi/extraPropTags.h>
#include <core/smartview/SmartView.h>
#include <core/utility/strings.h>
#include <core/utility/registry.h>
#include <core/utility/output.h>
#include <core/mapi/mapiFunctions.h>

void PrintGuid(const GUID& lpGuid)
{
	wprintf(
		L"%.8lX-%.4X-%.4X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X",
		lpGuid.Data1,
		lpGuid.Data2,
		lpGuid.Data3,
		lpGuid.Data4[0],
		lpGuid.Data4[1],
		lpGuid.Data4[2],
		lpGuid.Data4[3],
		lpGuid.Data4[4],
		lpGuid.Data4[5],
		lpGuid.Data4[6],
		lpGuid.Data4[7]);
}

class NamedPropEntry
{
public:
	NamedPropEntry(ULONG propTag, LPGUID lpGuid, LPWSTR name)
	{
		this->Kind = MNID_STRING;
		this->PropTag = propTag;
		this->PropSetGuid = *lpGuid;
		this->PropName = name;
	}

	NamedPropEntry(ULONG propTag, LPGUID lpGuid, ULONG id)
	{
		this->Kind = MNID_ID;
		this->PropTag = propTag;
		this->PropSetGuid = *lpGuid;
		this->PropId = id;
	}

	ULONG PropTag = 0;
	GUID PropSetGuid = {0};
	ULONG Kind = 0;
	std::wstring PropName;
	ULONG PropId = 0;
};

void DoNamedProps(_In_opt_ LPMDB lpMDB)
{
	auto hRes = S_OK;
	wprintf(L"Dumping named properties...\n");

	ULONG cPropNames = 0;
	LPSPropTagArray pProps = nullptr;
	LPMAPINAMEID* pNames = nullptr;
	hRes = WC_MAPI(lpMDB->GetNamesFromIDs(&pProps, nullptr, 0, &cPropNames, &pNames));

	if (SUCCEEDED(hRes))
	{
		wprintf(L"\n");
		std::vector<NamedPropEntry> props;
		for (std::uint32_t i = 0; i < cPropNames; i++)
		{
			switch (pNames[i]->ulKind)
			{
			case MNID_STRING:
				props.emplace_back(pProps->aulPropTag[i], pNames[i]->lpguid, pNames[i]->Kind.lpwstrName);
				break;
			case MNID_ID:
				props.emplace_back(pProps->aulPropTag[i], pNames[i]->lpguid, pNames[i]->Kind.lID);
				break;
			}
		}

		std::sort(props.begin(), props.end(), [](NamedPropEntry& i, NamedPropEntry& j) {
			// If the Property set GUIDs don't match, sort by that
			auto res = memcmp(&i.PropSetGuid, &j.PropSetGuid, sizeof(GUID));
			if (res) return res < 0;

			// If they are different kinds, use that next
			if (i.Kind != j.Kind)
			{
				return i.Kind < j.Kind;
			}

			switch (i.Kind)
			{
			case MNID_ID:
				return i.PropId < j.PropId;
			case MNID_STRING:
				return i.PropName < j.PropName;
			}

			// This shouldn't ever actually hit
			return i.PropTag < j.PropTag;
		});

		for (size_t i = 0; i < props.size(); i++)
		{
			wprintf(L"[%08x] (", props[i].PropTag);
			PrintGuid(props[i].PropSetGuid);
			switch (props[i].Kind)
			{
			case MNID_ID:
				wprintf(L":0x%08x)\n", props[i].PropId);
				break;

			case MNID_STRING:
				wprintf(L":%ws)\n", props[i].PropName.c_str());
				break;
			}
		}
	}
	else
	{
		wprintf(L"FAILED. Error 0x%x\n", hRes);
	}

	if (pProps) MAPIFreeBuffer(pProps);
	if (pNames) MAPIFreeBuffer(pNames);
}<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkOpenGLLight.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>

#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLLight.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
#ifdef VTK_USE_QUARTZ
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
#include "vtkObjectFactory.h"

#ifndef VTK_IMPLEMENT_MESA_CXX
//------------------------------------------------------------------------------
vtkOpenGLLight* vtkOpenGLLight::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkOpenGLLight");
  if(ret)
    {
    return (vtkOpenGLLight*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkOpenGLLight;
}
#endif

// Implement base class method.
void vtkOpenGLLight::Render(vtkRenderer *vtkNotUsed(ren),int light_index)
{
  float	dx, dy, dz;
  float	color[4];
  float Info[4];
  vtkMatrix4x4 *xform = NULL;

  // get required info from light
  color[0] = this->Intensity * this->Color[0];
  color[1] = this->Intensity * this->Color[1];
  color[2] = this->Intensity * this->Color[2];
  color[3] = 1.0;

  dx = this->FocalPoint[0] - this->Position[0];
  dy = this->FocalPoint[1] - this->Position[1];
  dz = this->FocalPoint[2] - this->Position[2];

  if(this->TransformMatrix != NULL) {
    xform = vtkMatrix4x4::New();
    xform->DeepCopy(this->TransformMatrix);
    xform->Transpose();

    // code assumes that we're already in GL_MODELVIEW matrix mode
    glPushMatrix();
    glMultMatrixd(xform->Element[0]);
  }

  glLightfv((GLenum)light_index, GL_DIFFUSE, color);
  glLightfv((GLenum)light_index, GL_SPECULAR, color);

  // define the light source
  if (!this->Positional)
    {
    Info[0]  = -dx;
    Info[1]  = -dy;
    Info[2]  = -dz;
    Info[3]  = 0.0;
    glLightfv((GLenum)light_index, GL_POSITION, Info );
    }
  else
    {
    // specify position and attenuation
    Info[0]  = this->Position[0];
    Info[1]  = this->Position[1];
    Info[2]  = this->Position[2];
    Info[3]  = 1.0;
    glLightfv((GLenum)light_index, GL_POSITION, Info );

    glLightf((GLenum)light_index,
	     GL_CONSTANT_ATTENUATION, this->AttenuationValues[0]);
    glLightf((GLenum)light_index,
	     GL_LINEAR_ATTENUATION, this->AttenuationValues[1]);
    glLightf((GLenum)light_index,
	     GL_QUADRATIC_ATTENUATION, this->AttenuationValues[2]);

    // set up spot parameters if neccesary
    if (this->ConeAngle < 180.0)
      {
      Info[0] = dx;
      Info[1] = dy;
      Info[2] = dz;
      glLightfv((GLenum)light_index, GL_SPOT_DIRECTION, Info );
      glLightf((GLenum)light_index, GL_SPOT_EXPONENT, this->Exponent);
      glLightf((GLenum)light_index, GL_SPOT_CUTOFF, this->ConeAngle);
      }
    else
      {
      glLighti((GLenum)light_index, GL_SPOT_CUTOFF, 180);
      }
    }

  if(this->TransformMatrix != NULL) {
    glPopMatrix();
    xform->Delete();
  }
}

<commit_msg>The light has to reset certain properties if it is non-directional.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLLight.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>

#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLLight.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
#ifdef VTK_USE_QUARTZ
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
#include "vtkObjectFactory.h"

#ifndef VTK_IMPLEMENT_MESA_CXX
//------------------------------------------------------------------------------
vtkOpenGLLight* vtkOpenGLLight::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkOpenGLLight");
  if(ret)
    {
    return (vtkOpenGLLight*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkOpenGLLight;
}
#endif

// Implement base class method.
void vtkOpenGLLight::Render(vtkRenderer *vtkNotUsed(ren),int light_index)
{
  float	dx, dy, dz;
  float	color[4];
  float Info[4];
  vtkMatrix4x4 *xform = NULL;

  // get required info from light
  color[0] = this->Intensity * this->Color[0];
  color[1] = this->Intensity * this->Color[1];
  color[2] = this->Intensity * this->Color[2];
  color[3] = 1.0;

  dx = this->FocalPoint[0] - this->Position[0];
  dy = this->FocalPoint[1] - this->Position[1];
  dz = this->FocalPoint[2] - this->Position[2];

  if(this->TransformMatrix != NULL) {
    xform = vtkMatrix4x4::New();
    xform->DeepCopy(this->TransformMatrix);
    xform->Transpose();

    // code assumes that we're already in GL_MODELVIEW matrix mode
    glPushMatrix();
    glMultMatrixd(xform->Element[0]);
  }

  glLightfv((GLenum)light_index, GL_DIFFUSE, color);
  glLightfv((GLenum)light_index, GL_SPECULAR, color);

  // define the light source
  if (!this->Positional)
    {
    Info[0]  = -dx;
    Info[1]  = -dy;
    Info[2]  = -dz;
    Info[3]  = 0.0;

    glLightf((GLenum)light_index, GL_SPOT_EXPONENT, 0);
    glLightf((GLenum)light_index, GL_SPOT_CUTOFF, 180);

    glLightfv((GLenum)light_index, GL_POSITION, Info );
    }
  else
    {
    // specify position and attenuation
    Info[0]  = this->Position[0];
    Info[1]  = this->Position[1];
    Info[2]  = this->Position[2];
    Info[3]  = 1.0;
    glLightfv((GLenum)light_index, GL_POSITION, Info );

    glLightf((GLenum)light_index,
	     GL_CONSTANT_ATTENUATION, this->AttenuationValues[0]);
    glLightf((GLenum)light_index,
	     GL_LINEAR_ATTENUATION, this->AttenuationValues[1]);
    glLightf((GLenum)light_index,
	     GL_QUADRATIC_ATTENUATION, this->AttenuationValues[2]);

    // set up spot parameters if neccesary
    if (this->ConeAngle < 180.0)
      {
      Info[0] = dx;
      Info[1] = dy;
      Info[2] = dz;
      glLightfv((GLenum)light_index, GL_SPOT_DIRECTION, Info );
      glLightf((GLenum)light_index, GL_SPOT_EXPONENT, this->Exponent);
      glLightf((GLenum)light_index, GL_SPOT_CUTOFF, this->ConeAngle);
      }
    else
      {
      glLighti((GLenum)light_index, GL_SPOT_CUTOFF, 180);
      }
    }

  if(this->TransformMatrix != NULL) {
    glPopMatrix();
    xform->Delete();
  }
}

<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	ラップタイム
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/format.hpp"
#include "scenes_base.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ラップタイム・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class laptime {

		uint32_t	lap_best_t_;
		uint32_t	lap_best_n_;

		int16_t draw_time_(int16_t x, int16_t y, uint32_t t) noexcept
		{
			auto mod = t % 100;
			t /= 100;
			auto sec = t % 60;
			t /= 60;
			auto min = t % 60;
			t /= 60;
			auto hur = t % 24;
			char tmp[16];
			utils::sformat("%02d:%02d:%02d.%02d", tmp, sizeof(tmp))
				% hur % min % sec % mod;
			return at_scenes_base().at_render().draw_text(x, y, tmp);
		}

		int16_t draw_lap_(int16_t x, int16_t y, uint32_t no, uint32_t t) noexcept
		{
			char tmp[8];
			utils::sformat("%03d ", tmp, sizeof(tmp)) % no;
			x = at_scenes_base().at_render().draw_text(x, y, tmp);
			return draw_time_(x, y, t);
		}

	public:
		//-------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-------------------------------------------------------------//
		laptime() : lap_best_t_(0), lap_best_n_(0) { }

		//-------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-------------------------------------------------------------//
		void init()
		{
			at_scenes_base().at_cmt().at_task().enable();
			lap_best_t_ = 0;
			lap_best_n_ = 0;
		}

		//-------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-------------------------------------------------------------//
		void service()
		{
			typedef scenes_base::RENDER RENDER;

			auto& render = at_scenes_base().at_render();
			render.clear(RENDER::COLOR::Black);

			auto& watch = at_scenes_base().at_cmt().at_task();
			auto t = watch.get();
			auto pos = watch.get_lap_pos();
			uint32_t dt = t;
			if(pos > 0) {
				dt -= watch.get_lap(pos - 1);
			}

			int16_t y = 16;
			auto x = draw_lap_(0, y, pos, t);
			x = draw_time_(x + 8, y, dt);
			draw_lap_(x + 16, y, lap_best_n_, lap_best_t_);

			render.frame(0, RENDER::height - 10, RENDER::width, 10, RENDER::COLOR::White);
			uint32_t bt = 0;
			if(pos > 0) {
				bt = watch.get_lap(pos - 1);
				if(pos > 1) {
					bt -= watch.get_lap(pos - 2);
				}
				if(lap_best_t_ == 0 || lap_best_t_ > bt) {
					lap_best_t_ = bt;
					lap_best_n_ = pos;
				}
			}
			if(bt > 0) {
				uint32_t ref = RENDER::width - 2;
				uint32_t per = ref * dt / bt;
				auto c = RENDER::COLOR::Lime;
				if(per > ref) {
					per = ref;
					c = RENDER::COLOR::Red;
				}
				render.fill_box(1, RENDER::height - 10 + 1, per, 10 - 2, c);
			}

			for(uint32_t i = 0; i < 4; ++i) {
				if(i >= pos) {
					break;
				}
				auto t = watch.get_lap(pos - i - 1);
				if(pos > 1) {
					t -= watch.get_lap(pos - i - 2);
				}
				draw_lap_(0, 32 + 16 * 4 - i * 16, pos - i, t);
			}

			auto& res = at_scenes_base().at_resource();
			res.draw_nmb_24(0, 272 - 10 - 24 - 1, "0123456789:.");
		}
	};
}
<commit_msg>update: lap-time manage<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	ラップタイム
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/format.hpp"
#include "scenes_base.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ラップタイム・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class laptime {

		uint32_t	lap_best_t_;
		uint32_t	lap_best_n_;

	public:
		//-------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-------------------------------------------------------------//
		laptime() : lap_best_t_(0), lap_best_n_(0) { }

		//-------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-------------------------------------------------------------//
		void init()
		{
			at_scenes_base().at_cmt().at_task().enable();
			lap_best_t_ = 0;
			lap_best_n_ = 0;

			typedef scenes_base::RENDER RENDER;

			auto& render = at_scenes_base().at_render();
			render.clear(RENDER::COLOR::Black);
		}

		//-------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-------------------------------------------------------------//
		void service()
		{
			typedef scenes_base::RENDER RENDER;
			auto& render = at_scenes_base().at_render();
			auto& res = at_scenes_base().at_resource();
			auto& watch = at_scenes_base().at_cmt().at_task();

			auto t = watch.get();
			auto pos = watch.get_lap_pos();
			uint32_t dt = t;
			if(pos > 0) {
				dt -= watch.get_lap(pos - 1);
			}

			int16_t x = 0;
			int16_t y = 0;
			res.draw_lap_state(x, y, pos, t, dt);
//			res.draw_lap_24(x + 16, y, lap_best_n_, lap_best_t_);

			// プログレスバー表示
			render.frame(0, RENDER::height - 10, RENDER::width, 10, RENDER::COLOR::White);
			uint32_t bt = 0;
			if(pos > 0) {
				bt = watch.get_lap(pos - 1);
				if(pos > 1) {
					bt -= watch.get_lap(pos - 2);
				}
				if(lap_best_t_ == 0 || lap_best_t_ > bt) {
					lap_best_t_ = bt;
					lap_best_n_ = pos;
				}
			}
			if(bt > 0) {
				uint32_t ref = RENDER::width - 2;
				uint32_t per = ref * dt / bt;
				auto fc = RENDER::COLOR::Lime;
				if(per > ref) {
					per = ref;
					fc = RENDER::COLOR::Red;
				}
				auto bc = RENDER::COLOR::Black;
				render.fill_box(1, RENDER::height - 10 + 1, ref - per, 10 - 2, bc);
				render.fill_box(1, RENDER::height - 10 + 1, per, 10 - 2, fc);
			}

			for(uint32_t i = 0; i < 4; ++i) {
				if(i >= pos) {
					break;
				}
				auto t = watch.get_lap(pos - i - 1);
				if(pos > 1) {
					t -= watch.get_lap(pos - i - 2);
				}
				res.draw_short_lap(0, 48 + 28 * 4 - i * 28, pos - i, t);
			}
		}
	};
}
<|endoftext|>


<commit_before>class Queue {
public:
    stack<int> stack1;
    stack<int> stack2;

    Queue() {
        // do intialization if necessary
    }

    void push(int element) {
        // write your code here
        stack1.push(element);

    }

    int pop() {
        // write your code here
        stack2=reverStack(stack1);
        int top=stack2.pop();
        stack1=reverStack(stack2);
        return top;
    }

    int top() {
        // write your code here
        stack2=reverStack(stack1);
        return stack2.top();
    }
};
<commit_msg>Fixing 40<commit_after>class Queue {
public:
    stack<int> stack1;
    stack<int> stack2;

    Queue() {
        // do intialization if necessary
    }

    void push(int element) {
        // write your code here
        stack1.push(element);

    }

    stack reverStack(const stack& stackIn){

    }

    int pop() {
        // write your code here
        stack2=reverStack(stack1);
        int top=stack2.top();
        stack2.pop();
        stack1=reverStack(stack2);
        return top;
    }

    int top() {
        // write your code here
        stack2=reverStack(stack1);
        return stack2.top();
    }
};
<|endoftext|>


<commit_before>/*
  3. Summation with fixed structure of inputs

  We have to keep the values of some integer variables. Some of them are primary variables; they represent input data. The others are secondary variables, and represent aggregations of some other variables. In our case, each secondary variable is a sum of some input variables. The inputs may be primary or secondary variables. However, we assume that the relations do not form cycles.

  At runtime, we get notifications of value changes for the primary variable. Processing a notification must atomically update the primary variable, as well as any secondary variable depending, directly or indirectly, on it. The updating shall not re-compute the sums; instead, you must use the difference between the old value and the new value of the primary variable.

  From time to time, as well as at the end, a consistency check shall be performed. It shall verify that all the secondary variables are indeed the sums of their inputs, as specified.
*/

#include <iostream>
#include <chrono>
#include <fstream>
#include <vector>
#include <map>
#include <stdlib.h>
#include <time.h>
#include <thread>
#include <mutex>

using namespace std;

#define NODE_MUTEX
//#define ENABLE_GLOBAL_MUTEX

class Node {
protected:
  #ifdef NODE_MUTEX
  std::mutex node_mtx;
  #endif
public:
  virtual int getIndex() = 0;
  virtual int getValue() = 0;         // thread safe
  virtual void addToValue(int) = 0;   // thread safe
  virtual int computeValue() = 0;
};

class BaseNode : public Node {
protected:
  int value, index;
public:
  BaseNode(int ind) {
    index = ind;
    value = 0;
  }
  BaseNode(int ind, int x) {
    index = ind;
    value = x;
  }
  virtual int getIndex() {
    return index;
  }
  virtual int getValue() {
    #ifdef NODE_MUTEX
    node_mtx.lock();
    #endif
    int auxval = value;
    #ifdef NODE_MUTEX
    node_mtx.unlock();
    #endif
    return auxval;
  }
  virtual void addToValue(int x) {
    #ifdef NODE_MUTEX
    node_mtx.lock();
    #endif
    value += x;
    #ifdef NODE_MUTEX
    node_mtx.unlock();
    #endif
  }
  virtual int computeValue() {
    return value;
  }
};

class InternalNode : public BaseNode {
private:
  vector <Node*> dependency;
public:
  InternalNode(int ind) : BaseNode(ind) {
  }
  void addDependency(Node *n) {
    dependency.push_back(n);
  }
  virtual int computeValue() {
    value = 0;
    for(auto it : dependency) {
      value += it->computeValue();
    }
    return value;
  }
};

class ComputationalGraph {
private:
  #ifdef ENABLE_GLOBAL_MUTEX
  mutex global_mutex;
  #endif
  map<int, Node*> nodes;
  map<Node*, vector<Node*>> dependants;
  int n, m;
  void dfs(Node *node, int quantity) {
    node->addToValue(quantity);
    for(auto it : dependants[node]) {
      dfs(it, quantity);
    }
  }
public:
  void updateBaseNode(BaseNode* baseNode, int newValue) {
    #ifdef ENABLE_GLOBAL_MUTEX
    global_mutex.lock();
    #endif
    dfs(baseNode, newValue - baseNode->getValue());
    #ifdef ENABLE_GLOBAL_MUTEX
    global_mutex.unlock();
    #endif
  }
  void loadGraph(string filename) {
    ifstream fin(filename);
    fin >> n; // number of leaf nodes
    for(int i = 1; i <= n; ++ i) {
      int x;
      fin >> x;
      Node *node = new BaseNode(i, x);
      nodes[i] = node;
    }
    fin >> m; // number of dependencies
    for(int i = 1; i <= m; ++ i) {
      int x, y; // y depends on x
      fin >> x >> y;
      if (!nodes[x]) {
        nodes[x] = new InternalNode(x);
      }
      if (!nodes[y]) {
        nodes[y] = new InternalNode(y);
      }
      dynamic_cast<InternalNode*>(nodes[y])->addDependency(nodes[x]);
      dependants[nodes[x]].push_back(nodes[y]);
    }
  }
  void computeInitialValue() {
    for(auto it : nodes) {
      it.second->computeValue();
    }
  }
  void printValues() {
    for (auto it : nodes) {
      cout << "value of " << it.first << " is: " << it.second->getValue() << '\n';
    }
  }
  BaseNode* getRandomBaseNode() {
    return dynamic_cast<BaseNode*>(nodes[rand() % n + 1]);
  }
};

int T = 1000;

int getRandomInteger(int _max, int _min) {
  return _min + (rand() % static_cast<int>(_max - _min + 1));
}

int main() {
  auto start = std::chrono::high_resolution_clock::now();
  srand(time(NULL));
  vector <thread> threads;
  ComputationalGraph g;
  g.loadGraph("graph.in");
  g.computeInitialValue();
  for(int t = 0; t < T; ++ t) {
    BaseNode* currentNode = g.getRandomBaseNode();
    int newVal = getRandomInteger(-10, 10);
    cerr << "thread " << t + 1 << " updates node " << currentNode->getIndex()
        << " with " << newVal << '\n';
    threads.push_back(thread(&ComputationalGraph::updateBaseNode, &g, currentNode, newVal));
  }
  for(int t = 0; t < T; ++ t) {
    threads[t].join();
  }
  g.printValues();
  auto finish = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> elapsed = finish - start;
  cerr << "Elapsed time: " << elapsed.count() << '\n';
  return 0;
}
<commit_msg>Added consistency<commit_after>/*
  3. Summation with fixed structure of inputs

  We have to keep the values of some integer variables. Some of them are primary variables; they represent input data. The others are secondary variables, and represent aggregations of some other variables. In our case, each secondary variable is a sum of some input variables. The inputs may be primary or secondary variables. However, we assume that the relations do not form cycles.

  At runtime, we get notifications of value changes for the primary variable. Processing a notification must atomically update the primary variable, as well as any secondary variable depending, directly or indirectly, on it. The updating shall not re-compute the sums; instead, you must use the difference between the old value and the new value of the primary variable.

  From time to time, as well as at the end, a consistency check shall be performed. It shall verify that all the secondary variables are indeed the sums of their inputs, as specified.
*/

#include <iostream>
#include <chrono>
#include <fstream>
#include <vector>
#include <map>
#include <stdlib.h>
#include <time.h>
#include <thread>
#include <mutex>
#include <cassert>

using namespace std;

#define NODE_MUTEX
//#define ENABLE_GLOBAL_MUTEX

class Node {
protected:
  #ifdef NODE_MUTEX
  std::mutex node_mtx;
  #endif
public:
  virtual int getIndex() = 0;
  virtual int getValue() = 0;         // thread safe
  virtual void addToValue(int) = 0;   // thread safe
  virtual int computeValue() = 0;
  virtual bool isConsistent() = 0;
};

class BaseNode : public Node {
protected:
  int value, index;
public:
  BaseNode(int ind) {
    index = ind;
    value = 0;
  }
  BaseNode(int ind, int x) {
    index = ind;
    value = x;
  }
  virtual int getIndex() {
    return index;
  }
  virtual int getValue() {
    #ifdef NODE_MUTEX
    node_mtx.lock();
    #endif
    int auxval = value;
    #ifdef NODE_MUTEX
    node_mtx.unlock();
    #endif
    return auxval;
  }
  virtual void addToValue(int x) {
    #ifdef NODE_MUTEX
    node_mtx.lock();
    #endif
    value += x;
    #ifdef NODE_MUTEX
    node_mtx.unlock();
    #endif
  }
  virtual int computeValue() {
    return value;
  }
  virtual bool isConsistent() {
    return true;
  }
};

class InternalNode : public BaseNode {
private:
  vector <Node*> dependency;
public:
  InternalNode(int ind) : BaseNode(ind) {
  }
  void addDependency(Node *n) {
    dependency.push_back(n);
  }
  virtual int computeValue() {
    value = 0;
    for(auto it : dependency) {
      value += it->computeValue();
    }
    return value;
  }
  virtual bool isConsistent() {
    int sum = 0;
    for(auto it : dependency) {
      sum += it->getValue();
    }
    return sum == value;
  }
};

class ComputationalGraph {
private:
  #ifdef ENABLE_GLOBAL_MUTEX
  mutex global_mutex;
  #endif
  map<int, Node*> nodes;
  map<Node*, vector<Node*>> dependants;
  int n, m;
  void dfs(Node *node, int quantity) {
    node->addToValue(quantity);
    for(auto it : dependants[node]) {
      dfs(it, quantity);
    }
  }
public:
  void updateBaseNode(BaseNode* baseNode, int newValue) {
    #ifdef ENABLE_GLOBAL_MUTEX
    global_mutex.lock();
    #endif
    dfs(baseNode, newValue - baseNode->getValue());
    #ifdef ENABLE_GLOBAL_MUTEX
    global_mutex.unlock();
    #endif
  }
  void loadGraph(string filename) {
    ifstream fin(filename);
    fin >> n; // number of leaf nodes
    for(int i = 1; i <= n; ++ i) {
      int x;
      fin >> x;
      Node *node = new BaseNode(i, x);
      nodes[i] = node;
    }
    fin >> m; // number of dependencies
    for(int i = 1; i <= m; ++ i) {
      int x, y; // y depends on x
      fin >> x >> y;
      if (!nodes[x]) {
        nodes[x] = new InternalNode(x);
      }
      if (!nodes[y]) {
        nodes[y] = new InternalNode(y);
      }
      dynamic_cast<InternalNode*>(nodes[y])->addDependency(nodes[x]);
      dependants[nodes[x]].push_back(nodes[y]);
    }
  }
  void computeInitialValue() {
    for(auto it : nodes) {
      it.second->computeValue();
    }
  }
  void checkConsistency() {
    cerr << "Checking consistency\n";
    for(auto it : nodes) {
      assert(it.second->isConsistent());
    }
    cerr << "Consistent\n";
  }
  void printValues() {
    for (auto it : nodes) {
      cout << "value of " << it.first << " is: " << it.second->getValue() << '\n';
    }
  }
  BaseNode* getRandomBaseNode() {
    return dynamic_cast<BaseNode*>(nodes[rand() % n + 1]);
  }
};

int T = 1000;

int getRandomInteger(int _max, int _min) {
  return _min + (rand() % static_cast<int>(_max - _min + 1));
}

int main() {
  auto start = std::chrono::high_resolution_clock::now();
  srand(time(NULL));
  vector <thread> threads;
  ComputationalGraph g;
  g.loadGraph("graph.in");
  g.computeInitialValue();
  for(int t = 0; t < T; ++ t) {
    if (t % 5 == 0) {
      // check for consistency
      for(int i = 0; i < threads.size(); ++ i) {
        threads[i].join();
      }
      g.checkConsistency();
      threads.clear();
    }
    BaseNode* currentNode = g.getRandomBaseNode();
    int newVal = getRandomInteger(-10, 10);
    cerr << "thread " << t + 1 << " updates node " << currentNode->getIndex()
        << " with " << newVal << '\n';
   threads.push_back(thread(&ComputationalGraph::updateBaseNode, &g, currentNode, newVal));
  }
  for(int t = 0; t < (int)threads.size(); ++ t) {
    threads[t].join();
  }
  threads.clear();
  g.checkConsistency();
  g.printValues();
  auto finish = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> elapsed = finish - start;
  cerr << "Elapsed time: " << elapsed.count() << '\n';
  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>
#include <cmath>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/matrix_transform_2d.hpp>

#include <graphics/opengl/gl_api.h>

#include <graphics/shader.h>
#include <collision.h>
#include <log.h>
#include <file_manager.h>
#include <system_manager.h>
#include <resource_manager.h>
#include <event_manager.h>
#include <input_manager.h>
#include <component_storage.h>
#include <core_components.h>
#include <input_events.h>
#include <scene_events.h>
#include <update_events.h>
#include <input.h>
#include <prefab.h>
#include <scene_utils.h>

#include "render_system.h"
#include "poly_renderer.h"
#include "components.h"

struct stdoutstream : public oak::log::Stream {
	void write(const void *source, size_t size) override {
		fwrite(source, 1, size, stdout);
	}
};

bool isRunning = false;

struct CollisionSystem : public oak::System {

	void init() override {
		cache.requireComponent<TransformComponent>();
		cache.requireComponent<MeshComponent>();
		cache.requireComponent<ManifoldComponent>();
	}

	void run() override {
		cache.update(*scene);

		auto& ts = oak::getComponentStorage<TransformComponent>(*scene);
		auto& ms = oak::getComponentStorage<const MeshComponent>(*scene);
		auto& cs = oak::getComponentStorage<ManifoldComponent>(*scene);

		auto& entities = cache.entities();

		auto& A = entities[0];
		auto& Atc = oak::getComponent<TransformComponent>(ts, A);
		auto& Amc = oak::getComponent<const MeshComponent>(ms, A);
		auto& Acc = oak::getComponent<ManifoldComponent>(cs, A);
		for (size_t i = 1; i < entities.size(); i++) {

			auto& B = entities[i];
			auto& Btc = oak::getComponent<const TransformComponent>(ts, B);
			auto& Bmc = oak::getComponent<const MeshComponent>(ms, B);
			auto& Bcc = oak::getComponent<ManifoldComponent>(cs, B);

			oak::Simplex splex{ &oak::oalloc_frame };
			auto collides = oak::gjk(*Amc.mesh, Atc.transform, *Bmc.mesh, Btc.transform, splex);
			Acc.collides = collides;
			Bcc.collides = collides;
			if (collides) {
				glm::vec2 N;
				float d;
				oak::epa(*Amc.mesh, Atc.transform, *Bmc.mesh, Btc.transform, splex, N, d);
				Atc.transform[2] += glm::vec3{ -N * d, 0.0f };
			}
		}
	}

	oak::EntityCache cache;
	oak::Scene *scene;
};

int main(int argc, char** argv) {
	//setup log
	stdoutstream sos;
	oak::log::cout.addStream(&sos);
	oak::log::cwarn.addStream(&sos);
	oak::log::cerr.addStream(&sos);

	//init engine managers
	oak::EventManager evtManager;
	oak::InputManager inputManager;
	oak::FileManager fileManager;
	oak::SystemManager sysManager;
	oak::ComponentTypeManager chs;
	oak::ResourceManager resManager;

	inputManager.bind("move_forward", oak::key::w, true);
	inputManager.bind("move_backward", oak::key::s, true);
	inputManager.bind("strafe_left", oak::key::a, true);
	inputManager.bind("strafe_right", oak::key::d, true);
	inputManager.bind("move_up", oak::key::space, true);
	inputManager.bind("move_down", oak::key::lshift, true);

	fileManager.mount("{$cwd}/platform/res", "/res");
	fileManager.mount("{$cwd}/platform", "/res/shaders");
	fileManager.mount("{$cwd}/core/graphics/shaders", "/res/shaders");

	//add all events
	evtManager.addQueue<oak::EntityCreateEvent>();
	evtManager.addQueue<oak::EntityDestroyEvent>();
	evtManager.addQueue<oak::EntityActivateEvent>();
	evtManager.addQueue<oak::EntityDeactivateEvent>();
	evtManager.addQueue<oak::WindowCreateEvent>();
	evtManager.addQueue<oak::WindowCloseEvent>();
	evtManager.addQueue<oak::WindowResizeEvent>();
	evtManager.addQueue<oak::FrameSizeEvent>();
	evtManager.addQueue<oak::KeyEvent>();
	evtManager.addQueue<oak::ButtonEvent>();
	evtManager.addQueue<oak::CursorEvent>();
	evtManager.addQueue<oak::CursorModeEvent>();
	evtManager.addQueue<oak::TextEvent>();
	evtManager.addQueue<oak::TickEvent>();
	evtManager.addQueue<oak::SimulateEvent>();

	//get references to resource storage containers
	auto& bufferHandle = resManager.get<oak::graphics::Buffer>();
	auto& textureHandle = resManager.get<oak::graphics::Texture>();
	auto& shaderHandle = resManager.get<oak::graphics::Shader>();
	auto& materialHandle = resManager.get<oak::graphics::Material>();

	//create the scene
	oak::Scene scene;

	//create all the systems
	oak::graphics::GLApi api;

	//create the rendering system
	RenderSystem renderSystem{ &scene, &api };
	CollisionSystem collisionSystem;
	collisionSystem.scene = &scene;

	//basic test renderer
	PolyRenderer polyRenderer;
	renderSystem.pushLayerBack(&polyRenderer);

	//define vertex attribute layouts that will be used in the scene

	oak::graphics::AttributeLayout layout2d{ oak::vector<oak::graphics::AttributeType>{
		oak::graphics::AttributeType::POSITION2D,
		oak::graphics::AttributeType::COLOR
	} };

	//add them to the system manager
	sysManager.addSystem(&renderSystem, "render_system");
	sysManager.addSystem(&collisionSystem, "collision_system");

	//create component type handles
	chs.addHandle<oak::EventComponent>("event");
	chs.addHandle<oak::PrefabComponent>("prefab");
	chs.addHandle<TransformComponent>("transform");
	chs.addHandle<MeshComponent>("mesh");
	chs.addHandle<ManifoldComponent>("manifold");

	//create component storage
	oak::ComponentStorage eventStorage{ "event" };
	oak::ComponentStorage prefabStorage{ "prefab" };
	oak::ComponentStorage transformStorage{ "transform" };
	oak::ComponentStorage meshStorage{ "mesh" };
	oak::ComponentStorage manifoldStorage{ "manifold" };

	//add component storage to scene
	scene.addComponentStorage(&eventStorage);
	scene.addComponentStorage(&prefabStorage);
	scene.addComponentStorage(&transformStorage);
	scene.addComponentStorage(&meshStorage);
	scene.addComponentStorage(&manifoldStorage);

	//init the test renderer
	polyRenderer.init();

	//setup uniforms
	struct {
		glm::mat4 proj;
		glm::mat4 view;
	} omatrix;
	omatrix.view = glm::mat4{ 1.0f };
	omatrix.proj = glm::ortho(0.0f, 1280.0f, 720.0f, 0.0f, -1.0f, 1.0f);

	oak::graphics::BufferInfo bufferInfo;
	//create ortho matrix buffer
	bufferInfo.type = oak::graphics::BufferType::UNIFORM;
	bufferInfo.hint = oak::graphics::BufferHint::STATIC;
	bufferInfo.base = 1;
	auto& ortho_ubo = bufferHandle.add("ortho", oak::graphics::buffer::create(bufferInfo));
	oak::graphics::buffer::bind(ortho_ubo);
	oak::graphics::buffer::data(ortho_ubo, sizeof(omatrix), &omatrix);

	oak::Mesh2d m1;
	m1.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { 0.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 0.0f, 32.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 32.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	oak::Mesh2d m2;
	m2.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { 0.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 16.0f, 16.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	oak::Mesh2d m3;
	m3.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { -8.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { -12.0f, 16.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { -4.0f, 20.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 8.0f, 4.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 6.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	//create entities
	oak::Prefab polygon{ "polygon", scene };
	polygon.addComponent<TransformComponent>(glm::rotate(glm::mat3{ 1.0f }, 45.0f));
	polygon.addComponent<MeshComponent>(&m2);
	polygon.addComponent<ManifoldComponent>();

	oak::EntityId p1 = polygon.createInstance();
	scene.activateEntity(p1);

	oak::EntityId p2 = polygon.createInstance();
	oak::getComponent<TransformComponent>(scene, p2).transform = glm::translate(glm::mat3{ 1.0f }, glm::vec2{ 64.0f });
	oak::getComponent<MeshComponent>(scene, p2).mesh = &m2;
	scene.activateEntity(p2);

	oak::EntityId p3 = polygon.createInstance();
	oak::getComponent<TransformComponent>(scene, p3).transform = glm::translate(glm::mat3{ 1.0f }, glm::vec2{ 256.0f });
	oak::getComponent<MeshComponent>(scene, p3).mesh = &m3;
	scene.activateEntity(p3);

	//first frame time
	std::chrono::high_resolution_clock::time_point lastFrame = std::chrono::high_resolution_clock::now();
	std::chrono::duration<float> dt;

	//main game loop
	isRunning = true;
	while (isRunning) {
		inputManager.update();
		//create / destroy / activate / deactivate entities
		scene.update();

		if (inputManager.getKey(oak::key::w)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 0.0f, -2.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::a)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ -2.0f, 0.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::s)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 0.0f, 2.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::d)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 2.0f, 0.0f, 0.0f };
		}

		collisionSystem.run();

		renderSystem.run();

		//check for exit
		if (!evtManager.getQueue<oak::WindowCloseEvent>().empty()) {
			isRunning = false;
		}

		//update the delta time
		std::chrono::high_resolution_clock::time_point currentFrame = std::chrono::high_resolution_clock::now();
		dt = std::chrono::duration_cast<std::chrono::duration<float>>(currentFrame - lastFrame);
		lastFrame = currentFrame;

		//do engine things
		evtManager.clear();
		oak::oalloc_frame.clear();
	}

	//clean up
	scene.reset();

	return 0;
}
<commit_msg>fixed thing<commit_after>#include <iostream>
#include <chrono>
#include <cmath>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/matrix_transform_2d.hpp>

#include <graphics/opengl/gl_api.h>

#include <graphics/shader.h>
#include <collision.h>
#include <log.h>
#include <file_manager.h>
#include <system_manager.h>
#include <resource_manager.h>
#include <event_manager.h>
#include <input_manager.h>
#include <component_storage.h>
#include <core_components.h>
#include <input_events.h>
#include <scene_events.h>
#include <update_events.h>
#include <input.h>
#include <prefab.h>
#include <scene_utils.h>

#include "render_system.h"
#include "poly_renderer.h"
#include "components.h"

struct stdoutstream : public oak::log::Stream {
	void write(const void *source, size_t size) override {
		fwrite(source, 1, size, stdout);
	}
};

bool isRunning = false;

struct CollisionSystem : public oak::System {

	void init() override {
		cache.requireComponent<TransformComponent>();
		cache.requireComponent<MeshComponent>();
		cache.requireComponent<ManifoldComponent>();
	}

	void run() override {
		cache.update(*scene);

		auto& ts = oak::getComponentStorage<TransformComponent>(*scene);
		auto& ms = oak::getComponentStorage<const MeshComponent>(*scene);
		auto& cs = oak::getComponentStorage<ManifoldComponent>(*scene);

		auto& entities = cache.entities();

		auto& A = entities[0];
		auto& Atc = oak::getComponent<TransformComponent>(ts, A);
		auto& Amc = oak::getComponent<const MeshComponent>(ms, A);
		auto& Acc = oak::getComponent<ManifoldComponent>(cs, A);
		for (size_t i = 1; i < entities.size(); i++) {

			auto& B = entities[i];
			auto& Btc = oak::getComponent<const TransformComponent>(ts, B);
			auto& Bmc = oak::getComponent<const MeshComponent>(ms, B);
			auto& Bcc = oak::getComponent<ManifoldComponent>(cs, B);

			oak::Simplex splex{ &oak::oalloc_frame };
			auto collides = oak::gjk(*Amc.mesh, Atc.transform, *Bmc.mesh, Btc.transform, splex);
			Acc.collides = Acc.collides ? 1 : collides;
			Bcc.collides = Bcc.collides ? 1 : collides;
			if (collides) {
				glm::vec2 N;
				float d;
				oak::epa(*Amc.mesh, Atc.transform, *Bmc.mesh, Btc.transform, splex, N, d);
				Atc.transform[2] += glm::vec3{ -N * d, 0.0f };
			}
		}
	}

	oak::EntityCache cache;
	oak::Scene *scene;
};

int main(int argc, char** argv) {
	//setup log
	stdoutstream sos;
	oak::log::cout.addStream(&sos);
	oak::log::cwarn.addStream(&sos);
	oak::log::cerr.addStream(&sos);

	//init engine managers
	oak::EventManager evtManager;
	oak::InputManager inputManager;
	oak::FileManager fileManager;
	oak::SystemManager sysManager;
	oak::ComponentTypeManager chs;
	oak::ResourceManager resManager;

	inputManager.bind("move_forward", oak::key::w, true);
	inputManager.bind("move_backward", oak::key::s, true);
	inputManager.bind("strafe_left", oak::key::a, true);
	inputManager.bind("strafe_right", oak::key::d, true);
	inputManager.bind("move_up", oak::key::space, true);
	inputManager.bind("move_down", oak::key::lshift, true);

	fileManager.mount("{$cwd}/platform/res", "/res");
	fileManager.mount("{$cwd}/platform", "/res/shaders");
	fileManager.mount("{$cwd}/core/graphics/shaders", "/res/shaders");

	//add all events
	evtManager.addQueue<oak::EntityCreateEvent>();
	evtManager.addQueue<oak::EntityDestroyEvent>();
	evtManager.addQueue<oak::EntityActivateEvent>();
	evtManager.addQueue<oak::EntityDeactivateEvent>();
	evtManager.addQueue<oak::WindowCreateEvent>();
	evtManager.addQueue<oak::WindowCloseEvent>();
	evtManager.addQueue<oak::WindowResizeEvent>();
	evtManager.addQueue<oak::FrameSizeEvent>();
	evtManager.addQueue<oak::KeyEvent>();
	evtManager.addQueue<oak::ButtonEvent>();
	evtManager.addQueue<oak::CursorEvent>();
	evtManager.addQueue<oak::CursorModeEvent>();
	evtManager.addQueue<oak::TextEvent>();
	evtManager.addQueue<oak::TickEvent>();
	evtManager.addQueue<oak::SimulateEvent>();

	//get references to resource storage containers
	auto& bufferHandle = resManager.get<oak::graphics::Buffer>();
	auto& textureHandle = resManager.get<oak::graphics::Texture>();
	auto& shaderHandle = resManager.get<oak::graphics::Shader>();
	auto& materialHandle = resManager.get<oak::graphics::Material>();

	//create the scene
	oak::Scene scene;

	//create all the systems
	oak::graphics::GLApi api;

	//create the rendering system
	RenderSystem renderSystem{ &scene, &api };
	CollisionSystem collisionSystem;
	collisionSystem.scene = &scene;

	//basic test renderer
	PolyRenderer polyRenderer;
	renderSystem.pushLayerBack(&polyRenderer);

	//define vertex attribute layouts that will be used in the scene

	oak::graphics::AttributeLayout layout2d{ oak::vector<oak::graphics::AttributeType>{
		oak::graphics::AttributeType::POSITION2D,
		oak::graphics::AttributeType::COLOR
	} };

	//add them to the system manager
	sysManager.addSystem(&renderSystem, "render_system");
	sysManager.addSystem(&collisionSystem, "collision_system");

	//create component type handles
	chs.addHandle<oak::EventComponent>("event");
	chs.addHandle<oak::PrefabComponent>("prefab");
	chs.addHandle<TransformComponent>("transform");
	chs.addHandle<MeshComponent>("mesh");
	chs.addHandle<ManifoldComponent>("manifold");

	//create component storage
	oak::ComponentStorage eventStorage{ "event" };
	oak::ComponentStorage prefabStorage{ "prefab" };
	oak::ComponentStorage transformStorage{ "transform" };
	oak::ComponentStorage meshStorage{ "mesh" };
	oak::ComponentStorage manifoldStorage{ "manifold" };

	//add component storage to scene
	scene.addComponentStorage(&eventStorage);
	scene.addComponentStorage(&prefabStorage);
	scene.addComponentStorage(&transformStorage);
	scene.addComponentStorage(&meshStorage);
	scene.addComponentStorage(&manifoldStorage);

	//init the test renderer
	polyRenderer.init();

	//setup uniforms
	struct {
		glm::mat4 proj;
		glm::mat4 view;
	} omatrix;
	omatrix.view = glm::mat4{ 1.0f };
	omatrix.proj = glm::ortho(0.0f, 1280.0f, 720.0f, 0.0f, -1.0f, 1.0f);

	oak::graphics::BufferInfo bufferInfo;
	//create ortho matrix buffer
	bufferInfo.type = oak::graphics::BufferType::UNIFORM;
	bufferInfo.hint = oak::graphics::BufferHint::STATIC;
	bufferInfo.base = 1;
	auto& ortho_ubo = bufferHandle.add("ortho", oak::graphics::buffer::create(bufferInfo));
	oak::graphics::buffer::bind(ortho_ubo);
	oak::graphics::buffer::data(ortho_ubo, sizeof(omatrix), &omatrix);

	oak::Mesh2d m1;
	m1.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { 0.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 0.0f, 32.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 32.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	oak::Mesh2d m2;
	m2.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { 0.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 16.0f, 16.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 32.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	oak::Mesh2d m3;
	m3.vertices = oak::vector<oak::Mesh2d::Vertex>{
		oak::Mesh2d::Vertex{ { -8.0f, 0.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { -12.0f, 16.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { -4.0f, 20.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 8.0f, 4.0f }, glm::vec2{ 1.0f } },
		oak::Mesh2d::Vertex{ { 6.0f, 0.0f }, glm::vec2{ 1.0f } },
	};

	//create entities
	oak::Prefab polygon{ "polygon", scene };
	polygon.addComponent<TransformComponent>(glm::rotate(glm::mat3{ 1.0f }, 45.0f));
	polygon.addComponent<MeshComponent>(&m2);
	polygon.addComponent<ManifoldComponent>();

	oak::EntityId p1 = polygon.createInstance();
	scene.activateEntity(p1);

	oak::EntityId p2 = polygon.createInstance();
	oak::getComponent<TransformComponent>(scene, p2).transform = glm::translate(glm::mat3{ 1.0f }, glm::vec2{ 64.0f });
	oak::getComponent<MeshComponent>(scene, p2).mesh = &m2;
	scene.activateEntity(p2);

	oak::EntityId p3 = polygon.createInstance();
	oak::getComponent<TransformComponent>(scene, p3).transform = glm::translate(glm::mat3{ 1.0f }, glm::vec2{ 256.0f });
	oak::getComponent<MeshComponent>(scene, p3).mesh = &m3;
	scene.activateEntity(p3);

	//first frame time
	std::chrono::high_resolution_clock::time_point lastFrame = std::chrono::high_resolution_clock::now();
	std::chrono::duration<float> dt;

	//main game loop
	isRunning = true;
	while (isRunning) {
		inputManager.update();
		//create / destroy / activate / deactivate entities
		scene.update();

		if (inputManager.getKey(oak::key::w)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 0.0f, -2.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::a)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ -2.0f, 0.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::s)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 0.0f, 2.0f, 0.0f };
		}

		if (inputManager.getKey(oak::key::d)) {
			oak::getComponent<TransformComponent>(scene, p1).transform[2] += glm::vec3{ 2.0f, 0.0f, 0.0f };
		}

		collisionSystem.run();

		renderSystem.run();

		//check for exit
		if (!evtManager.getQueue<oak::WindowCloseEvent>().empty()) {
			isRunning = false;
		}

		//update the delta time
		std::chrono::high_resolution_clock::time_point currentFrame = std::chrono::high_resolution_clock::now();
		dt = std::chrono::duration_cast<std::chrono::duration<float>>(currentFrame - lastFrame);
		lastFrame = currentFrame;

		//do engine things
		evtManager.clear();
		oak::oalloc_frame.clear();
	}

	//clean up
	scene.reset();

	return 0;
}
<|endoftext|>


<commit_before>#ifndef __PML_PARTITION__
#define __PML_PARTITION__

#include <cstdint>

const int64_t MAX_PARTITION_K = 416;

inline uint64_t general_pent(int64_t k)
{
    if ((k & 0x01) == 1)
       k *= -1;
    k /= 2;
    return (3 * k - 1) * k / 2;
}

inline uint64_t partition(int64_t k, uint64_t* cache)
{
    if (k == 0)
        return 1;
    else if (k < 0 || k > MAX_PARTITION_K)
        return 0;
    else if (cache[k] != 0)
        return cache[k];

    uint64_t sum = 0;
    uint64_t sub = 2;
    int8_t neg = 0;
    uint64_t pent_ = general_pent(sub);
    while (pent_ <= (uint64_t) k)
    {
       sum += partition(k - pent_, cache) * (neg < 2 ? 1 : -1);
       sub++;
       neg++;
       if (neg == 4)
           neg = 0;
       pent_ = general_pent(sub);
    }

    cache[k] = sum;
    return sum;
}

inline uint64_t partition(int k)
{
    uint64_t* cache = new uint64_t[k + 1]{0};
    uint64_t ret = partition(k, cache);
    delete[] cache;
    return ret;
}

#endif
<commit_msg>fixed oddity with general_pent() indexing<commit_after>#ifndef __PML_PARTITION__
#define __PML_PARTITION__

#include <cstdint>

const int64_t MAX_PARTITION_K = 416;

inline uint64_t general_pent(int64_t k)
{
    k += 2;
    if ((k & 0x01) == 1)
       k *= -1;
    k /= 2;
    return (3 * k - 1) * k / 2;
}

inline uint64_t partition(int64_t k, uint64_t* cache)
{
    if (k == 0)
        return 1;
    else if (k < 0 || k > MAX_PARTITION_K)
        return 0;
    else if (cache[k] != 0)
        return cache[k];

    uint64_t sum = 0;
    uint64_t sub = 0;
    int8_t neg = 0;
    uint64_t pent_ = general_pent(sub);
    while (pent_ <= (uint64_t) k)
    {
       sum += partition(k - pent_, cache) * (neg < 2 ? 1 : -1);
       sub++;
       neg++;
       if (neg == 4)
           neg = 0;
       pent_ = general_pent(sub);
    }

    cache[k] = sum;
    return sum;
}

inline uint64_t partition(int k)
{
    uint64_t* cache = new uint64_t[k + 1]{0};
    uint64_t ret = partition(k, cache);
    delete[] cache;
    return ret;
}

#endif
<|endoftext|>


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

/**
 * @file FlightTask.hpp
 *
 * Abstract base class for different advanced flight tasks like orbit, follow me, ...
 *
 * @author Matthias Grob <maetugr@gmail.com>
 */

#pragma once

#include <px4_module_params.h>
#include <drivers/drv_hrt.h>
#include <matrix/matrix/math.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/topics/vehicle_local_position.h>
#include <uORB/topics/vehicle_local_position_setpoint.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_constraints.h>
#include <uORB/topics/vehicle_attitude.h>
#include "../SubscriptionArray.hpp"

class FlightTask : public ModuleParams
{
public:
	FlightTask() :
		ModuleParams(nullptr)
	{
		_resetSetpoints();
		_constraints = empty_constraints;
	}

	virtual ~FlightTask() = default;

	/**
	 * Initialize the uORB subscriptions using an array
	 * @return true on success, false on error
	 */
	virtual bool initializeSubscriptions(SubscriptionArray &subscription_array);

	/**
	 * Call once on the event where you switch to the task
	 * @return true on success, false on error
	 */
	virtual bool activate();

	/**
	 * To be called to adopt parameters from an arrived vehicle command
	 * @return true if accepted, false if declined
	 */
	virtual bool applyCommandParameters(const vehicle_command_s &command) { return true; };

	/**
	 * Call before activate() or update()
	 * to initialize time and input data
	 * @return true on success, false on error
	 */
	virtual bool updateInitialize();

	/**
	 * To be called regularly in the control loop cycle to execute the task
	 * @return true on success, false on error
	 */
	virtual bool update() = 0;

	/**
	 * Get the output data
	 */
	const vehicle_local_position_setpoint_s getPositionSetpoint();

	/**
	 * Get vehicle constraints.
	 * The constraints can vary with task.
	 * @return constraints
	 */
	const vehicle_constraints_s getConstraints() {return _constraints;};

	/**
	 * Empty setpoint.
	 * All setpoints are set to NAN.
	 */
	static const vehicle_local_position_setpoint_s empty_setpoint;

	/**
	 * Empty constraints.
	 * All constraints are set to NAN.
	 */
	static const vehicle_constraints_s empty_constraints;

	/**
	 * Call this whenever a parameter update notification is received (parameter_update uORB message)
	 */
	void handleParameterUpdate()
	{
		updateParams();
	}

protected:

	uORB::Subscription<vehicle_local_position_s> *_sub_vehicle_local_position{nullptr};
	uORB::Subscription<vehicle_attitude_s> *_sub_attitude{nullptr};
	uint8_t _heading_reset_counter{0}; /**< estimator heading reset */

	/**
	 * Reset all setpoints to NAN
	 */
	void _resetSetpoints();

	/*
	 * Check and update local position
	 */
	bool _evaluateVehicleLocalPosition();

	/**
	 * Set constraints to default values
	 */
	virtual void  _setDefaultConstraints();

	/* Time abstraction */
	static constexpr uint64_t _timeout = 500000; /**< maximal time in us before a loop or data times out */
	float _time = 0; /**< passed time in seconds since the task was activated */
	float _deltatime = 0; /**< passed time in seconds since the task was last updated */
	hrt_abstime _time_stamp_activate = 0; /**< time stamp when task was activated */
	hrt_abstime _time_stamp_current = 0; /**< time stamp at the beginning of the current task update */
	hrt_abstime _time_stamp_last = 0; /**< time stamp when task was last updated */

	/* Current vehicle state */
	matrix::Vector3f _position; /**< current vehicle position */
	matrix::Vector3f _velocity; /**< current vehicle velocity */
	float _yaw = 0.f; /**< current vehicle yaw heading */
	float _dist_to_bottom; /**< current height above ground level */

	/**
	 * Setpoints which the position controller has to execute.
	 * Setpoints that are set to NAN are not controlled. Not all setpoints can be set at the same time.
	 * If more than one type of setpoint is set, then order of control is a as follow: position, velocity,
	 * acceleration, thrust. The exception is _position_setpoint together with _velocity_setpoint, where the
	 * _velocity_setpoint is used as feedforward.
	 * _acceleration_setpoint is currently not supported.
	 */
	matrix::Vector3f _position_setpoint;
	matrix::Vector3f _velocity_setpoint;
	matrix::Vector3f _acceleration_setpoint;
	matrix::Vector3f _thrust_setpoint;
	float _yaw_setpoint;
	float _yawspeed_setpoint;

	/**
	 * Vehicle constraints.
	 * The constraints can vary with tasks.
	 */
	vehicle_constraints_s _constraints;

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

/**
 * @file FlightTask.hpp
 *
 * Abstract base class for different advanced flight tasks like orbit, follow me, ...
 *
 * @author Matthias Grob <maetugr@gmail.com>
 */

#pragma once

#include <px4_module_params.h>
#include <drivers/drv_hrt.h>
#include <matrix/matrix/math.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/topics/vehicle_local_position.h>
#include <uORB/topics/vehicle_local_position_setpoint.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_constraints.h>
#include <uORB/topics/vehicle_attitude.h>
#include "../SubscriptionArray.hpp"

class FlightTask : public ModuleParams
{
public:
	FlightTask() :
		ModuleParams(nullptr)
	{
		_resetSetpoints();
		_constraints = empty_constraints;
	}

	virtual ~FlightTask() = default;

	/**
	 * Initialize the uORB subscriptions using an array
	 * @return true on success, false on error
	 */
	virtual bool initializeSubscriptions(SubscriptionArray &subscription_array);

	/**
	 * Call once on the event where you switch to the task
	 * @return true on success, false on error
	 */
	virtual bool activate();

	/**
	 * To be called to adopt parameters from an arrived vehicle command
	 * @return true if accepted, false if declined
	 */
	virtual bool applyCommandParameters(const vehicle_command_s &command) { return true; };

	/**
	 * Call before activate() or update()
	 * to initialize time and input data
	 * @return true on success, false on error
	 */
	virtual bool updateInitialize();

	/**
	 * To be called regularly in the control loop cycle to execute the task
	 * @return true on success, false on error
	 */
	virtual bool update() = 0;

	/**
	 * Get the output data
	 */
	const vehicle_local_position_setpoint_s getPositionSetpoint();

	/**
	 * Get vehicle constraints.
	 * The constraints can vary with task.
	 * @return constraints
	 */
	const vehicle_constraints_s getConstraints() {return _constraints;};

	/**
	 * Empty setpoint.
	 * All setpoints are set to NAN.
	 */
	static const vehicle_local_position_setpoint_s empty_setpoint;

	/**
	 * Empty constraints.
	 * All constraints are set to NAN.
	 */
	static const vehicle_constraints_s empty_constraints;

	/**
	 * Call this whenever a parameter update notification is received (parameter_update uORB message)
	 */
	void handleParameterUpdate()
	{
		updateParams();
	}

protected:

	uORB::Subscription<vehicle_local_position_s> *_sub_vehicle_local_position{nullptr};
	uORB::Subscription<vehicle_attitude_s> *_sub_attitude{nullptr};
	uint8_t _heading_reset_counter{0}; /**< estimator heading reset */

	/**
	 * Reset all setpoints to NAN
	 */
	void _resetSetpoints();

	/*
	 * Check and update local position
	 */
	bool _evaluateVehicleLocalPosition();

	/**
	 * Set constraints to default values
	 */
	virtual void  _setDefaultConstraints();

	/* Time abstraction */
	static constexpr uint64_t _timeout = 500000; /**< maximal time in us before a loop or data times out */
	float _time = 0; /**< passed time in seconds since the task was activated */
	float _deltatime = 0; /**< passed time in seconds since the task was last updated */
	hrt_abstime _time_stamp_activate = 0; /**< time stamp when task was activated */
	hrt_abstime _time_stamp_current = 0; /**< time stamp at the beginning of the current task update */
	hrt_abstime _time_stamp_last = 0; /**< time stamp when task was last updated */

	/* Current vehicle state */
	matrix::Vector3f _position; /**< current vehicle position */
	matrix::Vector3f _velocity; /**< current vehicle velocity */
	float _yaw = 0.f; /**< current vehicle yaw heading */
	float _dist_to_bottom = 0.0f; /**< current height above ground level */

	/**
	 * Setpoints which the position controller has to execute.
	 * Setpoints that are set to NAN are not controlled. Not all setpoints can be set at the same time.
	 * If more than one type of setpoint is set, then order of control is a as follow: position, velocity,
	 * acceleration, thrust. The exception is _position_setpoint together with _velocity_setpoint, where the
	 * _velocity_setpoint is used as feedforward.
	 * _acceleration_setpoint is currently not supported.
	 */
	matrix::Vector3f _position_setpoint;
	matrix::Vector3f _velocity_setpoint;
	matrix::Vector3f _acceleration_setpoint;
	matrix::Vector3f _thrust_setpoint;
	float _yaw_setpoint;
	float _yawspeed_setpoint;

	/**
	 * Vehicle constraints.
	 * The constraints can vary with tasks.
	 */
	vehicle_constraints_s _constraints;

	DEFINE_PARAMETERS_CUSTOM_PARENT(ModuleParams,
					(ParamFloat<px4::params::MPC_XY_VEL_MAX>) MPC_XY_VEL_MAX,
					(ParamFloat<px4::params::MPC_Z_VEL_MAX_DN>) MPC_Z_VEL_MAX_DN,
					(ParamFloat<px4::params::MPC_Z_VEL_MAX_UP>) MPC_Z_VEL_MAX_UP,
					(ParamFloat<px4::params::MPC_TILTMAX_AIR>) MPC_TILTMAX_AIR
				       )
};
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgeomapgroupobject.h"
#include "qgeomapgroupobject_p.h"

#include "qgeomapobject_p.h"

#include "qgeocoordinate.h"
#include "qgeoboundingbox.h"

#include "qgeomapdata.h"
#include "qgeomapdata_p.h"

QTM_BEGIN_NAMESPACE

/*!
    \class QGeoMapGroupObject
    \brief The QGeoMapGroupObject class is a QGeoMapObject used to
    manager a group of other map objects.

    \inmodule QtLocation

    \ingroup maps-mapping-objects

    The QGeoMapGroupObject class can be used to quickly add and remove
    groups of objects to a map.

    The map objects contained in the group will be ordered relative to
    one another in the usual manner, such that objects with higher z-values
    will be drawn over objects with lower z-values and objects with
    equal z-values will be drawn in insertion order.

    This ordering of the objects will be independent of the other
    objects that are added to the map, since the z-value and insertion
    order of the QGeoMapGroupObject is used to determine where the
    group is placed in the scene.
*/

/*!
    Constructs a new group object.
*/
QGeoMapGroupObject::QGeoMapGroupObject()
    : d_ptr(new QGeoMapGroupObjectPrivate(this)) {}

/*!
    Destroys this group object.
*/
QGeoMapGroupObject::~QGeoMapGroupObject()
{
    delete d_ptr;
}

/*!
    \reimp
*/
QGeoMapObject::Type QGeoMapGroupObject::type() const
{
    return QGeoMapObject::GroupType;
}

/*!
    Returns a bounding box which contains this map object.

    If this map object has children, the bounding box will be large
    enough to contain both this map object and all of its children.
*/
QGeoBoundingBox QGeoMapGroupObject::boundingBox() const
{
    QGeoBoundingBox bounds;

    if (d_ptr->children.size() == 0)
        return bounds;

    bounds = d_ptr->children.at(0)->boundingBox();

    for (int i = 1; i < d_ptr->children.size(); ++i)
        bounds = bounds.united(d_ptr->children.at(i)->boundingBox());

    return bounds;
}

/*!
    Returns whether \a coordinate is contained with the boundary of this
    map object.

    If this map object has children, this function will return whether
    \a coordinate is contained within the boundary of this map object or
    within the boundary of any of its children.
*/
bool QGeoMapGroupObject::contains(const QGeoCoordinate &coordinate) const
{
    for (int i = 0; i < d_ptr->children.size(); ++i)
        if (d_ptr->children.at(i)->contains(coordinate))
            return true;

    return false;
}

bool mapObjectLessThan(const QGeoMapObject* op1, const QGeoMapObject* op2)
{
    return op1->operator <(*op2);
}

/*!
    Adds \a childObject to the list of children of this map object.

    The children objects are drawn in order of the QGeoMapObject::zValue()
    value.  Children objects having the same z value will be drawn
    in the order they were added.

    The map object will take ownership of \a childObject.
*/
void QGeoMapGroupObject::addChildObject(QGeoMapObject *childObject)
{
    if (!childObject || d_ptr->children.contains(childObject))
        return;

    childObject->setMapData(mapData());
    childObject->d_func()->serial = d_func()->serial++;

    //binary search
    QList<QGeoMapObject*>::iterator i = qUpperBound(d_ptr->children.begin(),
                                                    d_ptr->children.end(),
                                                    childObject,
                                                    mapObjectLessThan);
    d_ptr->children.insert(i, childObject);
    update();

    connect(childObject, SIGNAL(zValueChanged(int)),
            d_ptr, SLOT(childChangedZValue(int)));

    emit childAdded(childObject);
}

/*!
    Removes \a childObject from the list of children of this map object.

    The map object will release ownership of \a childObject.
*/
void QGeoMapGroupObject::removeChildObject(QGeoMapObject *childObject)
{
    if (!childObject)
        return;

    if (d_ptr->children.removeAll(childObject) > 0) {

        disconnect(childObject, SIGNAL(zValueChanged(int)),
                   d_ptr, SLOT(childChangedZValue(int)));

        emit childRemoved(childObject);
        childObject->setMapData(0);
    }

    update();
}

/*!
    Returns the children of this object.
*/
QList<QGeoMapObject*> QGeoMapGroupObject::childObjects() const
{
    return d_ptr->children;
}

/*!
    Clears the children of this object.

    The child objects will be deleted.
*/
void QGeoMapGroupObject::clearChildObjects()
{
    for (int i = 0; i < d_ptr->children.size(); ++i) {
        emit childRemoved(d_ptr->children[i]);
        d_ptr->children[i]->setMapData(0);
        delete d_ptr->children[i];
    }

    d_ptr->children.clear();

    update();
}

/*!
    \reimp
*/
void QGeoMapGroupObject::setVisible(bool visible)
{
    for (int i = 0; i < d_ptr->children.size(); ++i)
        d_ptr->children[i]->setVisible(visible);

    QGeoMapObject::setVisible(visible);

    update();
}

/*!
    \reimp
*/
void QGeoMapGroupObject::setMapData(QGeoMapData *mapData)
{

    for (int i = 0; i < d_ptr->children.size(); ++i) {
        d_ptr->children[i]->setMapData(mapData);
        if (mapData)
            emit childAdded(d_ptr->children[i]);
    }

    QGeoMapObject::setMapData(mapData);
}

/*!
\fn void QGeoMapGroupObject::childAdded(QGeoMapObject *childObject)

    This signal will be emitted when the map object \a childObject
    is added to the group.
*/

/*!
\fn void QGeoMapGroupObject::childRemoved(QGeoMapObject *childObject)

    This signal will be emitted when the map object \a childObject
    is removed from the group.
*/

/*******************************************************************************
*******************************************************************************/

QGeoMapGroupObjectPrivate::QGeoMapGroupObjectPrivate(QGeoMapGroupObject *p) :
    QObject(p),
    serial(1),
    q_ptr(p)
{}

QGeoMapGroupObjectPrivate::~QGeoMapGroupObjectPrivate()
{
    qDeleteAll(children);
}

void QGeoMapGroupObjectPrivate::childChangedZValue(int zValue)
{
    Q_UNUSED(zValue);
    QGeoMapObject *child = qobject_cast<QGeoMapObject*>(sender());
    if (!child)
        return;

    if (children.removeAll(child) > 0) {
        QList<QGeoMapObject*>::iterator i = qUpperBound(children.begin(),
                                                        children.end(),
                                                        child,
                                                        mapObjectLessThan);
        children.insert(i, child);
        q_ptr->update();
    }
}

#include "moc_qgeomapgroupobject.cpp"
#include "moc_qgeomapgroupobject_p.cpp"

QTM_END_NAMESPACE

<commit_msg>MapGroupObject: forcing removal of children from the engine<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgeomapgroupobject.h"
#include "qgeomapgroupobject_p.h"

#include "qgeomapobject_p.h"
#include "qgeomapobjectengine_p.h"

#include "qgeocoordinate.h"
#include "qgeoboundingbox.h"

#include "qgeomapdata.h"
#include "qgeomapdata_p.h"

QTM_BEGIN_NAMESPACE

/*!
    \class QGeoMapGroupObject
    \brief The QGeoMapGroupObject class is a QGeoMapObject used to
    manager a group of other map objects.

    \inmodule QtLocation

    \ingroup maps-mapping-objects

    The QGeoMapGroupObject class can be used to quickly add and remove
    groups of objects to a map.

    The map objects contained in the group will be ordered relative to
    one another in the usual manner, such that objects with higher z-values
    will be drawn over objects with lower z-values and objects with
    equal z-values will be drawn in insertion order.

    This ordering of the objects will be independent of the other
    objects that are added to the map, since the z-value and insertion
    order of the QGeoMapGroupObject is used to determine where the
    group is placed in the scene.
*/

/*!
    Constructs a new group object.
*/
QGeoMapGroupObject::QGeoMapGroupObject()
    : d_ptr(new QGeoMapGroupObjectPrivate(this)) {}

/*!
    Destroys this group object.
*/
QGeoMapGroupObject::~QGeoMapGroupObject()
{
    delete d_ptr;
}

/*!
    \reimp
*/
QGeoMapObject::Type QGeoMapGroupObject::type() const
{
    return QGeoMapObject::GroupType;
}

/*!
    Returns a bounding box which contains this map object.

    If this map object has children, the bounding box will be large
    enough to contain both this map object and all of its children.
*/
QGeoBoundingBox QGeoMapGroupObject::boundingBox() const
{
    QGeoBoundingBox bounds;

    if (d_ptr->children.size() == 0)
        return bounds;

    bounds = d_ptr->children.at(0)->boundingBox();

    for (int i = 1; i < d_ptr->children.size(); ++i)
        bounds = bounds.united(d_ptr->children.at(i)->boundingBox());

    return bounds;
}

/*!
    Returns whether \a coordinate is contained with the boundary of this
    map object.

    If this map object has children, this function will return whether
    \a coordinate is contained within the boundary of this map object or
    within the boundary of any of its children.
*/
bool QGeoMapGroupObject::contains(const QGeoCoordinate &coordinate) const
{
    for (int i = 0; i < d_ptr->children.size(); ++i)
        if (d_ptr->children.at(i)->contains(coordinate))
            return true;

    return false;
}

bool mapObjectLessThan(const QGeoMapObject* op1, const QGeoMapObject* op2)
{
    return op1->operator <(*op2);
}

/*!
    Adds \a childObject to the list of children of this map object.

    The children objects are drawn in order of the QGeoMapObject::zValue()
    value.  Children objects having the same z value will be drawn
    in the order they were added.

    The map object will take ownership of \a childObject.
*/
void QGeoMapGroupObject::addChildObject(QGeoMapObject *childObject)
{
    if (!childObject || d_ptr->children.contains(childObject))
        return;

    childObject->setMapData(mapData());
    childObject->d_func()->serial = d_func()->serial++;

    //binary search
    QList<QGeoMapObject*>::iterator i = qUpperBound(d_ptr->children.begin(),
                                                    d_ptr->children.end(),
                                                    childObject,
                                                    mapObjectLessThan);
    d_ptr->children.insert(i, childObject);
    update();

    connect(childObject, SIGNAL(zValueChanged(int)),
            d_ptr, SLOT(childChangedZValue(int)));

    emit childAdded(childObject);
}

/*!
    Removes \a childObject from the list of children of this map object.

    The map object will release ownership of \a childObject.
*/
void QGeoMapGroupObject::removeChildObject(QGeoMapObject *childObject)
{
    if (!childObject)
        return;

    if (d_ptr->children.removeAll(childObject) > 0) {

        disconnect(childObject, SIGNAL(zValueChanged(int)),
                   d_ptr, SLOT(childChangedZValue(int)));

        emit childRemoved(childObject);
        childObject->setMapData(0);

        if (this->mapData()) {
            QGeoMapObjectEngine *oe = this->mapData()->d_ptr->oe;
            if (oe)
                oe->removeObject(childObject);
        }
    }

    update();
}

/*!
    Returns the children of this object.
*/
QList<QGeoMapObject*> QGeoMapGroupObject::childObjects() const
{
    return d_ptr->children;
}

/*!
    Clears the children of this object.

    The child objects will be deleted.
*/
void QGeoMapGroupObject::clearChildObjects()
{
    for (int i = 0; i < d_ptr->children.size(); ++i) {
        emit childRemoved(d_ptr->children[i]);
        d_ptr->children[i]->setMapData(0);

        if (this->mapData()) {
            QGeoMapObjectEngine *oe = this->mapData()->d_ptr->oe;
            if (oe)
                oe->removeObject(d_ptr->children[i]);
        }

        delete d_ptr->children[i];
    }

    d_ptr->children.clear();

    update();
}

/*!
    \reimp
*/
void QGeoMapGroupObject::setVisible(bool visible)
{
    for (int i = 0; i < d_ptr->children.size(); ++i)
        d_ptr->children[i]->setVisible(visible);

    QGeoMapObject::setVisible(visible);

    update();
}

/*!
    \reimp
*/
void QGeoMapGroupObject::setMapData(QGeoMapData *mapData)
{

    for (int i = 0; i < d_ptr->children.size(); ++i) {
        d_ptr->children[i]->setMapData(mapData);
        if (mapData)
            emit childAdded(d_ptr->children[i]);
    }

    QGeoMapObject::setMapData(mapData);
}

/*!
\fn void QGeoMapGroupObject::childAdded(QGeoMapObject *childObject)

    This signal will be emitted when the map object \a childObject
    is added to the group.
*/

/*!
\fn void QGeoMapGroupObject::childRemoved(QGeoMapObject *childObject)

    This signal will be emitted when the map object \a childObject
    is removed from the group.
*/

/*******************************************************************************
*******************************************************************************/

QGeoMapGroupObjectPrivate::QGeoMapGroupObjectPrivate(QGeoMapGroupObject *p) :
    QObject(p),
    serial(1),
    q_ptr(p)
{}

QGeoMapGroupObjectPrivate::~QGeoMapGroupObjectPrivate()
{
    qDeleteAll(children);
}

void QGeoMapGroupObjectPrivate::childChangedZValue(int zValue)
{
    Q_UNUSED(zValue);
    QGeoMapObject *child = qobject_cast<QGeoMapObject*>(sender());
    if (!child)
        return;

    if (children.removeAll(child) > 0) {
        QList<QGeoMapObject*>::iterator i = qUpperBound(children.begin(),
                                                        children.end(),
                                                        child,
                                                        mapObjectLessThan);
        children.insert(i, child);
        q_ptr->update();
    }
}

#include "moc_qgeomapgroupobject.cpp"
#include "moc_qgeomapgroupobject_p.cpp"

QTM_END_NAMESPACE

<|endoftext|>