<commit_before>//functor_overload header
//Copyright (c) 2014 mmYYmmdd

#if !defined MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED
#define MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED

#include <type_traits>

namespace mymd {
	namespace detail_fo	{

		template <typename>
		struct noCondition	{
			static constexpr bool value = true;
		};

		template <template <typename> class C = noCondition, bool B = true>
		struct cond	{ };
		//-----------------------------------------------------
		template <typename...>
		struct types  { };

		template <typename T, typename>
		struct arg  {
			using apply = std::enable_if<true, T>;
		};

		template <template <typename> class C, bool B, typename V>
		struct arg<cond<C, B>, V>  {
			using apply = std::enable_if<B == C<V>::value, V>;
		};
		//-----------------------------------------------------
		struct no_action	{
			constexpr no_action() { }
			template <typename... V>
			void operator ()(V&&...) const {}
		};
		//-----------------------------------------------------
		template <typename F, typename... A>
		class bolt  {
			F fn;
			template <typename T, typename U>	//workaround for VC
			using apply = typename arg<T, U>::apply;
		protected:
			template <typename... V>
			auto invoke(types<V...>, typename arg<A, V>::apply::type&&... a) const
				->decltype(fn(std::declval<typename apply<A, V>::type>()...))
			{  return fn(std::forward<typename apply<A, V>::type>(a) ...);  }
		public:
			constexpr bolt(const F& f) : fn(f)  {  }
		};

		template <typename T1, typename T2>
		struct bolts : private T1, private T2  {
            using T1::operator ();
            using T2::operator ();
			constexpr bolts(const T1& t1, const T2& t2) : T1(t1), T2(t2) { }
		};

		template <typename F, typename... A>
		struct bolts<bolt<F, A...>, void> : private bolt<F, A...>  {
            protected: using bolt<F, A...>::invoke;
        public:
			constexpr bolts(const bolt<F, A...>& t) : bolt<F, A...>(t) { }
			template <typename... V>
			auto operator()(V&&... v) const->decltype(invoke(types<V...>{}, std::declval<V>()...))
			{  return invoke(types<V...>{}, std::forward<V>(v)...);  }
		};

		template <typename T1, typename T2, typename U1, typename U2>
		auto operator +(bolts<T1, T2> const& b, bolts<U1, U2> const& c)
			->bolts<bolts<T1, T2>, bolts<U1, U2>>
		{
			return bolts<bolts<T1, T2>, bolts<U1, U2>>(b, c);
		}

	}	//namespace detail_fo

	//user interfaces are ,
	//  mymd::gen< >( )  ,  mymd::cond< >  ,  operator +

	using detail_fo::cond;

	template <typename... A, typename F>
	auto gen(const F& f) ->detail_fo::bolts<detail_fo::bolt<F, A...>, void>
	{
		return detail_fo::bolts<detail_fo::bolt<F, A...>, void>(detail_fo::bolt<F, A...>(f));
	}

	//no action
	template <typename... A>
	auto gen() ->detail_fo::bolts<detail_fo::bolt<detail_fo::no_action, A...>, void>
	{
		return detail_fo::bolts<detail_fo::bolt<detail_fo::no_action, A...>, void>
			(detail_fo::bolt<detail_fo::no_action, A...>(detail_fo::no_action{}));
	}

	//----------------------------------
	//template <typename T>
	//using is_xxx = mymd::is_some_rr<std::is_yyyy, std::is_zzzz>::apply<T>;
	//using is_xxx = mymd::is_every_rr<std::is_yyyy, std::is_zzzz>::apply<T>;

	template <template <typename> class first, template <typename> class... tail>
	struct is_some_rr	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value || is_some_rr<tail...>::template apply<T>::value;
		};
	};

	template <template <typename> class first>
	struct is_some_rr<first>	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value;
		};
	};

	template <template <typename> class first, template <typename> class... tail>
	struct is_every_rr	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value && is_every_rr<tail...>::template apply<T>::value;
		};
	};

	template <template <typename> class first>
	struct is_every_rr<first>	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value;
		};
	};
}

#endif
<commit_msg>struct bolts を detail_fo の外に出した<commit_after>//functor_overload header
//Copyright (c) 2014 mmYYmmdd

#if !defined MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED
#define MMYYMMDD_FUNCTOR_OVERLOAD_INCLUDED

#include <type_traits>

namespace mymd {
	namespace detail_fo	{

		template <typename>
		struct noCondition	{
			static constexpr bool value = true;
		};

		template <template <typename> class C = noCondition, bool B = true>
		struct cond	{ };
		//-----------------------------------------------------
		template <typename...>
		struct types  { };

		template <typename T, typename>
		struct arg  {
			using apply = std::enable_if<true, T>;
		};

		template <template <typename> class C, bool B, typename V>
		struct arg<cond<C, B>, V>  {
			using apply = std::enable_if<B == C<V>::value, V>;
		};
		//-----------------------------------------------------
		struct no_action	{
			constexpr no_action() { }
			template <typename... V>
			void operator ()(V&&...) const {}
		};
		//-----------------------------------------------------
		template <typename F, typename... A>
		class bolt  {
			F fn;
			template <typename T, typename U>	//workaround for VC
			using apply = typename arg<T, U>::apply;
		protected:
			template <typename... V>
			auto invoke(types<V...>, typename arg<A, V>::apply::type&&... a) const
				->decltype(fn(std::declval<typename apply<A, V>::type>()...))
			{  return fn(std::forward<typename apply<A, V>::type>(a) ...);  }
		public:
			constexpr bolt(const F& f) : fn(f)  {  }
		};
		//----------------------------------------------

	}	//namespace detail_fo

	//user interfaces are ,
	//  mymd::gen< >( )  ,  mymd::cond< >  ,  operator +

	using detail_fo::cond;

	template <typename T1, typename T2>
	struct bolts : private T1, private T2  {
        using T1::operator ();
        using T2::operator ();
		constexpr bolts(const T1& t1, const T2& t2) : T1(t1), T2(t2) { }
	};

	template <typename F, typename... A>
	struct bolts<detail_fo::bolt<F, A...>, void> : private detail_fo::bolt<F, A...>  {
        protected: using detail_fo::bolt<F, A...>::invoke;
    public:
		constexpr bolts(const detail_fo::bolt<F, A...>& t) : detail_fo::bolt<F, A...>(t) { }
		template <typename... V>
		auto operator()(V&&... v) const->decltype(invoke(detail_fo::types<V...>{}, std::declval<V>()...))
		{  return invoke(detail_fo::types<V...>{}, std::forward<V>(v)...);  }
	};

	template <typename T1, typename T2, typename U1, typename U2>
	auto operator +(bolts<T1, T2> const& b, bolts<U1, U2> const& c)
		->bolts<bolts<T1, T2>, bolts<U1, U2>>
	{
		return bolts<bolts<T1, T2>, bolts<U1, U2>>(b, c);
	}

	template <typename... A, typename F>
	auto gen(const F& f) ->bolts<detail_fo::bolt<F, A...>, void>
	{
		return bolts<detail_fo::bolt<F, A...>, void>(detail_fo::bolt<F, A...>(f));
	}

	//no action
	template <typename... A>
	auto gen() ->bolts<detail_fo::bolt<detail_fo::no_action, A...>, void>
	{
		return bolts<detail_fo::bolt<detail_fo::no_action, A...>, void>
			(detail_fo::bolt<detail_fo::no_action, A...>(detail_fo::no_action{}));
	}

	//----------------------------------
	//template <typename T>
	//using is_xxx = mymd::is_some_rr<std::is_yyyy, std::is_zzzz>::apply<T>;
	//using is_xxx = mymd::is_every_rr<std::is_yyyy, std::is_zzzz>::apply<T>;

	template <template <typename> class first, template <typename> class... tail>
	struct is_some_rr	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value || is_some_rr<tail...>::template apply<T>::value;
		};
	};

	template <template <typename> class first>
	struct is_some_rr<first>	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value;
		};
	};

	template <template <typename> class first, template <typename> class... tail>
	struct is_every_rr	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value && is_every_rr<tail...>::template apply<T>::value;
		};
	};

	template <template <typename> class first>
	struct is_every_rr<first>	{
		template <typename T>
		struct apply	{
			using T2 = typename std::remove_reference<T>::type;
			static constexpr bool value = first<T2>::value;
		};
	};
}

#endif
<|endoftext|>


<commit_before><commit_msg>Re-enable property tree verification for layout tests<commit_after><|endoftext|>


<commit_before>#include "../ht.h"
#include "game/sdl/sdlspritemgr.h"
#include "game/sdl/hosthelpers.h"
#include "game/sdl/sdlspritemgr.h"

namespace wi {

static SdlSpriteManager *s_psprm;
static Size s_siz;

Display *HostCreateDisplay() {
	// Create a display

	Display *pdisp = new Display();
	if (pdisp == NULL)
		return NULL;
	if (!pdisp->Init()) {
		delete pdisp;
		return NULL;
	}
	return pdisp;
}

Display::Display()
{
	m_cx = 0;
	m_cy = 0;
	memset(m_amodeInfo, 0, sizeof(m_amodeInfo));
	m_imode = -1;
	m_cmodes = 0;
	m_pbmBack = NULL;
	m_pbmFront = NULL;
	m_pbmClip = NULL;

    m_window = NULL;
    m_renderer = NULL;
    m_texture = NULL;

    m_gamePixels = NULL;
    m_gamePixels32 = NULL;
    memset(m_palette, 0, sizeof(m_palette));
    m_pitch32 = 0;
    m_pixelCount = 0;

    m_density = 0;
    m_fShouldRender = false;
}

Display::~Display()
{
	delete m_pbmBack;
	m_pbmBack = NULL;
	delete m_pbmFront;
	m_pbmFront = NULL;
	delete m_pbmClip;
	m_pbmClip = NULL;

    SDL_DestroyWindow(m_window);
    m_window = NULL;
    SDL_DestroyRenderer(m_renderer);
    m_renderer = NULL;
    SDL_DestroyTexture(m_texture);
    m_texture = NULL;

    delete m_gamePixels;
    m_gamePixels = NULL;
    delete m_gamePixels32;
    m_gamePixels32 = NULL;
}

bool Display::Init()
{
    dword videoflags;

    /* Initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        LOG() << "Couldn't initialize SDL: " << SDL_GetError();
        return false;
    }

	// Absolutely do not mess with SDL_FULLSCREEN if there is any chance the app
	// will crash or stop at a breakpoint. If it does you will be lost in full
	// screen mode! (ssh from another machine and kill the Xcode process)
    videoflags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_SHOWN;
    #if defined(__IPHONEOS__) || defined(__ANDROID__)
    videoflags = videoflags | SDL_WINDOW_BORDERLESS;
    SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight LandscapeLeft");
    #endif

    // Android wants to process mouse and touch events separately
    #if defined(__ANDROID__)
    SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
    #endif

    // Get surface properties
    SurfaceProperties props;
    HostHelpers::GetSurfaceProperties(&props);
    m_cx = props.cxWidth;
    m_cy = props.cyHeight;
    m_density = props.density;

    // Create window
    if ((m_window = SDL_CreateWindow("Hostile Takeover", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_cx, m_cy, videoflags)) == NULL) {
        LOG() << "Couldn't create window: " << m_cx << "x" << m_cy << " \nError: " << SDL_GetError();
        return false;
    }

    // Create renderer
    m_renderer = SDL_CreateRenderer(m_window, 0, SDL_RENDERER_TARGETTEXTURE);
    this->SetShouldRender(true);

    // Keep the screen size around
    s_siz.cx = m_cx;
    s_siz.cy = m_cy;

    // Create texture
    m_texture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, m_cx, m_cy);

    // Set pixel info
    m_pixelCount = m_cx * m_cy;
    m_gamePixels = (byte *)malloc(m_pixelCount);
    m_gamePixels32 = (dword *)malloc(m_pixelCount * 4);
    m_pitch32 = m_cx * sizeof(dword);

    // Keep the screen size around
    s_siz.cx = m_cx;
    s_siz.cy = m_cy;

    ModeInfo *pmode = m_amodeInfo;

#if 1
    pmode->nDepth = 8;
    pmode->cx = props.cxWidth;
    pmode->cy = props.cyHeight;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 0;
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cyHeight;
    pmode->cy = props.cxWidth;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 90; // leftie controls
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cxWidth;
    pmode->cy = props.cyHeight;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 180; // bizzaro controls
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cyHeight;
    pmode->cy = props.cxWidth;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 270; // rightie controls
    pmode++;
#endif

    m_cmodes = pmode - m_amodeInfo;

    HostOutputDebugString("Display::Init %d", pmode - m_amodeInfo);
    HostOutputDebugString("Display::Init %d modes", m_cmodes);

#if defined(__IPHONEOS__)
    HostHelpers::DisplayInitComplete();
#endif
    return true;
}

void Display::SetPalette(Palette *ppal)
{
	SDL_Color aclr[256];
	int cEntries = BigWord(ppal->cEntries);
	byte *pb = (byte *)ppal->argb;
	SDL_Color *pclr = aclr;

	for (int i = 0; i < cEntries; i++) {
		pclr->r = *pb++;
		pclr->g = *pb++;
		pclr->b = *pb++;
		pclr++;
	}

    for (int i = 0; i < cEntries; i++) {
        m_palette[i] = ((Uint8)aclr[i].r << 16) | ((Uint8)aclr[i].g << 8) | ((Uint8)aclr[i].b << 0);
    }

}

int Display::GetModeCount()
{
    return m_cmodes;
}

void Display::GetModeInfo(int imode, ModeInfo *pmode)
{
	memset(pmode, 0, sizeof(*pmode));
	if (imode >= 0 && imode < m_cmodes)
		*pmode = m_amodeInfo[imode];
}

int Display::GetMode(ModeInfo *pmode)
{
	if (pmode != NULL) {
		if (m_imode == -1) {
			memset(pmode, 0, sizeof(*pmode));
		} else {
			*pmode = m_amodeInfo[m_imode];
		}
	}
	return m_imode;
}

bool Display::SetMode(int imode)
{
    // Allocate dib

	ModeInfo *pmode = &m_amodeInfo[imode];

	DibBitmap *pbmBack = CreateDibBitmap(NULL, pmode->cx, pmode->cy);
	if (pbmBack == NULL)
		return false;

    DibBitmap *pbmFront = CreateDibBitmap(m_gamePixels, pmode->cx, pmode->cy);
	if (pbmFront == NULL) {
		delete pbmBack;
		return NULL;
	}
	delete m_pbmBack;
	delete m_pbmFront;
	m_pbmBack = pbmBack;
	m_pbmFront = pbmFront;
	m_imode = imode;

	return true;
}

void Display::DrawText(const char *psz, int x, int y, word wf)
{
}

void Display::DrawFrameInclusive(Rect *prc)
{
}

DibBitmap *Display::GetBackDib()
{
    return m_pbmBack;
}

DibBitmap *Display::GetFrontDib()
{
    return m_pbmFront;
}

DibBitmap *Display::GetClippingDib()
{
    DibBitmap *pbm = CreateDibBitmap(NULL, kcCopyBy4Procs * 4, kcCopyBy4Procs * 4);
    if (pbm == NULL)
		return NULL;
	m_pbmClip = pbm;
	return pbm;
}

void Display::GetHslAdjustments(short *pnHueOffset, short *pnSatMultiplier, short *pnLumOffset)
{
	*pnHueOffset = 0;
	*pnSatMultiplier = 0;
	*pnLumOffset = 0;
}

void Display::FrameStart()
{
    // surface->pixels can change every time the surface is locked.
	// TODO(darrinm): problem for, e.g. scrolling optimizations?
    m_pbmFront->Init(m_gamePixels, m_cx, m_cy);
}

void Display::FrameComplete(int cfrmm, UpdateMap **apupd, Rect *arc,
        bool fScrolled)
{
    for (int i = 0; i < m_pixelCount; i++) {
        m_gamePixels32[i] = m_palette[m_gamePixels[i]];
    }

    RenderGameSurface();
}

void Display::RenderGameSurface() {
    if (!m_fShouldRender)
        return;

    // Update the texture
    SDL_UpdateTexture(m_texture, NULL, m_gamePixels32, m_pitch32);

    // Draw any sprites onto the texture
    SDL_SetRenderTarget(m_renderer, m_texture);
    s_psprm->DrawSprites(m_renderer, s_siz);
    SDL_SetRenderTarget(m_renderer, NULL);

    // Present the renderer to the screen
    SDL_RenderClear(m_renderer);
    SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
    SDL_RenderPresent(m_renderer);
}

void Display::ResetScrollOffset()
{
#if 0 // TODO(darrinm): SDL-ify
    IPhone::ResetScrollOffset();
#endif
}

SpriteManager *Display::GetSpriteManager()
{
	if (s_psprm == NULL)
		s_psprm = new SdlSpriteManager();
	return s_psprm;
}

void Display::SetFormMgrs(FormMgr *pfrmmSimUI, FormMgr *pfrmmInput)
{
#if 0 // TODO(darrinm): SDL-ify
    IPhone::SetFormMgrs(pfrmmSimUI, pfrmmInput);
#endif
}

float Display::Density() {
    return m_density;
}

void Display::SetShouldRender(bool fsr) {
    m_fShouldRender = fsr;
}

} // namespace wi
<commit_msg>Use free for malloc-ed objects<commit_after>#include "../ht.h"
#include "game/sdl/sdlspritemgr.h"
#include "game/sdl/hosthelpers.h"
#include "game/sdl/sdlspritemgr.h"

namespace wi {

static SdlSpriteManager *s_psprm;
static Size s_siz;

Display *HostCreateDisplay() {
	// Create a display

	Display *pdisp = new Display();
	if (pdisp == NULL)
		return NULL;
	if (!pdisp->Init()) {
		delete pdisp;
		return NULL;
	}
	return pdisp;
}

Display::Display()
{
	m_cx = 0;
	m_cy = 0;
	memset(m_amodeInfo, 0, sizeof(m_amodeInfo));
	m_imode = -1;
	m_cmodes = 0;
	m_pbmBack = NULL;
	m_pbmFront = NULL;
	m_pbmClip = NULL;

    m_window = NULL;
    m_renderer = NULL;
    m_texture = NULL;

    m_gamePixels = NULL;
    m_gamePixels32 = NULL;
    memset(m_palette, 0, sizeof(m_palette));
    m_pitch32 = 0;
    m_pixelCount = 0;

    m_density = 0;
    m_fShouldRender = false;
}

Display::~Display()
{
	delete m_pbmBack;
	m_pbmBack = NULL;
	delete m_pbmFront;
	m_pbmFront = NULL;
	delete m_pbmClip;
	m_pbmClip = NULL;

    SDL_DestroyWindow(m_window);
    m_window = NULL;
    SDL_DestroyRenderer(m_renderer);
    m_renderer = NULL;
    SDL_DestroyTexture(m_texture);
    m_texture = NULL;

    free(m_gamePixels);
    m_gamePixels = NULL;
    free(m_gamePixels32);
    m_gamePixels32 = NULL;
}

bool Display::Init()
{
    dword videoflags;

    /* Initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        LOG() << "Couldn't initialize SDL: " << SDL_GetError();
        return false;
    }

	// Absolutely do not mess with SDL_FULLSCREEN if there is any chance the app
	// will crash or stop at a breakpoint. If it does you will be lost in full
	// screen mode! (ssh from another machine and kill the Xcode process)
    videoflags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_SHOWN;
    #if defined(__IPHONEOS__) || defined(__ANDROID__)
    videoflags = videoflags | SDL_WINDOW_BORDERLESS;
    SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight LandscapeLeft");
    #endif

    // Android wants to process mouse and touch events separately
    #if defined(__ANDROID__)
    SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
    #endif

    // Get surface properties
    SurfaceProperties props;
    HostHelpers::GetSurfaceProperties(&props);
    m_cx = props.cxWidth;
    m_cy = props.cyHeight;
    m_density = props.density;

    // Create window
    if ((m_window = SDL_CreateWindow("Hostile Takeover", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_cx, m_cy, videoflags)) == NULL) {
        LOG() << "Couldn't create window: " << m_cx << "x" << m_cy << " \nError: " << SDL_GetError();
        return false;
    }

    // Create renderer
    m_renderer = SDL_CreateRenderer(m_window, 0, SDL_RENDERER_TARGETTEXTURE);
    this->SetShouldRender(true);

    // Keep the screen size around
    s_siz.cx = m_cx;
    s_siz.cy = m_cy;

    // Create texture
    m_texture = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, m_cx, m_cy);

    // Set pixel info
    m_pixelCount = m_cx * m_cy;
    m_gamePixels = (byte *)malloc(m_pixelCount);
    m_gamePixels32 = (dword *)malloc(m_pixelCount * 4);
    m_pitch32 = m_cx * sizeof(dword);

    // Keep the screen size around
    s_siz.cx = m_cx;
    s_siz.cy = m_cy;

    ModeInfo *pmode = m_amodeInfo;

#if 1
    pmode->nDepth = 8;
    pmode->cx = props.cxWidth;
    pmode->cy = props.cyHeight;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 0;
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cyHeight;
    pmode->cy = props.cxWidth;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 90; // leftie controls
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cxWidth;
    pmode->cy = props.cyHeight;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 180; // bizzaro controls
    pmode++;
#endif

#if 0
    pmode->nDepth = 8;
    pmode->cx = props.cyHeight;
    pmode->cy = props.cxWidth;
    pmode->cyGraffiti = 0;
    pmode->fNative = true;
    pmode->nDegreeOrientation = 270; // rightie controls
    pmode++;
#endif

    m_cmodes = pmode - m_amodeInfo;

    HostOutputDebugString("Display::Init %d", pmode - m_amodeInfo);
    HostOutputDebugString("Display::Init %d modes", m_cmodes);

#if defined(__IPHONEOS__)
    HostHelpers::DisplayInitComplete();
#endif
    return true;
}

void Display::SetPalette(Palette *ppal)
{
	SDL_Color aclr[256];
	int cEntries = BigWord(ppal->cEntries);
	byte *pb = (byte *)ppal->argb;
	SDL_Color *pclr = aclr;

	for (int i = 0; i < cEntries; i++) {
		pclr->r = *pb++;
		pclr->g = *pb++;
		pclr->b = *pb++;
		pclr++;
	}

    for (int i = 0; i < cEntries; i++) {
        m_palette[i] = ((Uint8)aclr[i].r << 16) | ((Uint8)aclr[i].g << 8) | ((Uint8)aclr[i].b << 0);
    }

}

int Display::GetModeCount()
{
    return m_cmodes;
}

void Display::GetModeInfo(int imode, ModeInfo *pmode)
{
	memset(pmode, 0, sizeof(*pmode));
	if (imode >= 0 && imode < m_cmodes)
		*pmode = m_amodeInfo[imode];
}

int Display::GetMode(ModeInfo *pmode)
{
	if (pmode != NULL) {
		if (m_imode == -1) {
			memset(pmode, 0, sizeof(*pmode));
		} else {
			*pmode = m_amodeInfo[m_imode];
		}
	}
	return m_imode;
}

bool Display::SetMode(int imode)
{
    // Allocate dib

	ModeInfo *pmode = &m_amodeInfo[imode];

	DibBitmap *pbmBack = CreateDibBitmap(NULL, pmode->cx, pmode->cy);
	if (pbmBack == NULL)
		return false;

    DibBitmap *pbmFront = CreateDibBitmap(m_gamePixels, pmode->cx, pmode->cy);
	if (pbmFront == NULL) {
		delete pbmBack;
		return NULL;
	}
	delete m_pbmBack;
	delete m_pbmFront;
	m_pbmBack = pbmBack;
	m_pbmFront = pbmFront;
	m_imode = imode;

	return true;
}

void Display::DrawText(const char *psz, int x, int y, word wf)
{
}

void Display::DrawFrameInclusive(Rect *prc)
{
}

DibBitmap *Display::GetBackDib()
{
    return m_pbmBack;
}

DibBitmap *Display::GetFrontDib()
{
    return m_pbmFront;
}

DibBitmap *Display::GetClippingDib()
{
    DibBitmap *pbm = CreateDibBitmap(NULL, kcCopyBy4Procs * 4, kcCopyBy4Procs * 4);
    if (pbm == NULL)
		return NULL;
	m_pbmClip = pbm;
	return pbm;
}

void Display::GetHslAdjustments(short *pnHueOffset, short *pnSatMultiplier, short *pnLumOffset)
{
	*pnHueOffset = 0;
	*pnSatMultiplier = 0;
	*pnLumOffset = 0;
}

void Display::FrameStart()
{
    // surface->pixels can change every time the surface is locked.
	// TODO(darrinm): problem for, e.g. scrolling optimizations?
    m_pbmFront->Init(m_gamePixels, m_cx, m_cy);
}

void Display::FrameComplete(int cfrmm, UpdateMap **apupd, Rect *arc,
        bool fScrolled)
{
    for (int i = 0; i < m_pixelCount; i++) {
        m_gamePixels32[i] = m_palette[m_gamePixels[i]];
    }

    RenderGameSurface();
}

void Display::RenderGameSurface() {
    if (!m_fShouldRender)
        return;

    // Update the texture
    SDL_UpdateTexture(m_texture, NULL, m_gamePixels32, m_pitch32);

    // Draw any sprites onto the texture
    SDL_SetRenderTarget(m_renderer, m_texture);
    s_psprm->DrawSprites(m_renderer, s_siz);
    SDL_SetRenderTarget(m_renderer, NULL);

    // Present the renderer to the screen
    SDL_RenderClear(m_renderer);
    SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
    SDL_RenderPresent(m_renderer);
}

void Display::ResetScrollOffset()
{
#if 0 // TODO(darrinm): SDL-ify
    IPhone::ResetScrollOffset();
#endif
}

SpriteManager *Display::GetSpriteManager()
{
	if (s_psprm == NULL)
		s_psprm = new SdlSpriteManager();
	return s_psprm;
}

void Display::SetFormMgrs(FormMgr *pfrmmSimUI, FormMgr *pfrmmInput)
{
#if 0 // TODO(darrinm): SDL-ify
    IPhone::SetFormMgrs(pfrmmSimUI, pfrmmInput);
#endif
}

float Display::Density() {
    return m_density;
}

void Display::SetShouldRender(bool fsr) {
    m_fShouldRender = fsr;
}

} // namespace wi
<|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/core/reduce_pre_probing_table.hpp
 *
 * Hash table with support for reduce and partitions.
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Matthias Stumpp <mstumpp@gmail.com>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER
#define C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER

#include <c7a/common/function_traits.hpp>
#include <c7a/common/logger.hpp>
#include <c7a/data/manager.hpp>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

namespace c7a {
namespace core {
template <typename KeyExtractor, typename ReduceFunction, typename EmitterFunction>
class ReducePreProbingTable
{
    static const bool debug = false;

    using Key = typename common::FunctionTraits<KeyExtractor>::result_type;

    using Value = typename common::FunctionTraits<ReduceFunction>::result_type;

    typedef std::pair<Key, Value> KeyValuePair;

protected:
    struct hash_result
    {
        //! which partition number the item belongs to.
        size_t partition_id;
        //! index within the partition's sub-hashtable of this item
        size_t partition_offset;
        //! index within the whole hashtable
        size_t global_index;

        hash_result(size_t p_id, size_t p_off, size_t g_id) {
            partition_id = p_id;
            partition_offset = p_off;
            global_index = g_id;
        }
    };

    struct probing_result
    {
        //! the offset relativ to provided pos.
        int probing_offset;

        explicit probing_result(int o) {
            probing_offset = o;
        }
    };

public:
    typedef std::function<hash_result(Key, ReducePreProbingTable*)> HashFunction;

    typedef std::function<probing_result(int, ReducePreProbingTable*)> ProbingFunction;

    ReducePreProbingTable(size_t num_partitions,
                          size_t num_items_init_scale,
                          size_t num_items_resize_scale,
                          size_t stepsize,
                          size_t max_stepsize,
                          double max_partition_fill_ratio,
                          size_t max_num_items_table,
                          KeyExtractor key_extractor, ReduceFunction reduce_function,
                          std::vector<EmitterFunction>& emit,
                          std::pair<Key, Value> sentinel,
                          HashFunction hash_function
                              = [](Key v, ReducePreProbingTable* ht) {
                                    size_t hashed = std::hash<Key>() (v);

                                    size_t partition_offset = hashed %
                                                              ht->num_items_per_partition_;
                                    size_t partition_id = hashed % ht->num_partitions_;
                                    size_t global_index = partition_id *
                                                          ht->num_items_per_partition_ +
                                                          partition_offset;
                                    hash_result hr(partition_id, partition_offset, global_index);
                                    return hr;
                                },
                          ProbingFunction probing_function
                              = [](int pos, ReducePreProbingTable*) {
                                    int probing_offset = pos + 1;
                                    probing_result pr(probing_offset);
                                    return pr;
                                })
        : num_partitions_(num_partitions),
          num_items_init_scale_(num_items_init_scale),
          num_items_resize_scale_(num_items_resize_scale),
          stepsize_(stepsize),
          max_stepsize_(max_stepsize),
          max_partition_fill_ratio_(max_partition_fill_ratio),
          max_num_items_table_(max_num_items_table),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function),
          probing_function_(probing_function) {
        init(sentinel);
    }

    ReducePreProbingTable(size_t num_partitions, KeyExtractor key_extractor,
                          ReduceFunction reduce_function, std::vector<EmitterFunction>& emit,
                          std::pair<Key, Value> sentinel,
                          HashFunction hash_function
                              = [](Key v, ReducePreProbingTable* ht) {
                                    size_t hashed = std::hash<Key>() (v);

                                    size_t partition_offset = hashed %
                                                              ht->num_items_per_partition_;
                                    size_t partition_id = hashed % ht->num_partitions_;
                                    size_t global_index = partition_id *
                                                          ht->num_items_per_partition_ +
                                                          partition_offset;
                                    hash_result hr(partition_id, partition_offset, global_index);
                                    return hr;
                                },
                          ProbingFunction probing_function
                              = [](int pos, ReducePreProbingTable*) {
                                    int probing_offset = pos + 1;
                                    probing_result pr(probing_offset);
                                    return pr;
                                })
        : num_partitions_(num_partitions),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function),
          probing_function_(probing_function) {
        init(sentinel);
    }

    //! non-copyable: delete copy-constructor
    ReducePreProbingTable(const ReducePreProbingTable&) = delete;
    //! non-copyable: delete assignment operator
    ReducePreProbingTable& operator = (const ReducePreProbingTable&) = delete;

    ~ReducePreProbingTable() { }

    void init(std::pair<Key, Value> sentinel) {
        sLOG << "creating ReducePreProbingTable with" << emit_.size() << "output emiters";
        for (size_t i = 0; i < emit_.size(); i++)
            emit_stats_.push_back(0);

        num_items_ = num_partitions_ * num_items_init_scale_;
        if (num_partitions_ > num_items_ &&
            num_items_ % num_partitions_ != 0) {
            throw std::invalid_argument("partition_size must be less than or equal to num_items "
                                        "AND partition_size a divider of num_items");
        }
        num_items_per_partition_ = num_items_ / num_partitions_;

        // set the key to initial key
        sentinel_ = KeyValuePair(sentinel.first, sentinel.second);
        vector_.resize(num_items_, sentinel_);
        items_per_partition_.resize(num_partitions_, 0);
    }

    /*!
     * Inserts a key/value pair.
     *
     * Optionally, this may be reduce using the reduce function
     * in case the key already exists.
     */
    void Insert(Value&& p) {
        Key key = key_extractor_(p);

        hash_result h = hash_function_(key, this);

        int pos = h.global_index;
        size_t count = 0;

        KeyValuePair* current = &vector_[pos];

        while (current->first != sentinel_.first)
        {
            if (current->first == key)
            {
                LOG << "match of key: " << key
                    << " and " << current->first << " ... reducing...";

                current->second = reduce_function_(current->second, p);

                LOG << "...finished reduce!";
                return;
            }

            //++count;
            probing_result pr = probing_function_(pos, this);
            count += pr.probing_offset;

            if (count > max_stepsize_ || count > num_items_per_partition_)
            {
                ResizeUp();
                Insert(std::move(p));
                return;
            }

            if (h.partition_offset + count >= num_items_per_partition_)
            {
                pos -= (h.partition_offset + count);
            }

            current = &vector_[pos + count];
        }

        // insert new pair
        if (current->first == sentinel_.first)
        {
            vector_[pos + count] = KeyValuePair(key, p);

            // increase total counter
            table_size_++;

            // increase counter for partition
            items_per_partition_[h.partition_id]++;
        }

        if (table_size_ > max_num_items_table_)
        {
            LOG << "flush";
            FlushLargestPartition();
        }

        if (items_per_partition_[h.partition_id]
            / num_items_per_partition_ > max_partition_fill_ratio_)
        {
            LOG << "resize";
            ResizeUp();
        }
    }

    /*!
    * Flushes all items.
    */
    void Flush() {
        LOG << "Flushing all items";

        // retrieve items
        for (size_t i = 0; i < num_partitions_; i++)
        {
            FlushPartition(i);
        }

        LOG << "Flushed all items";
    }

    /*!
     * Retrieves all items belonging to the partition
     * having the most items. Retrieved items are then forward
     * to the provided emitter.
     */
    void FlushLargestPartition() {
        LOG << "Flushing items of largest partition";

        // get partition with max size
        size_t p_size_max = 0;
        size_t p_idx = 0;
        for (size_t i = 0; i < num_partitions_; i++)
        {
            if (items_per_partition_[i] > p_size_max)
            {
                p_size_max = items_per_partition_[i];
                p_idx = i;
            }
        }

        LOG << "currMax: "
            << p_size_max
            << " currentIdx: "
            << p_idx
            << " currentIdx*p_size: "
            << p_idx * num_items_per_partition_
            << " CurrentIdx*p_size+p_size-1 "
            << p_idx * num_items_per_partition_ + num_items_per_partition_ - 1;

        LOG << "Largest patition id: "
            << p_idx;

        FlushPartition(p_idx);

        LOG << "Flushed items of largest partition";
    }

    /*!
     * Flushes all items of a partition.
     */
    void FlushPartition(size_t partition_id) {
        LOG << "Flushing items of partition with id: "
            << partition_id;

        for (size_t i = partition_id * num_items_per_partition_;
             i < partition_id * num_items_per_partition_ + num_items_per_partition_; i++)
        {
            KeyValuePair current = vector_[i];
            if (current.first != sentinel_.first)
            {
                emit_[partition_id](std::move(current.second));
                vector_[i] = sentinel_;
            }
        }

        // reset total counter
        table_size_ -= items_per_partition_[partition_id];
        // reset partition specific counter
        items_per_partition_[partition_id] = 0;
        // flush elements pushed into emitter
        emit_[partition_id].Flush();

        LOG << "Flushed items of partition with id: "
            << partition_id;
    }

    /*!
     * Returns the total num of items.
     */
    size_t Size() {
        return table_size_;
    }

    /*!
     * Returns the total num of items.
     */
    size_t NumItems() {
        return num_items_;
    }

    /*!
     * Returns the number of buckets per partition.
     */
    size_t NumItemsPerPartition() {
        return num_items_per_partition_;
    }

    /*!
     * Returns the number of partitions.
     */
    size_t NumPartitions() {
        return num_partitions_;
    }

    /*!
     * Returns the size of a partition referenzed by partition_id.
     */
    size_t PartitionSize(size_t partition_id) {
        return items_per_partition_[partition_id];
    }

    /*!
     * Sets the maximum size of the hash table. We don't want to push 2vt
     * elements before flush happens.
     */
    void SetMaxSize(size_t size) {
        max_num_items_table_ = size;
    }

    /*!
     * Closes all emitter
     */
    void CloseEmitter() {
        sLOG << "emit stats: ";
        unsigned int i = 0;
        for (auto& e : emit_) {
            e.Close();
            sLOG << "emitter " << i << " pushed " << emit_stats_[i++];
        }
    }

    /*!
     * Resizes the table by increasing the number of items using some
     * resize scale factor. All items are rehashed as part of the operation.
     */
    void ResizeUp() {
        LOG << "Resizing";
        num_items_ *= num_items_resize_scale_;
        num_items_per_partition_ = num_items_ / num_partitions_;
        // reset items_per_partition and table_size
        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;

        // move old hash array
        std::vector<KeyValuePair> vector_old;
        std::swap(vector_old, vector_);

        // init new hash array
        vector_.resize(num_items_, sentinel_);

        // rehash all items in old array
        for (KeyValuePair k_v_pair : vector_old)
        {
            KeyValuePair current = k_v_pair;
            if (current.first != sentinel_.first)
            {
                Insert(std::move(current.second));
            }
        }
        LOG << "Resized";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Clear() {
        LOG << "Clearing";

        for (KeyValuePair k_v_pair : vector_)
        {
            k_v_pair = sentinel_; // TODO(ms): fix, doesnt work
        }

        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;
        LOG << "Cleared";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Reset() {
        LOG << "Resetting";
        num_items_ = num_partitions_ * num_items_init_scale_;
        num_items_per_partition_ = num_items_ / num_partitions_;

        for (KeyValuePair k_v_pair : vector_)
        {
            k_v_pair = sentinel_; // TODO(ms): fix, doesnt work
        }

        vector_.resize(num_items_, sentinel_);
        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;
        LOG << "Resetted";
    }

    /*!
    * Prints content of hash table.
    */
    void Print() {

        std::string log = "Printing\n";

        for (size_t i = 0; i < num_items_; i++)
        {
            if (vector_[i].first == sentinel_.first)
            {
                log += "item: ";
                log += std::to_string(i);
                log += " empty\n";
                continue;
            }

            log += "item: ";
            log += std::to_string(i);
            log += " (";
            log += vector_[i].first;
            log += ", ";
            //log += vector_[i].second; // TODO(ms): How to convert Value to a string?
            log += ")\n";
        }

        std::cout << log << std::endl;

        return;
    }

private:
    size_t num_partitions_;                         // partition size

    size_t num_items_init_scale_ = 10;              // set number of items per partition based on num_partitions
    // multiplied with some scaling factor, must be equal to or greater than 1

    size_t num_items_resize_scale_ = 2;             // resize scale on max_num_items_per_bucket_

    size_t stepsize_ = 1;                           // stepsize in case of collision

    size_t max_stepsize_ = 10;                      // max stepsize before resize

    double max_partition_fill_ratio_ = 0.9;         // max partition fill ratio before resize

    size_t max_num_items_table_ = 1048576;          // max num of items before spilling of largest partition

    size_t num_items_;                              // num items

    size_t num_items_per_partition_;                // num items per partition

    std::vector<size_t> items_per_partition_;       // num items per partition

    size_t table_size_ = 0;                         // total number of items

    KeyExtractor key_extractor_;

    ReduceFunction reduce_function_;

    std::vector<EmitterFunction> emit_;
    std::vector<int> emit_stats_;

    std::vector<KeyValuePair> vector_;

    KeyValuePair sentinel_;

    HashFunction hash_function_;
    ProbingFunction probing_function_;
};

} // namespace core
} // namespace c7a

#endif // !C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER

/******************************************************************************/
<commit_msg>Adding REVIEW comments to reduce_pre_probing_table.<commit_after>/*******************************************************************************
 * c7a/core/reduce_pre_probing_table.hpp
 *
 * Hash table with support for reduce and partitions.
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Matthias Stumpp <mstumpp@gmail.com>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER
#define C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER

#include <c7a/common/function_traits.hpp>
#include <c7a/common/logger.hpp>
#include <c7a/data/manager.hpp>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

namespace c7a {
namespace core {
template <typename KeyExtractor, typename ReduceFunction, typename EmitterFunction>
class ReducePreProbingTable
{
    static const bool debug = false;

    using Key = typename common::FunctionTraits<KeyExtractor>::result_type;

    using Value = typename common::FunctionTraits<ReduceFunction>::result_type;

    typedef std::pair<Key, Value> KeyValuePair;

protected:
    struct hash_result
    {
        //! which partition number the item belongs to.
        size_t partition_id;
        //! index within the partition's sub-hashtable of this item
        size_t partition_offset;
        //! index within the whole hashtable
        size_t global_index;

        hash_result(size_t p_id, size_t p_off, size_t g_id) {
            partition_id = p_id;
            partition_offset = p_off;
            global_index = g_id;
        }
    };

    // REVIEW(ms): remove the probing_result stuff, no other policy than linear is needed.
    struct probing_result
    {
        //! the offset relativ to provided pos.
        int probing_offset;

        explicit probing_result(int o) {
            probing_offset = o;
        }
    };

public:
    typedef std::function<hash_result(Key, ReducePreProbingTable*)> HashFunction;

    typedef std::function<probing_result(int, ReducePreProbingTable*)> ProbingFunction;

    ReducePreProbingTable(size_t num_partitions,
                          size_t num_items_init_scale,
                          size_t num_items_resize_scale,
                          size_t stepsize,
                          size_t max_stepsize,
                          double max_partition_fill_ratio,
                          size_t max_num_items_table,
                          KeyExtractor key_extractor, ReduceFunction reduce_function,
                          std::vector<EmitterFunction>& emit,
                          std::pair<Key, Value> sentinel,
                          HashFunction hash_function
                              = [](Key v, ReducePreProbingTable* ht) {
                                    size_t hashed = std::hash<Key>() (v);

                                    size_t partition_offset = hashed %
                                                              ht->num_items_per_partition_;
                                    size_t partition_id = hashed % ht->num_partitions_;
                                    size_t global_index = partition_id *
                                                          ht->num_items_per_partition_ +
                                                          partition_offset;
                                    hash_result hr(partition_id, partition_offset, global_index);
                                    return hr;
                                },
                          ProbingFunction probing_function
                              = [](int pos, ReducePreProbingTable*) {
                                    int probing_offset = pos + 1;
                                    probing_result pr(probing_offset);
                                    return pr;
                                })
        : num_partitions_(num_partitions),
          num_items_init_scale_(num_items_init_scale),
          num_items_resize_scale_(num_items_resize_scale),
          stepsize_(stepsize),
          max_stepsize_(max_stepsize),
          max_partition_fill_ratio_(max_partition_fill_ratio),
          max_num_items_table_(max_num_items_table),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function),
          probing_function_(probing_function) {
        init(sentinel);
    }

    ReducePreProbingTable(size_t num_partitions, KeyExtractor key_extractor,
                          ReduceFunction reduce_function, std::vector<EmitterFunction>& emit,
                          std::pair<Key, Value> sentinel,
                          HashFunction hash_function
                              = [](Key v, ReducePreProbingTable* ht) {
                                    size_t hashed = std::hash<Key>() (v);

                                    size_t partition_offset = hashed %
                                                              ht->num_items_per_partition_;
                                    size_t partition_id = hashed % ht->num_partitions_;
                                    size_t global_index = partition_id *
                                                          ht->num_items_per_partition_ +
                                                          partition_offset;
                                    hash_result hr(partition_id, partition_offset, global_index);
                                    return hr;
                                },
                          ProbingFunction probing_function
                              = [](int pos, ReducePreProbingTable*) {
                                    int probing_offset = pos + 1;
                                    probing_result pr(probing_offset);
                                    return pr;
                                })
        : num_partitions_(num_partitions),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function),
          probing_function_(probing_function) {
        init(sentinel);
    }

    //! non-copyable: delete copy-constructor
    ReducePreProbingTable(const ReducePreProbingTable&) = delete;
    //! non-copyable: delete assignment operator
    ReducePreProbingTable& operator = (const ReducePreProbingTable&) = delete;

    ~ReducePreProbingTable() { }

    void init(std::pair<Key, Value> sentinel) {
        sLOG << "creating ReducePreProbingTable with" << emit_.size() << "output emiters";
        for (size_t i = 0; i < emit_.size(); i++)
            emit_stats_.push_back(0);

        num_items_ = num_partitions_ * num_items_init_scale_;
        if (num_partitions_ > num_items_ &&
            num_items_ % num_partitions_ != 0) {
            throw std::invalid_argument("partition_size must be less than or equal to num_items "
                                        "AND partition_size a divider of num_items");
        }
        num_items_per_partition_ = num_items_ / num_partitions_;

        // set the key to initial key
        sentinel_ = KeyValuePair(sentinel.first, sentinel.second);
        vector_.resize(num_items_, sentinel_);
        items_per_partition_.resize(num_partitions_, 0);
    }

    /*!
     * Inserts a key/value pair.
     *
     * Optionally, this may be reduce using the reduce function
     * in case the key already exists.
     */
    void Insert(Value&& p) {
        Key key = key_extractor_(p);

        hash_result h = hash_function_(key, this);

        int pos = h.global_index;
        size_t count = 0;

        // REVIEW(ms): try to make the loop tighter, remove extra variables and
        // try to reduce the number of +/-/< operations, have only current + end
        // iterators.
        KeyValuePair* current = &vector_[pos];

        while (current->first != sentinel_.first)
        {
            if (current->first == key)
            {
                LOG << "match of key: " << key
                    << " and " << current->first << " ... reducing...";

                current->second = reduce_function_(current->second, p);

                LOG << "...finished reduce!";
                return;
            }

            //++count;
            probing_result pr = probing_function_(pos, this);
            count += pr.probing_offset;

            if (count > max_stepsize_ || count > num_items_per_partition_)
            {
                ResizeUp();
                Insert(std::move(p));
                return;
            }

            if (h.partition_offset + count >= num_items_per_partition_)
            {
                pos -= (h.partition_offset + count);
            }

            current = &vector_[pos + count];
        }

        // insert new pair
        if (current->first == sentinel_.first)
        {
            vector_[pos + count] = KeyValuePair(key, p);

            // increase total counter
            table_size_++;

            // increase counter for partition
            items_per_partition_[h.partition_id]++;
        }

        if (table_size_ > max_num_items_table_)
        {
            LOG << "flush";
            FlushLargestPartition();
        }

        if (items_per_partition_[h.partition_id]
            / num_items_per_partition_ > max_partition_fill_ratio_)
        {
            LOG << "resize";
            ResizeUp();
        }
    }

    /*!
    * Flushes all items.
    */
    void Flush() {
        LOG << "Flushing all items";

        // retrieve items
        for (size_t i = 0; i < num_partitions_; i++)
        {
            FlushPartition(i);
        }

        LOG << "Flushed all items";
    }

    /*!
     * Retrieves all items belonging to the partition
     * having the most items. Retrieved items are then forward
     * to the provided emitter.
     */
    void FlushLargestPartition() {
        LOG << "Flushing items of largest partition";

        // get partition with max size
        size_t p_size_max = 0;
        size_t p_idx = 0;
        for (size_t i = 0; i < num_partitions_; i++)
        {
            if (items_per_partition_[i] > p_size_max)
            {
                p_size_max = items_per_partition_[i];
                p_idx = i;
            }
        }

        LOG << "currMax: "
            << p_size_max
            << " currentIdx: "
            << p_idx
            << " currentIdx*p_size: "
            << p_idx * num_items_per_partition_
            << " CurrentIdx*p_size+p_size-1 "
            << p_idx * num_items_per_partition_ + num_items_per_partition_ - 1;

        LOG << "Largest patition id: "
            << p_idx;

        FlushPartition(p_idx);

        LOG << "Flushed items of largest partition";
    }

    /*!
     * Flushes all items of a partition.
     */
    void FlushPartition(size_t partition_id) {
        LOG << "Flushing items of partition with id: "
            << partition_id;

        for (size_t i = partition_id * num_items_per_partition_;
             i < partition_id * num_items_per_partition_ + num_items_per_partition_; i++)
        {
            KeyValuePair current = vector_[i];
            if (current.first != sentinel_.first)
            {
                emit_[partition_id](std::move(current.second));
                vector_[i] = sentinel_;
            }
        }

        // reset total counter
        table_size_ -= items_per_partition_[partition_id];
        // reset partition specific counter
        items_per_partition_[partition_id] = 0;
        // flush elements pushed into emitter
        emit_[partition_id].Flush();

        LOG << "Flushed items of partition with id: "
            << partition_id;
    }

    /*!
     * Returns the total num of items.
     */
    size_t Size() {
        return table_size_;
    }

    /*!
     * Returns the total num of items.
     */
    size_t NumItems() {
        return num_items_;
    }

    /*!
     * Returns the number of buckets per partition.
     */
    size_t NumItemsPerPartition() {
        return num_items_per_partition_;
    }

    /*!
     * Returns the number of partitions.
     */
    size_t NumPartitions() {
        return num_partitions_;
    }

    /*!
     * Returns the size of a partition referenzed by partition_id.
     */
    size_t PartitionSize(size_t partition_id) {
        return items_per_partition_[partition_id];
    }

    /*!
     * Sets the maximum size of the hash table. We don't want to push 2vt
     * elements before flush happens.
     */
    void SetMaxSize(size_t size) {
        max_num_items_table_ = size;
    }

    /*!
     * Closes all emitter
     */
    void CloseEmitter() {
        sLOG << "emit stats: ";
        unsigned int i = 0;
        for (auto& e : emit_) {
            e.Close();
            sLOG << "emitter " << i << " pushed " << emit_stats_[i++];
        }
    }

    /*!
     * Resizes the table by increasing the number of items using some
     * resize scale factor. All items are rehashed as part of the operation.
     */
    void ResizeUp() {
        LOG << "Resizing";
        num_items_ *= num_items_resize_scale_;
        num_items_per_partition_ = num_items_ / num_partitions_;
        // reset items_per_partition and table_size
        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;

        // move old hash array
        std::vector<KeyValuePair> vector_old;
        std::swap(vector_old, vector_);

        // init new hash array
        vector_.resize(num_items_, sentinel_);

        // rehash all items in old array
        for (KeyValuePair k_v_pair : vector_old)
        {
            KeyValuePair current = k_v_pair;
            if (current.first != sentinel_.first)
            {
                Insert(std::move(current.second));
            }
        }
        LOG << "Resized";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Clear() {
        LOG << "Clearing";

        for (KeyValuePair k_v_pair : vector_)
        {
            k_v_pair = sentinel_; // TODO(ms): fix, doesnt work
        }

        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;
        LOG << "Cleared";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Reset() {
        LOG << "Resetting";
        num_items_ = num_partitions_ * num_items_init_scale_;
        num_items_per_partition_ = num_items_ / num_partitions_;

        for (KeyValuePair k_v_pair : vector_)
        {
            k_v_pair = sentinel_; // TODO(ms): fix, doesnt work
        }

        vector_.resize(num_items_, sentinel_);
        std::fill(items_per_partition_.begin(), items_per_partition_.end(), 0);
        table_size_ = 0;
        LOG << "Resetted";
    }

    /*!
    * Prints content of hash table.
    */
    void Print() {

        std::string log = "Printing\n";

        for (size_t i = 0; i < num_items_; i++)
        {
            if (vector_[i].first == sentinel_.first)
            {
                log += "item: ";
                log += std::to_string(i);
                log += " empty\n";
                continue;
            }

            log += "item: ";
            log += std::to_string(i);
            log += " (";
            log += vector_[i].first;
            log += ", ";
            // REVIEW(ms): about Value -> String: you cannot in general.

            //log += vector_[i].second; // TODO(ms): How to convert Value to a string?
            log += ")\n";
        }

        std::cout << log << std::endl;

        return;
    }

private:
    // REVIEW(ms): use doxygen format like everyone else! which of these are
    // static const?

    size_t num_partitions_;                         // partition size

    size_t num_items_init_scale_ = 10;              // set number of items per partition based on num_partitions
    // multiplied with some scaling factor, must be equal to or greater than 1

    size_t num_items_resize_scale_ = 2;             // resize scale on max_num_items_per_bucket_

    size_t stepsize_ = 1;                           // stepsize in case of collision

    size_t max_stepsize_ = 10;                      // max stepsize before resize

    double max_partition_fill_ratio_ = 0.9;         // max partition fill ratio before resize

    size_t max_num_items_table_ = 1048576;          // max num of items before spilling of largest partition

    size_t num_items_;                              // num items

    size_t num_items_per_partition_;                // num items per partition

    std::vector<size_t> items_per_partition_;       // num items per partition

    size_t table_size_ = 0;                         // total number of items

    KeyExtractor key_extractor_;

    ReduceFunction reduce_function_;

    std::vector<EmitterFunction> emit_;
    std::vector<int> emit_stats_;

    std::vector<KeyValuePair> vector_;

    KeyValuePair sentinel_;

    HashFunction hash_function_;
    ProbingFunction probing_function_;
};

} // namespace core
} // namespace c7a

#endif // !C7A_CORE_REDUCE_PRE_PROBING_TABLE_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>//       ____  ____     ____                        _____             _
// __  _|___ \|  _ \   / ___| __ _ _ __ ___   ___  | ____|_ __   __ _(_)_ __   ___
// \ \/ / __) | | | | | |  _ / _  |  _   _ \ / _ \ |  _| |  _ \ / _  | |  _ \ / _ \
//  >  < / __/| |_| | | |_| | (_| | | | | | |  __/ | |___| | | | (_| | | | | |  __/
// /_/\_\_____|____/   \____|\__ _|_| |_| |_|\___| |_____|_| |_|\__, |_|_| |_|\___|
//                                                              |___/
//				Originally written by Marcus Loo Vergara (aka. Bitsauce)
//									2011-2015 (C)

#include <CGF/Common.h>
#include <CGF/Graphics.h>
#include <CGF/Input.h>
#include <CGF/Audio.h>

BEGIN_CGF_NAMESPACE

Exception::Exception(RetCode code, const char * msg, ...) :
	m_errorCode(code)
{
	va_list args;
	va_start(args, msg);

	int size = _scprintf(msg, args) + 1;
	m_message.resize(size);
	vsprintf_s(&m_message[0], size, msg, args);

	va_end(args);
}

Game *Game::s_game = 0;

// TODO: Might want to do some validation check on the name
// and org name so that the pref path won't bug out
Game::Game(const string &name, const string &organization) :
	m_name(name),
	m_organization(organization),
	m_flags(0),
	m_initialized(false),
	m_paused(false),
	m_running(false)
{
	if(s_game)
	{
		THROW("A game already exists!");
	}
	s_game = this;
}

Game::~Game()
{
	// Release managers
	delete m_fileSystem;
	//delete m_audio;
	delete m_timer;
	delete m_console;
	delete m_resourceManager;
	s_game = 0;
}

//------------------------------------------------------------------------
// Run
//------------------------------------------------------------------------
int Game::run()
{
	try
	{
		// Make sure we're not running already
		if(m_running)
		{
			THROW("Game already running");
		}
		m_running = true;

		// TODO: Implement an engine config file
		// (DefaultConfig.ini for instance). It should
		// set the value of CGF_EXPORT_LOG and CGF_VERBOSE, etc.
		//
		// ConfigFile default("config:/DefaultConfig.ini");
		// default.getValue("Window/ResolutionX");
		// etc...

		// Set game root directory
		m_binaryPath = SDL_GetBasePath();

		// Set save directory
		m_prefPath = SDL_GetPrefPath(m_organization.c_str(), m_name.c_str());

		m_console = new Console();
		m_fileSystem = new FileSystem();
		if(isEnabled(CGF_EXPORT_LOG))
		{
			m_console->m_output = new FileWriter(util::getAbsoluteFilePath("bin:/Console.log"));
		}

		m_timer = new Timer();
		//m_audio = new AudioManager();

		m_console->m_engine = this;

		LOG("** Initializing Engine **");

		// Initialize SDL
		if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
		{
			THROW("Unable to initialize SDL");
		}

		// Initialize resource manager
		m_resourceManager = new ResourceManager("Resources.xml");

		// Initialize window
		Window *mainWindow = new Window(m_name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 0);
		m_windows.push_back(mainWindow);
		GraphicsContext *graphicsContext = mainWindow->getGraphicsContext();

		// TODO: Concider moving these to a function of sorts (initGraphics())
		// Initialize GL3W
		if(gl3wInit() != 0)
		{
			THROW("GL3W did not initialize!");
		}

		// Print GPU info
		LOG("** Using GPU: %s (OpenGL %s) **", glGetString(GL_VENDOR), glGetString(GL_VERSION));

		// Check OpenGL 3.1 support
		if(!gl3wIsSupported(3, 1))
		{
			THROW("OpenGL 3.1 not supported\n");
		}

		// Setup default vertex format
		VertexFormat::s_vct.set(VERTEX_POSITION, 2);
		VertexFormat::s_vct.set(VERTEX_COLOR, 4, CGF_UBYTE);
		VertexFormat::s_vct.set(VERTEX_TEX_COORD, 2);

		// Setup viewport
		Vector2I size;
		mainWindow->getSize(&size.x, &size.y);
		graphicsContext->resizeViewport(size.x, size.y);

		// Init graphics
		glGenVertexArrays(1, &GraphicsContext::s_vao);
		glBindVertexArray(GraphicsContext::s_vao);
		glGenBuffers(1, &GraphicsContext::s_vbo);
		glGenBuffers(1, &GraphicsContext::s_ibo);

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

		// Enable blend
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// Enable alpha test // Optimization?
		//glEnable(GL_ALPHA_TEST);
		//glAlphaFunc(GL_LEQUAL, 0.0f);

		glPointSize(4);

		string vertexShader =
			"\n"
			"in vec2 in_Position;\n"
			"in vec2 in_TexCoord;\n"
			"in vec4 in_VertexColor;\n"
			"\n"
			"out vec2 v_TexCoord;\n"
			"out vec4 v_VertexColor;\n"
			"\n"
			"uniform mat4 u_ModelViewProj;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = vec4(in_Position, 0.0, 1.0) * u_ModelViewProj;\n"
			"	v_TexCoord = in_TexCoord;\n"
			"	v_VertexColor = in_VertexColor;\n"
			"}\n";

		string fragmentShader =
			"\n"
			"in vec2 v_TexCoord;\n"
			"in vec4 v_VertexColor;\n"
			"\n"
			"out vec4 out_FragColor;\n"
			"\n"
			"uniform sampler2D u_Texture;"
			"\n"
			"void main()\n"
			"{\n"
			"	out_FragColor = texture(u_Texture, v_TexCoord) * v_VertexColor;\n"
			"}\n";

		GraphicsContext::s_defaultShader = Resource<Shader>(new Shader(vertexShader, fragmentShader));

		uchar pixel[4];
		pixel[0] = pixel[1] = pixel[2] = pixel[3] = 255;
		GraphicsContext::s_defaultTexture = Resource<Texture2D>(new Texture2D(1, 1, pixel));

		// Initialize input handler
		m_inputManager = new InputManager("InputConfig.xml");

		m_scene = new Scene(this);

		SDL_StartTextInput();

		// Engine initialized
		m_initialized = true;

		LOG("** Engine Initialized **");

		// Call onStart event
		{
			GameEvent e(GameEvent::START);
			onEvent(&e);
		}

		// Fps sampling
		const uint numFpsSamples = 8;
		double fpsSamples[numFpsSamples];
		for(uint i = 0; i < numFpsSamples; ++i) fpsSamples[i] = 0.0;
		uint currFpsSample = 0;

		// Setup game loop
		m_timer->start();
		const double dt = 1.0 / 30.0;
		double accumulator = 0.0;
		double prevTime = m_timer->getElapsedTime();

		// Make sure update is called once before draw
		{
			TickEvent e(dt);
			onEvent(&e);
		}

		// Game loop
		while(m_running)
		{
			// Event handling
			SDL_Event event;
			while(SDL_PollEvent(&event))
			{
				switch(event.type)
				{
					case SDL_WINDOWEVENT:
					{
						list<Window*> windows(m_windows);
						for(Window *window : windows)
						{
							if(event.window.windowID == window->getID())
							{
								if(window->handleEvent(event, this))
								{
									// The window was closed. Release its resources.
									m_windows.remove(window);
									delete window;

									// If all windows are closed, end the game.
									if(m_windows.size() == 0)
									{
										end();
										goto gameloopend;
									}
								}
							}
						}
					}
					break;

					case SDL_KEYDOWN:
					{
						if(event.key.repeat == 0)
						{
							KeyEvent e(KeyEvent::DOWN, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
							onEvent(&e);
							m_inputManager->updateKeybinds(&e);
						}
						else
						{
							KeyEvent e(KeyEvent::REPEAT, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
							onEvent(&e);
							m_inputManager->updateKeybinds(&e);
						}
					}
					break;

					case SDL_KEYUP:
					{
						KeyEvent e(KeyEvent::UP, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
						onEvent(&e);
						m_inputManager->updateKeybinds(&e);
					}
					break;

					case SDL_TEXTINPUT:
					{
						if((SDL_GetModState() & (KMOD_CTRL | KMOD_ALT)) == 0)
						{
							TextEvent e(event.text.text[0]);
							onEvent(&e);
						}
					}
					break;

					case SDL_MOUSEMOTION:
					{
						m_inputManager->m_x = event.motion.x;
						m_inputManager->m_y = event.motion.y;
						MouseEvent e(MouseEvent::MOVE, event.motion.x, event.motion.y, CGF_MOUSE_BUTTON_NONE, 0, 0);
						onEvent(&e);
					}
					break;

					case SDL_MOUSEBUTTONDOWN:
					{
						// MouseEvent
						MouseEvent mouseEvent(MouseEvent::DOWN, m_inputManager->m_x, m_inputManager->m_y, (const MouseButton) event.button.button, 0, 0);
						onEvent(&mouseEvent);

						// KeyEvent
						KeyEvent keyEvent(KeyEvent::DOWN, m_inputManager, (const MouseButton) event.button.button, event.key.keysym.mod);
						onEvent(&keyEvent);
						m_inputManager->updateKeybinds(&keyEvent);
					}
					break;

					case SDL_MOUSEBUTTONUP:
					{
						// MouseEvent
						MouseEvent e(MouseEvent::UP, m_inputManager->m_x, m_inputManager->m_y, (const MouseButton) event.button.button, 0, 0);
						onEvent(&e);

						// KeyEvent
						KeyEvent keyEvent(KeyEvent::UP, m_inputManager, (const MouseButton) event.button.button, event.key.keysym.mod);
						onEvent(&keyEvent);
						m_inputManager->updateKeybinds(&keyEvent);
					}
					break;

					case SDL_MOUSEWHEEL:
					{
						// Scroll event
						MouseEvent e(MouseEvent::WHEEL, m_inputManager->m_x, m_inputManager->m_y, CGF_MOUSE_BUTTON_NONE, event.wheel.x, event.wheel.y);
						onEvent(&e);
					}
					break;
				}
			}

			// Check if game is paused or out of focus
			if(m_paused || (!isEnabled(CGF_RUN_IN_BACKGROUND) && !mainWindow->checkFlags(SDL_WINDOW_INPUT_FOCUS)))
			{
				continue;
			}

			// Calculate time delta
			const double currentTime = m_timer->getElapsedTime();
			double deltaTime = currentTime - prevTime;
			prevTime = currentTime;

			// Avoid spiral of death
			if(deltaTime > 0.25)
			{
				deltaTime = 0.25;
			}

			// Step begin
			{
				StepEvent e(StepEvent::BEGIN);
				onEvent(&e);
			}

			// Apply time delta to accumulator
			accumulator += deltaTime;
			while(accumulator >= dt)
			{
				// Update the game
				{
					TickEvent e(dt);
					onEvent(&e);
				}
				accumulator -= dt;
			}

			// Draw the game
			const double alpha = accumulator / dt;
			{
				DrawEvent e(alpha, graphicsContext);
				onEvent(&e);
			}
			SDL_GL_SwapWindow(mainWindow->getSDLHandle());
			glClear(GL_COLOR_BUFFER_BIT);

			// Add fps sample
			if(deltaTime != 0.0f)
			{
				fpsSamples[currFpsSample++] = 1.0 / deltaTime;
				if(currFpsSample >= numFpsSamples)
				{
					currFpsSample = 0;
				}
			}

			// Get average fps
			double fps = 0.0;
			for(uint i = 0; i < numFpsSamples; i++) fps += fpsSamples[i];
			m_framesPerSecond = fps / numFpsSamples;

			// Step end
			{
				StepEvent e(StepEvent::END);
				onEvent(&e);
			}
		}
gameloopend:

		SDL_StopTextInput();

		LOG("** Game Ending **");

		// Call onEnd event
		{
			GameEvent e(GameEvent::END);
			onEvent(&e);
		}
	}
	catch(Exception e)
	{
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "An error occured", e.message().c_str(), m_windows.front()->getSDLHandle());
		LOG("An exception occured: %s", e.message().c_str());
		return e.errorCode();
	}
	catch(...)
	{
		LOG("Unknown exception occured.");
		return CGF_UNKNOWN_EXCEPTION;
	}
	return CGF_OK;
}

void Game::end()
{
	m_running = false;
}

void Game::setPaused(const bool paused)
{
	m_paused = paused;
}

void Game::setFlags(const uint flags)
{
	m_flags = flags;
}

uint Game::getFlags() const
{
	return m_flags;
}

bool Game::isEnabled(const EngineFlag flag)
{
	return (m_flags & flag) != 0;
}

Window *Game::getWindow(const Sint32 id) const
{
	if(id < 0)
	{
		return m_windows.front();
	}
	for(Window *window : m_windows)
	{
		if(window->getID() == id)
		{
			return window;
		}
	}
	return 0;
}

END_CGF_NAMESPACE
<commit_msg>SDL fix<commit_after>//       ____  ____     ____                        _____             _
// __  _|___ \|  _ \   / ___| __ _ _ __ ___   ___  | ____|_ __   __ _(_)_ __   ___
// \ \/ / __) | | | | | |  _ / _  |  _   _ \ / _ \ |  _| |  _ \ / _  | |  _ \ / _ \
//  >  < / __/| |_| | | |_| | (_| | | | | | |  __/ | |___| | | | (_| | | | | |  __/
// /_/\_\_____|____/   \____|\__ _|_| |_| |_|\___| |_____|_| |_|\__, |_|_| |_|\___|
//                                                              |___/
//				Originally written by Marcus Loo Vergara (aka. Bitsauce)
//									2011-2015 (C)

#include <CGF/Common.h>
#include <CGF/Graphics.h>
#include <CGF/Input.h>
#include <CGF/Audio.h>

BEGIN_CGF_NAMESPACE

Exception::Exception(RetCode code, const char * msg, ...) :
	m_errorCode(code)
{
	va_list args;
	va_start(args, msg);

	int size = _scprintf(msg, args) + 1;
	m_message.resize(size);
	vsprintf_s(&m_message[0], size, msg, args);

	va_end(args);
}

Keycode KeyEvent::getKeycode() const
{
	return (Keycode) SDL_GetKeyFromScancode((SDL_Scancode) m_inputButton.getCode());
}

Game *Game::s_game = 0;

// TODO: Might want to do some validation check on the name
// and org name so that the pref path won't bug out
Game::Game(const string &name, const string &organization) :
	m_name(name),
	m_organization(organization),
	m_flags(0),
	m_initialized(false),
	m_paused(false),
	m_running(false)
{
	if(s_game)
	{
		THROW("A game already exists!");
	}
	s_game = this;
}

Game::~Game()
{
	// Release managers
	delete m_fileSystem;
	//delete m_audio;
	delete m_timer;
	delete m_console;
	delete m_resourceManager;
	s_game = 0;
}

//------------------------------------------------------------------------
// Run
//------------------------------------------------------------------------
int Game::run()
{
	try
	{
		// Make sure we're not running already
		if(m_running)
		{
			THROW("Game already running");
		}
		m_running = true;

		// TODO: Implement an engine config file
		// (DefaultConfig.ini for instance). It should
		// set the value of CGF_EXPORT_LOG and CGF_VERBOSE, etc.
		//
		// ConfigFile default("config:/DefaultConfig.ini");
		// default.getValue("Window/ResolutionX");
		// etc...

		// Set game root directory
		m_binaryPath = SDL_GetBasePath();

		// Set save directory
		m_prefPath = SDL_GetPrefPath(m_organization.c_str(), m_name.c_str());

		m_console = new Console();
		m_fileSystem = new FileSystem();
		if(isEnabled(CGF_EXPORT_LOG))
		{
			m_console->m_output = new FileWriter(util::getAbsoluteFilePath("bin:/Console.log"));
		}

		m_timer = new Timer();
		//m_audio = new AudioManager();

		m_console->m_engine = this;

		LOG("** Initializing Engine **");

		// Initialize SDL
		if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
		{
			THROW("Unable to initialize SDL");
		}

		// Initialize resource manager
		m_resourceManager = new ResourceManager("Resources.xml");

		// Initialize window
		Window *mainWindow = new Window(m_name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 0);
		m_windows.push_back(mainWindow);
		GraphicsContext *graphicsContext = mainWindow->getGraphicsContext();

		// TODO: Concider moving these to a function of sorts (initGraphics())
		// Initialize GL3W
		if(gl3wInit() != 0)
		{
			THROW("GL3W did not initialize!");
		}

		// Print GPU info
		LOG("** Using GPU: %s (OpenGL %s) **", glGetString(GL_VENDOR), glGetString(GL_VERSION));

		// Check OpenGL 3.1 support
		if(!gl3wIsSupported(3, 1))
		{
			THROW("OpenGL 3.1 not supported\n");
		}

		// Setup default vertex format
		VertexFormat::s_vct.set(VERTEX_POSITION, 2);
		VertexFormat::s_vct.set(VERTEX_COLOR, 4, CGF_UBYTE);
		VertexFormat::s_vct.set(VERTEX_TEX_COORD, 2);

		// Setup viewport
		Vector2I size;
		mainWindow->getSize(&size.x, &size.y);
		graphicsContext->resizeViewport(size.x, size.y);

		// Init graphics
		glGenVertexArrays(1, &GraphicsContext::s_vao);
		glBindVertexArray(GraphicsContext::s_vao);
		glGenBuffers(1, &GraphicsContext::s_vbo);
		glGenBuffers(1, &GraphicsContext::s_ibo);

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

		// Enable blend
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// Enable alpha test // Optimization?
		//glEnable(GL_ALPHA_TEST);
		//glAlphaFunc(GL_LEQUAL, 0.0f);

		glPointSize(4);

		string vertexShader =
			"\n"
			"in vec2 in_Position;\n"
			"in vec2 in_TexCoord;\n"
			"in vec4 in_VertexColor;\n"
			"\n"
			"out vec2 v_TexCoord;\n"
			"out vec4 v_VertexColor;\n"
			"\n"
			"uniform mat4 u_ModelViewProj;\n"
			"\n"
			"void main()\n"
			"{\n"
			"	gl_Position = vec4(in_Position, 0.0, 1.0) * u_ModelViewProj;\n"
			"	v_TexCoord = in_TexCoord;\n"
			"	v_VertexColor = in_VertexColor;\n"
			"}\n";

		string fragmentShader =
			"\n"
			"in vec2 v_TexCoord;\n"
			"in vec4 v_VertexColor;\n"
			"\n"
			"out vec4 out_FragColor;\n"
			"\n"
			"uniform sampler2D u_Texture;"
			"\n"
			"void main()\n"
			"{\n"
			"	out_FragColor = texture(u_Texture, v_TexCoord) * v_VertexColor;\n"
			"}\n";

		GraphicsContext::s_defaultShader = Resource<Shader>(new Shader(vertexShader, fragmentShader));

		uchar pixel[4];
		pixel[0] = pixel[1] = pixel[2] = pixel[3] = 255;
		GraphicsContext::s_defaultTexture = Resource<Texture2D>(new Texture2D(1, 1, pixel));

		// Initialize input handler
		m_inputManager = new InputManager("InputConfig.xml");

		m_scene = new Scene(this);

		SDL_StartTextInput();

		// Engine initialized
		m_initialized = true;

		LOG("** Engine Initialized **");

		// Call onStart event
		{
			GameEvent e(GameEvent::START);
			onEvent(&e);
		}

		// Fps sampling
		const uint numFpsSamples = 8;
		double fpsSamples[numFpsSamples];
		for(uint i = 0; i < numFpsSamples; ++i) fpsSamples[i] = 0.0;
		uint currFpsSample = 0;

		// Setup game loop
		m_timer->start();
		const double dt = 1.0 / 30.0;
		double accumulator = 0.0;
		double prevTime = m_timer->getElapsedTime();

		// Make sure update is called once before draw
		{
			TickEvent e(dt);
			onEvent(&e);
		}

		// Game loop
		while(m_running)
		{
			// Event handling
			SDL_Event event;
			while(SDL_PollEvent(&event))
			{
				switch(event.type)
				{
					case SDL_WINDOWEVENT:
					{
						list<Window*> windows(m_windows);
						for(Window *window : windows)
						{
							if(event.window.windowID == window->getID())
							{
								if(window->handleEvent(event, this))
								{
									// The window was closed. Release its resources.
									m_windows.remove(window);
									delete window;

									// If all windows are closed, end the game.
									if(m_windows.size() == 0)
									{
										end();
										goto gameloopend;
									}
								}
							}
						}
					}
					break;

					case SDL_KEYDOWN:
					{
						if(event.key.repeat == 0)
						{
							KeyEvent e(KeyEvent::DOWN, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
							onEvent(&e);
							m_inputManager->updateKeybinds(&e);
						}
						else
						{
							KeyEvent e(KeyEvent::REPEAT, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
							onEvent(&e);
							m_inputManager->updateKeybinds(&e);
						}
					}
					break;

					case SDL_KEYUP:
					{
						KeyEvent e(KeyEvent::UP, m_inputManager, (Scancode) event.key.keysym.scancode, event.key.keysym.mod);
						onEvent(&e);
						m_inputManager->updateKeybinds(&e);
					}
					break;

					case SDL_TEXTINPUT:
					{
						if((SDL_GetModState() & (KMOD_CTRL | KMOD_ALT)) == 0)
						{
							TextEvent e(event.text.text[0]);
							onEvent(&e);
						}
					}
					break;

					case SDL_MOUSEMOTION:
					{
						m_inputManager->m_x = event.motion.x;
						m_inputManager->m_y = event.motion.y;
						MouseEvent e(MouseEvent::MOVE, event.motion.x, event.motion.y, CGF_MOUSE_BUTTON_NONE, 0, 0);
						onEvent(&e);
					}
					break;

					case SDL_MOUSEBUTTONDOWN:
					{
						// MouseEvent
						MouseEvent mouseEvent(MouseEvent::DOWN, m_inputManager->m_x, m_inputManager->m_y, (const MouseButton) event.button.button, 0, 0);
						onEvent(&mouseEvent);

						// KeyEvent
						KeyEvent keyEvent(KeyEvent::DOWN, m_inputManager, (const MouseButton) event.button.button, event.key.keysym.mod);
						onEvent(&keyEvent);
						m_inputManager->updateKeybinds(&keyEvent);
					}
					break;

					case SDL_MOUSEBUTTONUP:
					{
						// MouseEvent
						MouseEvent e(MouseEvent::UP, m_inputManager->m_x, m_inputManager->m_y, (const MouseButton) event.button.button, 0, 0);
						onEvent(&e);

						// KeyEvent
						KeyEvent keyEvent(KeyEvent::UP, m_inputManager, (const MouseButton) event.button.button, event.key.keysym.mod);
						onEvent(&keyEvent);
						m_inputManager->updateKeybinds(&keyEvent);
					}
					break;

					case SDL_MOUSEWHEEL:
					{
						// Scroll event
						MouseEvent e(MouseEvent::WHEEL, m_inputManager->m_x, m_inputManager->m_y, CGF_MOUSE_BUTTON_NONE, event.wheel.x, event.wheel.y);
						onEvent(&e);
					}
					break;
				}
			}

			// Check if game is paused or out of focus
			if(m_paused || (!isEnabled(CGF_RUN_IN_BACKGROUND) && !mainWindow->checkFlags(SDL_WINDOW_INPUT_FOCUS)))
			{
				continue;
			}

			// Calculate time delta
			const double currentTime = m_timer->getElapsedTime();
			double deltaTime = currentTime - prevTime;
			prevTime = currentTime;

			// Avoid spiral of death
			if(deltaTime > 0.25)
			{
				deltaTime = 0.25;
			}

			// Step begin
			{
				StepEvent e(StepEvent::BEGIN);
				onEvent(&e);
			}

			// Apply time delta to accumulator
			accumulator += deltaTime;
			while(accumulator >= dt)
			{
				// Update the game
				{
					TickEvent e(dt);
					onEvent(&e);
				}
				accumulator -= dt;
			}

			// Draw the game
			const double alpha = accumulator / dt;
			{
				DrawEvent e(alpha, graphicsContext);
				onEvent(&e);
			}
			SDL_GL_SwapWindow(mainWindow->getSDLHandle());
			glClear(GL_COLOR_BUFFER_BIT);

			// Add fps sample
			if(deltaTime != 0.0f)
			{
				fpsSamples[currFpsSample++] = 1.0 / deltaTime;
				if(currFpsSample >= numFpsSamples)
				{
					currFpsSample = 0;
				}
			}

			// Get average fps
			double fps = 0.0;
			for(uint i = 0; i < numFpsSamples; i++) fps += fpsSamples[i];
			m_framesPerSecond = fps / numFpsSamples;

			// Step end
			{
				StepEvent e(StepEvent::END);
				onEvent(&e);
			}
		}
gameloopend:

		SDL_StopTextInput();

		LOG("** Game Ending **");

		// Call onEnd event
		{
			GameEvent e(GameEvent::END);
			onEvent(&e);
		}
	}
	catch(Exception e)
	{
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "An error occured", e.message().c_str(), m_windows.front()->getSDLHandle());
		LOG("An exception occured: %s", e.message().c_str());
		return e.errorCode();
	}
	catch(...)
	{
		LOG("Unknown exception occured.");
		return CGF_UNKNOWN_EXCEPTION;
	}
	return CGF_OK;
}

void Game::end()
{
	m_running = false;
}

void Game::setPaused(const bool paused)
{
	m_paused = paused;
}

void Game::setFlags(const uint flags)
{
	m_flags = flags;
}

uint Game::getFlags() const
{
	return m_flags;
}

bool Game::isEnabled(const EngineFlag flag)
{
	return (m_flags & flag) != 0;
}

Window *Game::getWindow(const Sint32 id) const
{
	if(id < 0)
	{
		return m_windows.front();
	}
	for(Window *window : m_windows)
	{
		if(window->getID() == id)
		{
			return window;
		}
	}
	return 0;
}

END_CGF_NAMESPACE
<|endoftext|>


<commit_before>//time01.cpp
#include <iostream>
#include "time00.h"

using namespace std;

int main()
{
	int h = 0, m = 0, s = 0;
	cout<<"Please enter the time as hh:mm:ss."<<endl;
	cout<<"Hours:"<<endl;
	cin>>h;
	cout<<"Minutes:"<<endl;
	cin>>m;
	cout<<"Seconds:"<<endl;
	cin>>s;
	Time t1(h, m, s);
	t1.display();
	cout<<"First time object created successfully. Please enter the second set of details."<<endl;
	cout<<"Hours:"<<endl;
	cin>>h;
	cout<<"Minutes:"<<endl;
	cin>>m;
	cout<<"Seconds:"<<endl;
	cin>>s;
	Time t2(h, m, s);
	t2.display();
	Time result = t1 + t2;
	cout<<"Total time:"<<endl;
	result.display();
	return 0;
}<commit_msg>Update<commit_after>//time01.cpp ---- The following code creates three objects of class Time and adds them using operator overloading
#include <iostream>
#include "time00.h"

using namespace std;

int main()
{
	int h = 0, m = 0, s = 0;
	cout<<"Please enter the time as hh:mm:ss."<<endl;
	cout<<"Hours:"<<endl;
	cin>>h;
	cout<<"Minutes:"<<endl;
	cin>>m;
	cout<<"Seconds:"<<endl;
	cin>>s;
	Time t1(h, m, s);
	t1.display();
	cout<<"First time object created successfully. Please enter the second set of details."<<endl;
	cout<<"Hours:"<<endl;
	cin>>h;
	cout<<"Minutes:"<<endl;
	cin>>m;
	cout<<"Seconds:"<<endl;
	cin>>s;
	Time t2(h, m, s);
	t2.display();
	cout<<"Second time object created successfully. Please enter the third and final set of details."<<endl;
	cout<<"Hours:"<<endl;
	cin>>h;
	cout<<"Minutes:"<<endl;
	cin>>m;
	cout<<"Seconds:"<<endl;
	cin>>s;
	Time t3(h, m, s);
	t3.display();
	Time result = t1 + t2 + t3;
	cout<<"Total time:"<<endl;
	result.display();
	return 0;
}<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

int main (int argc, char** argv) {

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 while (keepGoing) {

  image = cvQueryFrame(capture);
  imshow("webcam", image);

// thresholds on dark regions
  Mat black, blurred;
  Mat channel[3];
  split(image, channel);
  equalizeHist(channel[0], channel[0]);
  equalizeHist(channel[1], channel[1]);
  equalizeHist(channel[2], channel[2]);
  merge(channel, 3, black);
  blur(black, blurred, Size(width/4.5,height/9));
  split(blurred, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
  equalizeHist(black, black);
  bitwise_not(black,black);
  imshow("black", black);

  threshold(black, black, 40, 1, THRESH_BINARY_INV);
  split(image, channel);
  channel[0] = channel[0].mul(black);
  channel[1] = channel[1].mul(black);
  channel[2] = channel[2].mul(black);
  merge(channel, 3, image);
  //image = (image)/(255*255);
  imshow("yox", image);

//do some weird morphological closing thing
//  Mat channel[3];
  blur(image, image, Size(width/20, height/20));
  split(image, channel);
  image = (channel[0] + channel[1] + channel[2])/3.0;

  Mat smooth;
  Mat closed;
  Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
  morphologyEx(image, closed, MORPH_CLOSE, kernel);
  divide(image, closed, closed, 1, CV_32F);
  normalize(closed, image, 0, 255, NORM_MINMAX, CV_8U);
  threshold(image, image, -1, 255, THRESH_BINARY_INV + THRESH_OTSU);
  imshow("yo", image);

/*
  Mat canny;
  Canny(image, canny, 0, 50);
  imshow("canny", canny);
*/

/*
  Mat fill = image.clone();
  Point seed(rand()%width, rand()%height);
  floodFill(fill, seed, Scalar(200,0,0), 0, Scalar(0,0,0), Scalar(25,25,25));
  imshow("fill", fill);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

int main (int argc, char** argv) {

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 while (keepGoing) {

  image = cvQueryFrame(capture);
  imshow("webcam", image);

// thresholds on dark regions
  Mat black, blurred;
  Mat channel[3];
  split(image, channel);
  equalizeHist(channel[0], channel[0]);
  equalizeHist(channel[1], channel[1]);
  equalizeHist(channel[2], channel[2]);
  merge(channel, 3, black);
  blur(black, blurred, Size(width/4.5,height/9));
  split(blurred, channel);
  black = (channel[0] + channel[1] + channel[2])/3.0;
  equalizeHist(black, black);
  bitwise_not(black,black);
  imshow("black", black);

  threshold(black, black, 100, 1, THRESH_BINARY_INV);
  split(image, channel);
  channel[0] = channel[0].mul(black);
  channel[1] = channel[1].mul(black);
  channel[2] = channel[2].mul(black);
  merge(channel, 3, image);
  //image = (image)/(255*255);
  imshow("yox", image);

//do some weird morphological closing thing
//  Mat channel[3];
  blur(image, image, Size(width/20, height/20));
  split(image, channel);
  image = (channel[0] + channel[1] + channel[2])/3.0;

  Mat smooth;
  Mat closed;
  Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
  morphologyEx(image, closed, MORPH_CLOSE, kernel);
  divide(image, closed, closed, 1, CV_32F);
  normalize(closed, image, 0, 255, NORM_MINMAX, CV_8U);
  threshold(image, image, -1, 255, THRESH_BINARY_INV + THRESH_OTSU);
  imshow("yo", image);

/*
  Mat canny;
  Canny(image, canny, 0, 50);
  imshow("canny", canny);
*/

/*
  Mat fill = image.clone();
  Point seed(rand()%width, rand()%height);
  floodFill(fill, seed, Scalar(200,0,0), 0, Scalar(0,0,0), Scalar(25,25,25));
  imshow("fill", fill);
*/

  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>