<commit_before>/*!
    \file thread.cpp
    \brief Thread abstraction implementation
    \author Ivan Shynkarenka
    \date 27.01.2016
    \copyright MIT License
*/

#include "threads/thread.h"

#include "errors/exceptions.h"
#include "time/timestamp.h"

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef Yield
#define STATUS_SUCCESS 0x00000000
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <errno.h>
#include <pthread.h>
#include <time.h>
#endif

namespace CppCommon {

//! @cond
namespace Internals {

#if defined(_WIN32) || defined(_WIN64)
// Helper function to set minimum resolution of the Windows Timer
uint64_t SetMinimumTimerResolution()
{
    static NTSTATUS(__stdcall *NtQueryTimerResolution)(OUT PULONG MinimumResolution, OUT PULONG MaximumResolution, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(PULONG, PULONG, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryTimerResolution");
    static NTSTATUS(__stdcall *NtSetTimerResolution)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetTimerResolution");

    if ((NtQueryTimerResolution == nullptr) || (NtSetTimerResolution == nullptr))
        return 0;

    ULONG MinimumResolution, MaximumResolution, ActualResolution;
    NTSTATUS ns = NtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution);
    if (ns == STATUS_SUCCESS)
    {
        ns = NtSetTimerResolution(min(MinimumResolution, MaximumResolution), TRUE, &ActualResolution);
        if (ns == STATUS_SUCCESS)
            return (ActualResolution * 100);
    }
    return 1000000;
}
#endif

} // namespace Internals
//! @endcond

uint64_t Thread::CurrentThreadId() noexcept
{
#if defined(_WIN32) || defined(_WIN64)
    return GetCurrentThreadId();
#elif defined(unix) || defined(__unix) || defined(__unix__)
    return pthread_self();
#endif
}

void Thread::SleepFor(const Timespan& timespan) noexcept
{
    if (timespan < 0)
        return;
    if (timespan == 0)
        return Yield();
#if defined(_WIN32) || defined(_WIN64)
    static NTSTATUS(__stdcall *NtDelayExecution)(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(BOOLEAN, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");

    // Update once and get Windows Timer resolution
    static int64_t resolution = Internals::SetMinimumTimerResolution();

    int64_t sleep = timespan.nanoseconds();
    int64_t yield = timespan.nanoseconds() % resolution;

    // Yield to other thread for a short time
    if (yield > 0)
    {
        int64_t current = Timestamp::nano();
        do
        {
          SwitchToThread();
          int64_t temp = Timestamp::nano() - current;
          sleep -= temp;
          yield -= temp;
        } while (yield > 0);
    }

    // Sleep if we have enough time
    if (sleep > 0)
    {
        if (NtDelayExecution != nullptr)
        {
            // Sleep with microsecond precision
            LARGE_INTEGER interval;
            interval.QuadPart = -sleep / 100;
            NtDelayExecution(FALSE, &interval);
        }
        else
        {
            // Sleep with millisecond precision
            Sleep(sleep / 1000000);
        }
    }
#elif defined(unix) || defined(__unix) || defined(__unix__)
    struct timespec req, rem;
    req.tv_sec = timespan.seconds();
    req.tv_nsec = timespan.nanoseconds() % 1000000000;

    // Call nanosleep() in loop until we have remaining time to sleep
    while (nanosleep(&req, &rem) == -1)
    {
        if (errno == EINTR)
            req = rem;
        else
            break;
    }
#endif
}

void Thread::Yield() noexcept
{
#if defined(_WIN32) || defined(_WIN64)
    SwitchToThread();
#elif defined(unix) || defined(__unix) || defined(__unix__)
    pthread_yield();
#endif
}

ThreadPriority Thread::GetPriority()
{
#if defined(_WIN32) || defined(_WIN64)
    HANDLE hThread = GetCurrentThread();
    int priority = GetThreadPriority(hThread);
    if (priority == THREAD_PRIORITY_ERROR_RETURN)
        throwex SystemException("Failed to get the current thread priority!");
    if (priority < THREAD_PRIORITY_LOWEST)
        return ThreadPriority::IDLE;
    else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
        return ThreadPriority::LOWEST;
    else if (priority < THREAD_PRIORITY_NORMAL)
        return ThreadPriority::LOW;
    else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
        return ThreadPriority::NORMAL;
    else if (priority < THREAD_PRIORITY_HIGHEST)
        return ThreadPriority::HIGH;
    else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
        return ThreadPriority::HIGHEST;
    else
        return ThreadPriority::REALTIME;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy;
    struct sched_param sched;
    int result = pthread_getschedparam(pthread_self(), &policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to get the current thread priority!");
    if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
    {
        if (sched.sched_priority < 15)
            return ThreadPriority::IDLE;
        else if (sched.sched_priority < 30)
            return ThreadPriority::LOWEST;
        else if (sched.sched_priority < 50)
            return ThreadPriority::LOW;
        else if (sched.sched_priority < 70)
            return ThreadPriority::NORMAL;
        else if (sched.sched_priority < 85)
            return ThreadPriority::HIGH;
        else if (sched.sched_priority < 99)
            return ThreadPriority::HIGHEST;
        else
            return ThreadPriority::REALTIME;
    }
    else
        return ThreadPriority::NORMAL;
#endif
}

ThreadPriority Thread::GetPriority(std::thread& thread)
{
#if defined(_WIN32) || defined(_WIN64)
    HANDLE hThread = thread.native_handle();
    int priority = GetThreadPriority(hThread);
    if (priority == THREAD_PRIORITY_ERROR_RETURN)
        throwex SystemException("Failed to get the given thread priority!");
    if (priority < THREAD_PRIORITY_LOWEST)
        return ThreadPriority::IDLE;
    else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
        return ThreadPriority::LOWEST;
    else if (priority < THREAD_PRIORITY_NORMAL)
        return ThreadPriority::LOW;
    else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
        return ThreadPriority::NORMAL;
    else if (priority < THREAD_PRIORITY_HIGHEST)
        return ThreadPriority::HIGH;
    else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
        return ThreadPriority::HIGHEST;
    else
        return ThreadPriority::REALTIME;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy;
    struct sched_param sched;
    int result = pthread_getschedparam(thread.native_handle(), &policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to get the given thread priority!");
    if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
    {
        if (sched.sched_priority < 15)
            return ThreadPriority::IDLE;
        else if (sched.sched_priority < 30)
            return ThreadPriority::LOWEST;
        else if (sched.sched_priority < 50)
            return ThreadPriority::LOW;
        else if (sched.sched_priority < 70)
            return ThreadPriority::NORMAL;
        else if (sched.sched_priority < 85)
            return ThreadPriority::HIGH;
        else if (sched.sched_priority < 99)
            return ThreadPriority::HIGHEST;
        else
            return ThreadPriority::REALTIME;
    }
    else
        return ThreadPriority::NORMAL;
#endif
}

void Thread::SetPriority(ThreadPriority priority)
{
#if defined(_WIN32) || defined(_WIN64)
    int nPriority = THREAD_PRIORITY_NORMAL;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = THREAD_PRIORITY_IDLE;
            break;
        case ThreadPriority::LOWEST:
            nPriority = THREAD_PRIORITY_LOWEST;
            break;
        case ThreadPriority::LOW:
            nPriority = THREAD_PRIORITY_BELOW_NORMAL;
            break;
        case ThreadPriority::NORMAL:
            nPriority = THREAD_PRIORITY_NORMAL;
            break;
        case ThreadPriority::HIGH:
            nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = THREAD_PRIORITY_HIGHEST;
            break;
        case ThreadPriority::REALTIME:
            nPriority = THREAD_PRIORITY_TIME_CRITICAL;
            break;
    }

    HANDLE hThread = GetCurrentThread();
    if (!SetThreadPriority(hThread, nPriority))
        throwex SystemException("Failed to set the current thread priority!");
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy = SCHED_RR;
    struct sched_param sched;
    sched.sched_priority = 50;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = 1;
            break;
        case ThreadPriority::LOWEST:
            nPriority = 15;
            break;
        case ThreadPriority::LOW:
            nPriority = 30;
            break;
        case ThreadPriority::NORMAL:
            nPriority = 50;
            break;
        case ThreadPriority::HIGH:
            nPriority = 70;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = 85;
            break;
        case ThreadPriority::REALTIME:
            nPriority = 99;
            break;
    }

    int result = pthread_setschedparam(pthread_self(), policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to set the current thread priority!");
#endif
}

void Thread::SetPriority(std::thread& thread, ThreadPriority priority)
{
#if defined(_WIN32) || defined(_WIN64)
    int nPriority = THREAD_PRIORITY_NORMAL;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = THREAD_PRIORITY_IDLE;
            break;
        case ThreadPriority::LOWEST:
            nPriority = THREAD_PRIORITY_LOWEST;
            break;
        case ThreadPriority::LOW:
            nPriority = THREAD_PRIORITY_BELOW_NORMAL;
            break;
        case ThreadPriority::NORMAL:
            nPriority = THREAD_PRIORITY_NORMAL;
            break;
        case ThreadPriority::HIGH:
            nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = THREAD_PRIORITY_HIGHEST;
            break;
        case ThreadPriority::REALTIME:
            nPriority = THREAD_PRIORITY_TIME_CRITICAL;
            break;
    }

    HANDLE hThread = thread.native_handle();
    if (!SetThreadPriority(hThread, nPriority))
        throwex SystemException("Failed to set the given thread priority!");
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy = SCHED_RR;
    struct sched_param sched;
    sched.sched_priority = 50;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = 1;
            break;
        case ThreadPriority::LOWEST:
            nPriority = 15;
            break;
        case ThreadPriority::LOW:
            nPriority = 30;
            break;
        case ThreadPriority::NORMAL:
            nPriority = 50;
            break;
        case ThreadPriority::HIGH:
            nPriority = 70;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = 85;
            break;
        case ThreadPriority::REALTIME:
            nPriority = 99;
            break;
    }

    int result = pthread_setschedparam(thread.native_handle(), policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to set the given thread priority!");
#endif
}

} // namespace CppCommon
<commit_msg>Bugfixing<commit_after>/*!
    \file thread.cpp
    \brief Thread abstraction implementation
    \author Ivan Shynkarenka
    \date 27.01.2016
    \copyright MIT License
*/

#include "threads/thread.h"

#include "errors/exceptions.h"
#include "time/timestamp.h"

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef Yield
#define STATUS_SUCCESS 0x00000000
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <errno.h>
#include <pthread.h>
#include <time.h>
#endif

namespace CppCommon {

//! @cond
namespace Internals {

#if defined(_WIN32) || defined(_WIN64)
// Helper function to set minimum resolution of the Windows Timer
uint64_t SetMinimumTimerResolution()
{
    static NTSTATUS(__stdcall *NtQueryTimerResolution)(OUT PULONG MinimumResolution, OUT PULONG MaximumResolution, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(PULONG, PULONG, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryTimerResolution");
    static NTSTATUS(__stdcall *NtSetTimerResolution)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetTimerResolution");

    if ((NtQueryTimerResolution == nullptr) || (NtSetTimerResolution == nullptr))
        return 0;

    ULONG MinimumResolution, MaximumResolution, ActualResolution;
    NTSTATUS ns = NtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution);
    if (ns == STATUS_SUCCESS)
    {
        ns = NtSetTimerResolution(min(MinimumResolution, MaximumResolution), TRUE, &ActualResolution);
        if (ns == STATUS_SUCCESS)
            return (ActualResolution * 100);
    }
    return 1000000;
}
#endif

} // namespace Internals
//! @endcond

uint64_t Thread::CurrentThreadId() noexcept
{
#if defined(_WIN32) || defined(_WIN64)
    return GetCurrentThreadId();
#elif defined(unix) || defined(__unix) || defined(__unix__)
    return pthread_self();
#endif
}

void Thread::SleepFor(const Timespan& timespan) noexcept
{
    if (timespan < 0)
        return;
    if (timespan == 0)
        return Yield();
#if defined(_WIN32) || defined(_WIN64)
    static NTSTATUS(__stdcall *NtDelayExecution)(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(BOOLEAN, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");

    // Update once and get Windows Timer resolution
    static int64_t resolution = Internals::SetMinimumTimerResolution();

    int64_t sleep = timespan.nanoseconds();
    int64_t yield = timespan.nanoseconds() % resolution;

    // Yield to other thread for a short time
    if (yield > 0)
    {
        int64_t current = Timestamp::nano();
        do
        {
          SwitchToThread();
          int64_t temp = Timestamp::nano() - current;
          sleep -= temp;
          yield -= temp;
        } while (yield > 0);
    }

    // Sleep if we have enough time
    if (sleep > 0)
    {
        if (NtDelayExecution != nullptr)
        {
            // Sleep with microsecond precision
            LARGE_INTEGER interval;
            interval.QuadPart = -sleep / 100;
            NtDelayExecution(FALSE, &interval);
        }
        else
        {
            // Sleep with millisecond precision
            Sleep(sleep / 1000000);
        }
    }
#elif defined(unix) || defined(__unix) || defined(__unix__)
    struct timespec req, rem;
    req.tv_sec = timespan.seconds();
    req.tv_nsec = timespan.nanoseconds() % 1000000000;

    // Call nanosleep() in loop until we have remaining time to sleep
    while (nanosleep(&req, &rem) == -1)
    {
        if (errno == EINTR)
            req = rem;
        else
            break;
    }
#endif
}

void Thread::Yield() noexcept
{
#if defined(_WIN32) || defined(_WIN64)
    SwitchToThread();
#elif defined(unix) || defined(__unix) || defined(__unix__)
    pthread_yield();
#endif
}

ThreadPriority Thread::GetPriority()
{
#if defined(_WIN32) || defined(_WIN64)
    HANDLE hThread = GetCurrentThread();
    int priority = GetThreadPriority(hThread);
    if (priority == THREAD_PRIORITY_ERROR_RETURN)
        throwex SystemException("Failed to get the current thread priority!");
    if (priority < THREAD_PRIORITY_LOWEST)
        return ThreadPriority::IDLE;
    else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
        return ThreadPriority::LOWEST;
    else if (priority < THREAD_PRIORITY_NORMAL)
        return ThreadPriority::LOW;
    else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
        return ThreadPriority::NORMAL;
    else if (priority < THREAD_PRIORITY_HIGHEST)
        return ThreadPriority::HIGH;
    else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
        return ThreadPriority::HIGHEST;
    else
        return ThreadPriority::REALTIME;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy;
    struct sched_param sched;
    int result = pthread_getschedparam(pthread_self(), &policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to get the current thread priority!");
    if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
    {
        if (sched.sched_priority < 15)
            return ThreadPriority::IDLE;
        else if (sched.sched_priority < 30)
            return ThreadPriority::LOWEST;
        else if (sched.sched_priority < 50)
            return ThreadPriority::LOW;
        else if (sched.sched_priority < 70)
            return ThreadPriority::NORMAL;
        else if (sched.sched_priority < 85)
            return ThreadPriority::HIGH;
        else if (sched.sched_priority < 99)
            return ThreadPriority::HIGHEST;
        else
            return ThreadPriority::REALTIME;
    }
    else
        return ThreadPriority::NORMAL;
#endif
}

ThreadPriority Thread::GetPriority(std::thread& thread)
{
#if defined(_WIN32) || defined(_WIN64)
    HANDLE hThread = thread.native_handle();
    int priority = GetThreadPriority(hThread);
    if (priority == THREAD_PRIORITY_ERROR_RETURN)
        throwex SystemException("Failed to get the given thread priority!");
    if (priority < THREAD_PRIORITY_LOWEST)
        return ThreadPriority::IDLE;
    else if (priority < THREAD_PRIORITY_BELOW_NORMAL)
        return ThreadPriority::LOWEST;
    else if (priority < THREAD_PRIORITY_NORMAL)
        return ThreadPriority::LOW;
    else if (priority < THREAD_PRIORITY_ABOVE_NORMAL)
        return ThreadPriority::NORMAL;
    else if (priority < THREAD_PRIORITY_HIGHEST)
        return ThreadPriority::HIGH;
    else if (priority < THREAD_PRIORITY_TIME_CRITICAL)
        return ThreadPriority::HIGHEST;
    else
        return ThreadPriority::REALTIME;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy;
    struct sched_param sched;
    int result = pthread_getschedparam(thread.native_handle(), &policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to get the given thread priority!");
    if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
    {
        if (sched.sched_priority < 15)
            return ThreadPriority::IDLE;
        else if (sched.sched_priority < 30)
            return ThreadPriority::LOWEST;
        else if (sched.sched_priority < 50)
            return ThreadPriority::LOW;
        else if (sched.sched_priority < 70)
            return ThreadPriority::NORMAL;
        else if (sched.sched_priority < 85)
            return ThreadPriority::HIGH;
        else if (sched.sched_priority < 99)
            return ThreadPriority::HIGHEST;
        else
            return ThreadPriority::REALTIME;
    }
    else
        return ThreadPriority::NORMAL;
#endif
}

void Thread::SetPriority(ThreadPriority priority)
{
#if defined(_WIN32) || defined(_WIN64)
    int nPriority = THREAD_PRIORITY_NORMAL;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = THREAD_PRIORITY_IDLE;
            break;
        case ThreadPriority::LOWEST:
            nPriority = THREAD_PRIORITY_LOWEST;
            break;
        case ThreadPriority::LOW:
            nPriority = THREAD_PRIORITY_BELOW_NORMAL;
            break;
        case ThreadPriority::NORMAL:
            nPriority = THREAD_PRIORITY_NORMAL;
            break;
        case ThreadPriority::HIGH:
            nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = THREAD_PRIORITY_HIGHEST;
            break;
        case ThreadPriority::REALTIME:
            nPriority = THREAD_PRIORITY_TIME_CRITICAL;
            break;
    }

    HANDLE hThread = GetCurrentThread();
    if (!SetThreadPriority(hThread, nPriority))
        throwex SystemException("Failed to set the current thread priority!");
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy = SCHED_RR;
    struct sched_param sched;
    sched.sched_priority = 50;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            sched.sched_priority = 1;
            break;
        case ThreadPriority::LOWEST:
            sched.sched_priority = 15;
            break;
        case ThreadPriority::LOW:
            sched.sched_priority = 30;
            break;
        case ThreadPriority::NORMAL:
            sched.sched_priority = 50;
            break;
        case ThreadPriority::HIGH:
            sched.sched_priority = 70;
            break;
        case ThreadPriority::HIGHEST:
            sched.sched_priority = 85;
            break;
        case ThreadPriority::REALTIME:
            sched.sched_priority = 99;
            break;
    }

    int result = pthread_setschedparam(pthread_self(), policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to set the current thread priority!");
#endif
}

void Thread::SetPriority(std::thread& thread, ThreadPriority priority)
{
#if defined(_WIN32) || defined(_WIN64)
    int nPriority = THREAD_PRIORITY_NORMAL;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            nPriority = THREAD_PRIORITY_IDLE;
            break;
        case ThreadPriority::LOWEST:
            nPriority = THREAD_PRIORITY_LOWEST;
            break;
        case ThreadPriority::LOW:
            nPriority = THREAD_PRIORITY_BELOW_NORMAL;
            break;
        case ThreadPriority::NORMAL:
            nPriority = THREAD_PRIORITY_NORMAL;
            break;
        case ThreadPriority::HIGH:
            nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
            break;
        case ThreadPriority::HIGHEST:
            nPriority = THREAD_PRIORITY_HIGHEST;
            break;
        case ThreadPriority::REALTIME:
            nPriority = THREAD_PRIORITY_TIME_CRITICAL;
            break;
    }

    HANDLE hThread = thread.native_handle();
    if (!SetThreadPriority(hThread, nPriority))
        throwex SystemException("Failed to set the given thread priority!");
#elif defined(unix) || defined(__unix) || defined(__unix__)
    int policy = SCHED_RR;
    struct sched_param sched;
    sched.sched_priority = 50;
    switch (priority)
    {
        case ThreadPriority::IDLE:
            sched.sched_priority = 1;
            break;
        case ThreadPriority::LOWEST:
            sched.sched_priority = 15;
            break;
        case ThreadPriority::LOW:
            sched.sched_priority = 30;
            break;
        case ThreadPriority::NORMAL:
            sched.sched_priority = 50;
            break;
        case ThreadPriority::HIGH:
            sched.sched_priority = 70;
            break;
        case ThreadPriority::HIGHEST:
            sched.sched_priority = 85;
            break;
        case ThreadPriority::REALTIME:
            sched.sched_priority = 99;
            break;
    }

    int result = pthread_setschedparam(thread.native_handle(), policy, &sched);
    if (result != 0)
        throwex SystemException("Failed to set the given thread priority!");
#endif
}

} // namespace CppCommon
<|endoftext|>


<commit_before>#include "fenceview.h"
// OSG
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Vec4>
#include <osg/PositionAttitudeTransform>
#include <osg/ref_ptr>
// troen
#include "../constants.h"
#include "shaders.h"
#include "../model/fencemodel.h"
#include "../controller/fencecontroller.h"

using namespace troen;

FenceView::FenceView(FenceController* fenceController, osg::Vec3 color, std::shared_ptr<AbstractModel>& model) :
AbstractView(),
m_model(std::static_pointer_cast<FenceModel>(model)),
m_playerColor(color),
m_fenceController(fenceController)
{
	initializeFence();
	initializeShader();
}

void FenceView::initializeFence()
{
	m_fenceHeight = FENCE_HEIGHT_VIEW;

	m_coordinates = new osg::Vec3Array();
	m_coordinates->setDataVariance(osg::Object::DYNAMIC);

	m_relativeHeights = new osg::FloatArray();
	m_relativeHeights->setDataVariance(osg::Object::DYNAMIC);

	// this value could need adaption; will avoid time-intensive array resizing
	m_coordinates->reserveArray(10000);
	m_relativeHeights->reserveArray(10000);

	m_geometry = new osg::Geometry();
	m_geometry->setVertexArray(m_coordinates);

	// set the relative height between 0 and 1 as an additional vertex attribute
	m_geometry->setVertexAttribArray(5, m_relativeHeights);
	m_geometry->setVertexAttribBinding(5, osg::Geometry::BIND_PER_VERTEX);

	// seems to be important so that we won't crash after 683 fence parts
	m_geometry->setUseDisplayList(false);

	// use the shared normal array.
	// polyGeom->setNormalArray(shared_normals.get(), osg::Array::BIND_OVERALL);

	m_drawArrays = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP, 0, 0);
	m_geometry->addPrimitiveSet(m_drawArrays);

	m_geode = new osg::Geode();
	m_geode->addDrawable(m_geometry);

	m_node->addChild(m_geode);
	m_node->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
	m_node->setName("fenceGroup");

	m_radarElementsGroup = new osg::Group();
	m_radarElementsGroup->setNodeMask(CAMERA_MASK_NONE);
	m_node->addChild(m_radarElementsGroup);
}

void FenceView::updateFadeOutFactor(float fadeOutFactor)
{
	m_fadeOutFactorUniform->set(fadeOutFactor);
}

void FenceView::updateFenceGap(osg::Vec3 lastPosition, osg::Vec3 position)
{
	if (m_coordinates->size() > 1) {
		m_coordinates->at(m_coordinates->size() - 2) = osg::Vec3(position.x(), position.y(), position.z());
		m_coordinates->at(m_coordinates->size() - 1) = osg::Vec3(position.x(), position.y(), position.z() + m_fenceHeight);
		m_relativeHeights->at(m_relativeHeights->size() - 2) = 0.f;
		m_relativeHeights->at(m_relativeHeights->size() - 1) = 1.f;
	}
}

void FenceView::initializeShader()
{
	osg::ref_ptr<osg::StateSet> NodeState = m_node->getOrCreateStateSet();

	osg::Uniform* fenceColorU = new osg::Uniform("fenceColor", m_playerColor);
	NodeState->addUniform(fenceColorU);

	osg::Uniform* modelIDU = new osg::Uniform("modelID", GLOW);
	NodeState->addUniform(modelIDU);

	m_fadeOutFactorUniform = new osg::Uniform("fadeOutFactor", 1.f);
	NodeState->addUniform(m_fadeOutFactorUniform);

	NodeState->setMode(GL_BLEND, osg::StateAttribute::ON);
	NodeState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
	NodeState->setAttributeAndModes(shaders::m_allShaderPrograms[shaders::FENCE], osg::StateAttribute::ON);

	shaders::m_allShaderPrograms[shaders::FENCE]->addBindAttribLocation("a_relHeight", 5);
}

void FenceView::addFencePart(osg::Vec3 lastPosition, osg::Vec3 currentPosition)
{

	if (m_coordinates->size() == 0)
	{
		m_coordinates->push_back(lastPosition);
		m_coordinates->push_back(osg::Vec3(lastPosition.x(), lastPosition.y(), lastPosition.z() + m_fenceHeight));
		m_relativeHeights->push_back(0.f);
		m_relativeHeights->push_back(1.f);
	}

	// game fence part
	m_coordinates->push_back(currentPosition);
	m_coordinates->push_back(osg::Vec3(currentPosition.x(), currentPosition.y(), currentPosition.z() + m_fenceHeight));
	m_relativeHeights->push_back(0.f);
	m_relativeHeights->push_back(1.f);

	int currentFenceParts = (m_coordinates->size() - 2) / 2;

	// radar fence part
	if (currentFenceParts % FENCE_TO_MINIMAP_PARTS_RATIO == 0)
	{
		osg::ref_ptr<osg::Box> box
			= new osg::Box(osg::Vec3(0, 0, 0), 60, 60, 60);
		osg::ref_ptr<osg::ShapeDrawable> mark_shape = new osg::ShapeDrawable(box);
		mark_shape->setColor(osg::Vec4f(m_playerColor, 1));
		osg::ref_ptr<osg::Geode> mark_node = new osg::Geode;
		mark_node->addDrawable(mark_shape.get());
		//mark_node->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

		// place objects in world space
		osg::Matrixd initialTransform;
		//initialTransform.makeRotate(rotationQuatXY);
		initialTransform *= initialTransform.translate((currentPosition + lastPosition) / 2);

		osg::ref_ptr<osg::MatrixTransform> matrixTransformRadar = new osg::MatrixTransform(initialTransform);
		matrixTransformRadar->addChild(mark_node);

		m_radarElementsGroup->addChild(matrixTransformRadar);
		m_radarFenceBoxes.push_back(matrixTransformRadar);
	}

	// limit
	enforceFencePartsLimit();

	// TODO
	// remove if no disadvantages seem necessary?
	// m_geometry->dirtyBound();
	m_drawArrays->setCount(m_coordinates->size());
}

void FenceView::removeAllFences()
{
	m_node->removeChild(m_geode);
	for (auto radarFenceBox : m_radarFenceBoxes)
	{
		m_radarElementsGroup->removeChild(radarFenceBox);
	}
	m_radarFenceBoxes.clear();
	initializeFence();
}

void FenceView::enforceFencePartsLimit()
{
	int maxFenceParts = m_fenceController->getFenceLimit();

	// the quad strip contains two more vertices for the beginning of the fence
	int currentFenceParts = (m_coordinates->size() - 2) / 2;

	if (maxFenceParts != 0 && currentFenceParts > maxFenceParts)
	{
		for (int i = 0; i < (currentFenceParts - maxFenceParts); i++)
		{
			m_coordinates->erase(m_coordinates->begin(), m_coordinates->begin() + 2);
			m_relativeHeights->erase(m_relativeHeights->begin(), m_relativeHeights->begin() + 2);
		}
	}
	// radar fence boxes
	if (maxFenceParts != 0 && m_radarFenceBoxes.size() > maxFenceParts / FENCE_TO_MINIMAP_PARTS_RATIO)
	{
		for (int i = 0; i < (m_radarFenceBoxes.size() - maxFenceParts / FENCE_TO_MINIMAP_PARTS_RATIO); i++)
		{
			m_radarElementsGroup->removeChild(m_radarFenceBoxes.front());
			m_radarFenceBoxes.pop_front();
		}
	}
}

void FenceView::showFencesInRadarForPlayer(const int id)
{
	osg::Node::NodeMask currentMask = m_radarElementsGroup->getNodeMask();
	osg::Node::NodeMask newMask = currentMask | CAMERA_MASK_PLAYER[id];
	m_radarElementsGroup->setNodeMask(newMask);
}

void FenceView::hideFencesInRadarForPlayer(const int id)
{
	osg::Node::NodeMask currentMask = m_radarElementsGroup->getNodeMask();
	osg::Node::NodeMask newMask = currentMask & ~ CAMERA_MASK_PLAYER[id];
	m_radarElementsGroup->setNodeMask(newMask);
}<commit_msg>fix for disappearing network fence<commit_after>#include "fenceview.h"
// OSG
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Vec4>
#include <osg/PositionAttitudeTransform>
#include <osg/ref_ptr>
// troen
#include "../constants.h"
#include "shaders.h"
#include "../model/fencemodel.h"
#include "../controller/fencecontroller.h"

using namespace troen;

FenceView::FenceView(FenceController* fenceController, osg::Vec3 color, std::shared_ptr<AbstractModel>& model) :
AbstractView(),
m_model(std::static_pointer_cast<FenceModel>(model)),
m_playerColor(color),
m_fenceController(fenceController)
{
	initializeFence();
	initializeShader();
}

void FenceView::initializeFence()
{
	m_fenceHeight = FENCE_HEIGHT_VIEW;

	m_coordinates = new osg::Vec3Array();
	m_coordinates->setDataVariance(osg::Object::DYNAMIC);

	m_relativeHeights = new osg::FloatArray();
	m_relativeHeights->setDataVariance(osg::Object::DYNAMIC);

	// this value could need adaption; will avoid time-intensive array resizing
	m_coordinates->reserveArray(10000);
	m_relativeHeights->reserveArray(10000);

	m_geometry = new osg::Geometry();
	m_geometry->setVertexArray(m_coordinates);

	// set the relative height between 0 and 1 as an additional vertex attribute
	m_geometry->setVertexAttribArray(5, m_relativeHeights);
	m_geometry->setVertexAttribBinding(5, osg::Geometry::BIND_PER_VERTEX);

	// seems to be important so that we won't crash after 683 fence parts
	m_geometry->setUseDisplayList(false);

	// use the shared normal array.
	// polyGeom->setNormalArray(shared_normals.get(), osg::Array::BIND_OVERALL);

	m_drawArrays = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP, 0, 0);
	m_geometry->addPrimitiveSet(m_drawArrays);

	m_geode = new osg::Geode();
	m_geode->addDrawable(m_geometry);

	m_node->addChild(m_geode);
	m_node->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
	m_node->setName("fenceGroup");

	m_radarElementsGroup = new osg::Group();
	m_radarElementsGroup->setNodeMask(CAMERA_MASK_NONE);
	m_node->addChild(m_radarElementsGroup);
}

void FenceView::updateFadeOutFactor(float fadeOutFactor)
{
	m_fadeOutFactorUniform->set(fadeOutFactor);
}

void FenceView::updateFenceGap(osg::Vec3 lastPosition, osg::Vec3 position)
{
	if (m_coordinates->size() > 1) {
		m_coordinates->at(m_coordinates->size() - 2) = osg::Vec3(position.x(), position.y(), position.z());
		m_coordinates->at(m_coordinates->size() - 1) = osg::Vec3(position.x(), position.y(), position.z() + m_fenceHeight);
		m_relativeHeights->at(m_relativeHeights->size() - 2) = 0.f;
		m_relativeHeights->at(m_relativeHeights->size() - 1) = 1.f;
	}
}

void FenceView::initializeShader()
{
	osg::ref_ptr<osg::StateSet> NodeState = m_node->getOrCreateStateSet();

	osg::Uniform* fenceColorU = new osg::Uniform("fenceColor", m_playerColor);
	NodeState->addUniform(fenceColorU);

	osg::Uniform* modelIDU = new osg::Uniform("modelID", GLOW);
	NodeState->addUniform(modelIDU);

	m_fadeOutFactorUniform = new osg::Uniform("fadeOutFactor", 1.f);
	NodeState->addUniform(m_fadeOutFactorUniform);

	NodeState->setMode(GL_BLEND, osg::StateAttribute::ON);
	NodeState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
	NodeState->setAttributeAndModes(shaders::m_allShaderPrograms[shaders::FENCE], osg::StateAttribute::ON);

	shaders::m_allShaderPrograms[shaders::FENCE]->addBindAttribLocation("a_relHeight", 5);
}

void FenceView::addFencePart(osg::Vec3 lastPosition, osg::Vec3 currentPosition)
{

	if (m_coordinates->size() == 0)
	{
		m_coordinates->push_back(lastPosition);
		m_coordinates->push_back(osg::Vec3(lastPosition.x(), lastPosition.y(), lastPosition.z() + m_fenceHeight));
		m_relativeHeights->push_back(0.f);
		m_relativeHeights->push_back(1.f);
	}

	// game fence part
	m_coordinates->push_back(currentPosition);
	m_coordinates->push_back(osg::Vec3(currentPosition.x(), currentPosition.y(), currentPosition.z() + m_fenceHeight));
	m_relativeHeights->push_back(0.f);
	m_relativeHeights->push_back(1.f);

	int currentFenceParts = (m_coordinates->size() - 2) / 2;

	// radar fence part
	if (currentFenceParts % FENCE_TO_MINIMAP_PARTS_RATIO == 0)
	{
		osg::ref_ptr<osg::Box> box
			= new osg::Box(osg::Vec3(0, 0, 0), 60, 60, 60);
		osg::ref_ptr<osg::ShapeDrawable> mark_shape = new osg::ShapeDrawable(box);
		mark_shape->setColor(osg::Vec4f(m_playerColor, 1));
		osg::ref_ptr<osg::Geode> mark_node = new osg::Geode;
		mark_node->addDrawable(mark_shape.get());
		//mark_node->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

		// place objects in world space
		osg::Matrixd initialTransform;
		//initialTransform.makeRotate(rotationQuatXY);
		initialTransform *= initialTransform.translate((currentPosition + lastPosition) / 2);

		osg::ref_ptr<osg::MatrixTransform> matrixTransformRadar = new osg::MatrixTransform(initialTransform);
		matrixTransformRadar->addChild(mark_node);

		m_radarElementsGroup->addChild(matrixTransformRadar);
		m_radarFenceBoxes.push_back(matrixTransformRadar);
	}

	// limit
	enforceFencePartsLimit();

	//necessary for network fences, because of unpredictable timings
	m_geometry->dirtyBound();
	m_drawArrays->setCount(m_coordinates->size());
}

void FenceView::removeAllFences()
{
	m_node->removeChild(m_geode);
	for (auto radarFenceBox : m_radarFenceBoxes)
	{
		m_radarElementsGroup->removeChild(radarFenceBox);
	}
	m_radarFenceBoxes.clear();
	initializeFence();
}

void FenceView::enforceFencePartsLimit()
{
	int maxFenceParts = m_fenceController->getFenceLimit();

	// the quad strip contains two more vertices for the beginning of the fence
	int currentFenceParts = (m_coordinates->size() - 2) / 2;

	if (maxFenceParts != 0 && currentFenceParts > maxFenceParts)
	{
		for (int i = 0; i < (currentFenceParts - maxFenceParts); i++)
		{
			m_coordinates->erase(m_coordinates->begin(), m_coordinates->begin() + 2);
			m_relativeHeights->erase(m_relativeHeights->begin(), m_relativeHeights->begin() + 2);
		}
	}
	// radar fence boxes
	if (maxFenceParts != 0 && m_radarFenceBoxes.size() > maxFenceParts / FENCE_TO_MINIMAP_PARTS_RATIO)
	{
		for (int i = 0; i < (m_radarFenceBoxes.size() - maxFenceParts / FENCE_TO_MINIMAP_PARTS_RATIO); i++)
		{
			m_radarElementsGroup->removeChild(m_radarFenceBoxes.front());
			m_radarFenceBoxes.pop_front();
		}
	}
}

void FenceView::showFencesInRadarForPlayer(const int id)
{
	osg::Node::NodeMask currentMask = m_radarElementsGroup->getNodeMask();
	osg::Node::NodeMask newMask = currentMask | CAMERA_MASK_PLAYER[id];
	m_radarElementsGroup->setNodeMask(newMask);
}

void FenceView::hideFencesInRadarForPlayer(const int id)
{
	osg::Node::NodeMask currentMask = m_radarElementsGroup->getNodeMask();
	osg::Node::NodeMask newMask = currentMask & ~ CAMERA_MASK_PLAYER[id];
	m_radarElementsGroup->setNodeMask(newMask);
}<|endoftext|>


<commit_before>#include <shiny/voodoo/context.hpp>
#include <shiny/voodoo/prime_thread.hpp>

//======================================================================
// context creation
//======================================================================
auto shiny::create_context(fooey::window_ptr const& window, uint32_t width, uint32_t height) -> shiny::context_ptr
{
	return context_ptr(new context_t(window, width, height));
}

using shiny::context_t;
context_t::context_t(fooey::window_ptr const& window, uint32_t width, uint32_t height)
	: window_(window), width_(width), height_(height), fullscreen_()
{
	if (width_ == 0)
		width_ = window_->width_in_pixels();
	if (height_ == 0)
		height_ = window_->height_in_pixels();

	ATMA_ENSURE_IS(S_OK, voodoo::detail::d3d_device_->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgi_device_));
	ATMA_ENSURE_IS(S_OK, dxgi_device_->GetParent(__uuidof(IDXGIAdapter1), (void**)&dxgi_adapter_));
	ATMA_ENSURE_IS(S_OK, dxgi_adapter_->GetParent(__uuidof(IDXGIFactory1), (void**)&dxgi_factory_));

	enumerate_backbuffers();
	create_swapchain();

	auto cptr = shared_from_this();
	on_resize_handle_ = window_->on_resize.connect([cptr](atma::event_flow_t& fc, uint32_t width, uint32_t height)
	{
		voodoo::prime_thread::enqueue([&cptr, &fc, width, height]
		{
			if (!cptr->fullscreen_)
			{
				cptr->width_ = width;
				cptr->height_ = height;
				std::cout << "resizing to " << cptr->width_ << "x" << cptr->height_ << std::endl;
				ATMA_ENSURE_IS(S_OK, cptr->dxgi_swap_chain_->ResizeBuffers(3, cptr->width_, cptr->height_, DXGI_FORMAT_UNKNOWN, 0));
			}
		});
	});
}

context_t::~context_t()
{
	window_->on_resize.disconnect(on_resize_handle_);
}

auto context_t::enumerate_backbuffers() -> void
{
	auto format = DXGI_FORMAT_R8G8B8A8_UNORM;

	IDXGIOutput* out = nullptr;
	ATMA_ENSURE_IS(S_OK, dxgi_adapter_->EnumOutputs(1, &out));

	uint32_t mode_count = 0;
	ATMA_ENSURE_IS(S_OK, out->GetDisplayModeList(format, 0, &mode_count, nullptr));

	auto modes = std::unique_ptr<DXGI_MODE_DESC[]>(new DXGI_MODE_DESC[mode_count]);
	ATMA_ENSURE_IS(S_OK, out->GetDisplayModeList(format, 0, &mode_count, modes.get()));

	// convert dxgi format to shiny's format
	for (auto i = modes.get(); i != modes.get() + mode_count; ++i)
	{
		backbuffer_display_modes_.push_back({
			i->Width, i->Height,
			i->RefreshRate.Numerator, i->RefreshRate.Denominator,
			display_format_t::r8g8b8a8_unorm
		});
	}
}

auto context_t::create_swapchain() -> void
{
	auto format = closest_fullscreen_backbuffer_mode(width_, height_);

	auto desc = DXGI_SWAP_CHAIN_DESC{
		// DXGI_MODE_DESC
		{format.width, format.height, {format.refreshrate_frames, format.refreshrate_period}, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED},
		// DXGI_SAMPLE_DESC
		{1, 0},
		0, 3, window_->hwnd, TRUE, DXGI_SWAP_EFFECT_DISCARD, 0
	};

	ATMA_ENSURE_IS(S_OK, dxgi_factory_->CreateSwapChain(voodoo::detail::d3d_device_, &desc, &dxgi_swap_chain_));
}

auto context_t::toggle_fullscreen() -> void
{
	fullscreen_ = !fullscreen_;

	if (fullscreen_)
	{
		auto mode = closest_fullscreen_backbuffer_mode(width_, height_);
		auto dxgi_mode = DXGI_MODE_DESC{mode.width, mode.height, {mode.refreshrate_frames, mode.refreshrate_period}, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED};

		std::cout << "going fullscreen to " << mode.width << "x" << mode.height << std::endl;
		dxgi_swap_chain_->ResizeTarget(&dxgi_mode);
		dxgi_swap_chain_->SetFullscreenState(TRUE, nullptr);
	}
	else
	{
		std::cout << "going windowed to " << width_ << "x" << height_ << std::endl;
		auto dxgi_mode = DXGI_MODE_DESC{width_, height_, {0, 1}, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED};
		dxgi_swap_chain_->ResizeTarget(&dxgi_mode);
		dxgi_swap_chain_->SetFullscreenState(FALSE, nullptr);
		//window_->on_resize.fire(width_, height_);
		//SendMessage(window_->hwnd, WM_SIZE, 0, ((uint16_t)height_ << 16) | (uint16_t)width_);
		RECT rect;
		GetWindowRect(window_->hwnd, &rect);
		SetWindowPos(window_->hwnd, HWND_TOPMOST, rect.left, rect.top, window_->width_in_pixels(), window_->height_in_pixels(), 0);
	}
}

auto context_t::closest_fullscreen_backbuffer_mode(uint32_t width, uint32_t height) -> shiny::display_mode_t
{
	for (auto const& x : backbuffer_display_modes_)
	{
		if (x.width > width && x.height > height)
			return x;
	}

	return backbuffer_display_modes_.back();
}

auto shiny::signal_fullscreen_toggle(context_ptr const& context) -> void
{
	voodoo::prime_thread::enqueue(std::bind(&context_t::toggle_fullscreen, context));
}
<commit_msg>context things<commit_after>#include <shiny/voodoo/context.hpp>
#include <shiny/voodoo/prime_thread.hpp>

//======================================================================
// context creation
//======================================================================
auto shiny::create_context(fooey::window_ptr const& window, uint32_t width, uint32_t height) -> shiny::context_ptr
{
	return context_ptr(new context_t(window, width, height));
}

using shiny::context_t;
context_t::context_t(fooey::window_ptr const& window, uint32_t width, uint32_t height)
	: window_(window), width_(width), height_(height), fullscreen_()
{
	if (width_ == 0)
		width_ = window_->width_in_pixels();
	if (height_ == 0)
		height_ = window_->height_in_pixels();

	ATMA_ENSURE_IS(S_OK, voodoo::detail::d3d_device_->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgi_device_));
	ATMA_ENSURE_IS(S_OK, dxgi_device_->GetParent(__uuidof(IDXGIAdapter1), (void**)&dxgi_adapter_));
	ATMA_ENSURE_IS(S_OK, dxgi_adapter_->GetParent(__uuidof(IDXGIFactory1), (void**)&dxgi_factory_));

	enumerate_backbuffers();
	create_swapchain();

	auto cptr = shared_from_this();
	on_resize_handle_ = window_->on_resize.connect([cptr](atma::event_flow_t& fc, uint32_t width, uint32_t height)
	{
		voodoo::prime_thread::enqueue([&cptr, &fc, width, height]
		{
			if (!cptr->fullscreen_)
			{
				cptr->width_ = width;
				cptr->height_ = height;
				std::cout << "resizing to " << cptr->width_ << "x" << cptr->height_ << std::endl;
				ATMA_ENSURE_IS(S_OK, cptr->dxgi_swap_chain_->ResizeBuffers(3, cptr->width_, cptr->height_, DXGI_FORMAT_UNKNOWN, 0));
			}
		});
	});
}

context_t::~context_t()
{
	window_->on_resize.disconnect(on_resize_handle_);
}

auto context_t::enumerate_backbuffers() -> void
{
	auto format = DXGI_FORMAT_R8G8B8A8_UNORM;

	IDXGIOutput* out = nullptr;
	ATMA_ENSURE_IS(S_OK, dxgi_adapter_->EnumOutputs(1, &out));

	uint32_t mode_count = 0;
	ATMA_ENSURE_IS(S_OK, out->GetDisplayModeList(format, 0, &mode_count, nullptr));

	auto modes = std::unique_ptr<DXGI_MODE_DESC[]>(new DXGI_MODE_DESC[mode_count]);
	ATMA_ENSURE_IS(S_OK, out->GetDisplayModeList(format, 0, &mode_count, modes.get()));

	// convert dxgi format to shiny's format
	for (auto i = modes.get(); i != modes.get() + mode_count; ++i)
	{
		backbuffer_display_modes_.push_back({
			i->Width, i->Height,
			i->RefreshRate.Numerator, i->RefreshRate.Denominator,
			display_format_t::r8g8b8a8_unorm
		});
	}
}

auto context_t::create_swapchain() -> void
{
	auto format = closest_fullscreen_backbuffer_mode(width_, height_);

	auto desc = DXGI_SWAP_CHAIN_DESC{
		// DXGI_MODE_DESC
		{format.width, format.height, {format.refreshrate_frames, format.refreshrate_period}, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED},
		// DXGI_SAMPLE_DESC
		{1, 0},
		0, 3, window_->hwnd, TRUE, DXGI_SWAP_EFFECT_DISCARD, 0
	};

	ATMA_ENSURE_IS(S_OK, dxgi_factory_->CreateSwapChain(voodoo::detail::d3d_device_, &desc, &dxgi_swap_chain_));
}

auto context_t::toggle_fullscreen() -> void
{
	fullscreen_ = !fullscreen_;

	if (fullscreen_)
	{
		auto mode = closest_fullscreen_backbuffer_mode(width_, height_);
		auto dxgi_mode = DXGI_MODE_DESC{mode.width, mode.height, {mode.refreshrate_frames, mode.refreshrate_period}, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED};

		std::cout << "SHINY: going fullscreen to " << mode.width << "x" << mode.height << std::endl;
		dxgi_swap_chain_->ResizeTarget(&dxgi_mode);
		dxgi_swap_chain_->SetFullscreenState(TRUE, nullptr);
	}
	else
	{
		std::cout << "SHINY: going windowed to " << width_ << "x" << height_ << std::endl;
		auto dxgi_mode = DXGI_MODE_DESC{width_, height_, {0, 1}, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE, DXGI_MODE_SCALING_UNSPECIFIED};
		dxgi_swap_chain_->ResizeTarget(&dxgi_mode);
		dxgi_swap_chain_->SetFullscreenState(FALSE, nullptr);

		//fooey::signal_window_resize(window_, width_, height_);

		RECT rect;
		GetWindowRect(window_->hwnd, &rect);
		SetWindowPos(window_->hwnd, HWND_TOPMOST, rect.left, rect.top, window_->width_in_pixels(), window_->height_in_pixels(), 0);
	}
}

auto context_t::closest_fullscreen_backbuffer_mode(uint32_t width, uint32_t height) -> shiny::display_mode_t
{
	for (auto const& x : backbuffer_display_modes_)
	{
		if (x.width > width && x.height > height)
			return x;
	}

	return backbuffer_display_modes_.back();
}

auto shiny::signal_fullscreen_toggle(context_ptr const& context) -> void
{
	voodoo::prime_thread::enqueue(std::bind(&context_t::toggle_fullscreen, context));
}
<|endoftext|>


<commit_before>#include <osgUtil/CubeMapGenerator>

#include <memory>
#ifndef __sgi
#include <cstdlib>
#else
#include <stdlib.h>
#endif

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:	osg::Referenced(),
	texture_size_(texture_size)
{
	for (int i=0; i<6; ++i) {
		osg::ref_ptr<osg::Image> image = osgNew osg::Image;
		//std::auto_ptr<unsigned char> data(static_cast<unsigned char *>(std::malloc(texture_size*texture_size*4)));
		std::auto_ptr<unsigned char> data(new unsigned char[(texture_size*texture_size*4)]);

		image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data.get());
		data.release();
		images_.push_back(image);
	}
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:	osg::Referenced(copy),
	texture_size_(copy.texture_size_)
{
	Image_list::const_iterator i;
	for (i=copy.images_.begin(); i!=copy.images_.end(); ++i) {
		images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
	}
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
	const float duv = 2.0f/(texture_size_-1);

	float v = 1;
	for (int i=0; i<texture_size_; ++i) {
		float u = 1;
		for (int j=0; j<texture_size_; ++j) {
			if (use_osg_system) {
				set_pixel(0, j, i, compute_color(osg::Vec3(1, -u, v)));
				set_pixel(1, j, i, compute_color(osg::Vec3(-1, u, v)));
				set_pixel(2, j, i, compute_color(osg::Vec3(-u, v, 1)));
				set_pixel(3, j, i, compute_color(osg::Vec3(-u, -v, -1)));
				set_pixel(4, j, i, compute_color(osg::Vec3(-u, -1, v)));
				set_pixel(5, j, i, compute_color(osg::Vec3(u, 1, v)));
			} else {
				set_pixel(0, j, i, compute_color(osg::Vec3(1, v, -u)));
				set_pixel(1, j, i, compute_color(osg::Vec3(-1, v, u)));
				set_pixel(2, j, i, compute_color(osg::Vec3(-u, 1, v)));
				set_pixel(3, j, i, compute_color(osg::Vec3(-u, -1, -v)));
				set_pixel(4, j, i, compute_color(osg::Vec3(-u, v, -1)));
				set_pixel(5, j, i, compute_color(osg::Vec3(u, v, 1)));
			}
			u -= duv;
		}
		v -= duv;
	}
}
<commit_msg>Fixed memory allocation.<commit_after>#include <osgUtil/CubeMapGenerator>
#include <stdlib.h>

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:    osg::Referenced(),
    texture_size_(texture_size)
{
    for (int i=0; i<6; ++i)
    {
        osg::ref_ptr<osg::Image> image = osgNew osg::Image;
        unsigned char* data = (static_cast<unsigned char *>(malloc(texture_size*texture_size*4)));
        image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data);
        images_.push_back(image);
    }
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:    osg::Referenced(copy),
    texture_size_(copy.texture_size_)
{
    Image_list::const_iterator i;
    for (i=copy.images_.begin(); i!=copy.images_.end(); ++i)
    {
        images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
    }
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
    const float duv = 2.0f/(texture_size_-1);

    float v = 1;
    for (int i=0; i<texture_size_; ++i) {
        float u = 1;
        for (int j=0; j<texture_size_; ++j) {
            if (use_osg_system) {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, -u, v)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, u, v)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, v, 1)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -v, -1)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, -1, v)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, 1, v)));
            } else {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, v, -u)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, v, u)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, 1, v)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -1, -v)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, v, -1)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, v, 1)));
            }
            u -= duv;
        }
        v -= duv;
    }
}
<|endoftext|>


<commit_before>// ***************************************************************************
//
//   Generated automatically by genwrapper.
//   Please DO NOT EDIT this file!
//
// ***************************************************************************

#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/Attributes>

#include <osg/CopyOp>
#include <osg/Object>
#include <osg/State>
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Texture>
#include <osg/Vec2>
#include <osgText/Font>

// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif

BEGIN_OBJECT_REFLECTOR(osgText::Font)
	I_BaseType(osg::Object);
	I_ConstructorWithDefaults1(IN, osgText::Font::FontImplementation *, implementation, 0);
	I_Method0(osg::Object *, cloneType);
	I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, x);
	I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj);
	I_Method0(const char *, className);
	I_Method0(const char *, libraryName);
	I_Method0(std::string, getFileName);
	I_Method2(void, setFontResolution, IN, unsigned int, width, IN, unsigned int, height);
	I_Method0(unsigned int, getFontWidth);
	I_Method0(unsigned int, getFontHeight);
	I_Method3(osg::Vec2, getKerning, IN, unsigned int, leftcharcode, IN, unsigned int, rightcharcode, IN, osgText::KerningType, kerningType);
	I_Method1(osgText::Font::Glyph *, getGlyph, IN, unsigned int, charcode);
	I_Method0(bool, hasVertical);
	I_Method1(void, setGlyphImageMargin, IN, unsigned int, margin);
	I_Method0(unsigned int, getGlyphImageMargin);
	I_Method2(void, setTextureSizeHint, IN, unsigned int, width, IN, unsigned int, height);
	I_Method0(unsigned int, getTextureWidthHint);
	I_Method0(unsigned int, getTextureHeightHint);
	I_Method1(void, setMinFilterHint, IN, osg::Texture::FilterMode, mode);
	I_Method0(osg::Texture::FilterMode, getMinFilterHint);
	I_Method1(void, setMagFilterHint, IN, osg::Texture::FilterMode, mode);
	I_Method0(osg::Texture::FilterMode, getMagFilterHint);
	I_Method1(void, setImplementation, IN, osgText::Font::FontImplementation *, implementation);
	I_Method0(osgText::Font::FontImplementation *, getImplementation);
	I_Method0(const osgText::Font::FontImplementation *, getImplementation);
	I_MethodWithDefaults1(void, releaseGLObjects, IN, osg::State *, state, 0);
	I_ReadOnlyProperty(std::string, FileName);
	I_ReadOnlyProperty(unsigned int, FontHeight);
	I_ReadOnlyProperty(unsigned int, FontWidth);
	I_Property(unsigned int, GlyphImageMargin);
	I_Property(osgText::Font::FontImplementation *, Implementation);
	I_Property(osg::Texture::FilterMode, MagFilterHint);
	I_Property(osg::Texture::FilterMode, MinFilterHint);
	I_ReadOnlyProperty(unsigned int, TextureHeightHint);
	I_ReadOnlyProperty(unsigned int, TextureWidthHint);
END_REFLECTOR

BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgText::Font::FontImplementation)
	I_BaseType(osg::Referenced);
	I_Constructor0();
	I_Method0(std::string, getFileName);
	I_Method2(void, setFontResolution, IN, unsigned int, width, IN, unsigned int, height);
	I_Method1(osgText::Font::Glyph *, getGlyph, IN, unsigned int, charcode);
	I_Method3(osg::Vec2, getKerning, IN, unsigned int, leftcharcode, IN, unsigned int, rightcharcode, IN, osgText::KerningType, kerningType);
	I_Method0(bool, hasVertical);
	I_Method1(void, setFontWidth, IN, unsigned int, width);
	I_Method1(void, setFontHeight, IN, unsigned int, height);
	I_Method4(void, addGlyph, IN, unsigned int, width, IN, unsigned int, height, IN, unsigned int, charcode, IN, osgText::Font::Glyph *, glyph);
	I_ReadOnlyProperty(std::string, FileName);
	I_WriteOnlyProperty(unsigned int, FontHeight);
	I_WriteOnlyProperty(unsigned int, FontWidth);
END_REFLECTOR

BEGIN_OBJECT_REFLECTOR(osgText::Font::Glyph)
	I_BaseType(osg::Image);
	I_Constructor0();
	I_Method0(unsigned int, getGlyphCode);
	I_Method1(void, setHorizontalBearing, IN, const osg::Vec2 &, bearing);
	I_Method0(const osg::Vec2 &, getHorizontalBearing);
	I_Method1(void, setHorizontalAdvance, IN, float, advance);
	I_Method0(float, getHorizontalAdvance);
	I_Method1(void, setVerticalBearing, IN, const osg::Vec2 &, bearing);
	I_Method0(const osg::Vec2 &, getVerticalBearing);
	I_Method1(void, setVerticalAdvance, IN, float, advance);
	I_Method0(float, getVerticalAdvance);
	I_Method1(void, setTexture, IN, osgText::Font::GlyphTexture *, texture);
	I_Method0(osgText::Font::GlyphTexture *, getTexture);
	I_Method0(const osgText::Font::GlyphTexture *, getTexture);
	I_Method0(osg::StateSet *, getStateSet);
	I_Method0(const osg::StateSet *, getStateSet);
	I_Method2(void, setTexturePosition, IN, int, posX, IN, int, posY);
	I_Method0(int, getTexturePositionX);
	I_Method0(int, getTexturePositionY);
	I_Method1(void, setMinTexCoord, IN, const osg::Vec2 &, coord);
	I_Method0(const osg::Vec2 &, getMinTexCoord);
	I_Method1(void, setMaxTexCoord, IN, const osg::Vec2 &, coord);
	I_Method0(const osg::Vec2 &, getMaxTexCoord);
	I_Method0(void, subload);
	I_Method1(void, draw, IN, osg::State &, state);
	I_ReadOnlyProperty(unsigned int, GlyphCode);
	I_Property(float, HorizontalAdvance);
	I_Property(const osg::Vec2 &, HorizontalBearing);
	I_Property(const osg::Vec2 &, MaxTexCoord);
	I_Property(const osg::Vec2 &, MinTexCoord);
	I_ReadOnlyProperty(osg::StateSet *, StateSet);
	I_Property(osgText::Font::GlyphTexture *, Texture);
	I_ReadOnlyProperty(int, TexturePositionX);
	I_ReadOnlyProperty(int, TexturePositionY);
	I_Property(float, VerticalAdvance);
	I_Property(const osg::Vec2 &, VerticalBearing);
END_REFLECTOR

BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgText::Font::GlyphTexture)
	I_BaseType(osg::Texture2D);
	I_Constructor0();
	I_Method0(const char *, className);
	I_Method1(int, compare, IN, const osg::StateAttribute &, rhs);
	I_Method1(void, setStateSet, IN, osg::StateSet *, stateset);
	I_Method0(osg::StateSet *, getStateSet);
	I_Method0(const osg::StateSet *, getStateSet);
	I_Method1(void, setGlyphImageMargin, IN, unsigned int, margin);
	I_Method0(unsigned int, getGlyphImageMargin);
	I_Method3(bool, getSpaceForGlyph, IN, osgText::Font::Glyph *, glyph, IN, int &, posX, IN, int &, posY);
	I_Method3(void, addGlyph, IN, osgText::Font::Glyph *, glyph, IN, int, posX, IN, int, posY);
	I_Method1(void, apply, IN, osg::State &, state);
	I_Property(unsigned int, GlyphImageMargin);
	I_Property(osg::StateSet *, StateSet);
END_REFLECTOR

BEGIN_ENUM_REFLECTOR(osgText::KerningType)
	I_EnumLabel(osgText::KERNING_DEFAULT);
	I_EnumLabel(osgText::KERNING_UNFITTED);
	I_EnumLabel(osgText::KERNING_NONE);
END_REFLECTOR

<commit_msg>Updated wrappers.<commit_after>// ***************************************************************************
//
//   Generated automatically by genwrapper.
//   Please DO NOT EDIT this file!
//
// ***************************************************************************

#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/Attributes>

#include <osg/CopyOp>
#include <osg/Object>
#include <osg/State>
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Texture>
#include <osg/Vec2>
#include <osgText/Font>

// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif

BEGIN_OBJECT_REFLECTOR(osgText::Font)
	I_BaseType(osg::Object);
	I_ConstructorWithDefaults1(IN, osgText::Font::FontImplementation *, implementation, 0);
	I_Method0(osg::Object *, cloneType);
	I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, x);
	I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj);
	I_Method0(const char *, className);
	I_Method0(const char *, libraryName);
	I_Method0(std::string, getFileName);
	I_Method1(void, setStateSet, IN, osg::StateSet *, stateset);
	I_Method0(osg::StateSet *, getStateSet);
	I_Method0(const osg::StateSet *, getStateSet);
	I_Method2(void, setFontResolution, IN, unsigned int, width, IN, unsigned int, height);
	I_Method0(unsigned int, getFontWidth);
	I_Method0(unsigned int, getFontHeight);
	I_Method3(osg::Vec2, getKerning, IN, unsigned int, leftcharcode, IN, unsigned int, rightcharcode, IN, osgText::KerningType, kerningType);
	I_Method1(osgText::Font::Glyph *, getGlyph, IN, unsigned int, charcode);
	I_Method0(bool, hasVertical);
	I_Method1(void, setGlyphImageMargin, IN, unsigned int, margin);
	I_Method0(unsigned int, getGlyphImageMargin);
	I_Method2(void, setTextureSizeHint, IN, unsigned int, width, IN, unsigned int, height);
	I_Method0(unsigned int, getTextureWidthHint);
	I_Method0(unsigned int, getTextureHeightHint);
	I_Method1(void, setMinFilterHint, IN, osg::Texture::FilterMode, mode);
	I_Method0(osg::Texture::FilterMode, getMinFilterHint);
	I_Method1(void, setMagFilterHint, IN, osg::Texture::FilterMode, mode);
	I_Method0(osg::Texture::FilterMode, getMagFilterHint);
	I_Method1(void, setImplementation, IN, osgText::Font::FontImplementation *, implementation);
	I_Method0(osgText::Font::FontImplementation *, getImplementation);
	I_Method0(const osgText::Font::FontImplementation *, getImplementation);
	I_MethodWithDefaults1(void, releaseGLObjects, IN, osg::State *, state, 0);
	I_ReadOnlyProperty(std::string, FileName);
	I_ReadOnlyProperty(unsigned int, FontHeight);
	I_ReadOnlyProperty(unsigned int, FontWidth);
	I_Property(unsigned int, GlyphImageMargin);
	I_Property(osgText::Font::FontImplementation *, Implementation);
	I_Property(osg::Texture::FilterMode, MagFilterHint);
	I_Property(osg::Texture::FilterMode, MinFilterHint);
	I_Property(osg::StateSet *, StateSet);
	I_ReadOnlyProperty(unsigned int, TextureHeightHint);
	I_ReadOnlyProperty(unsigned int, TextureWidthHint);
END_REFLECTOR

BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgText::Font::FontImplementation)
	I_BaseType(osg::Referenced);
	I_Constructor0();
	I_Method0(std::string, getFileName);
	I_Method2(void, setFontResolution, IN, unsigned int, width, IN, unsigned int, height);
	I_Method1(osgText::Font::Glyph *, getGlyph, IN, unsigned int, charcode);
	I_Method3(osg::Vec2, getKerning, IN, unsigned int, leftcharcode, IN, unsigned int, rightcharcode, IN, osgText::KerningType, kerningType);
	I_Method0(bool, hasVertical);
	I_Method1(void, setFontWidth, IN, unsigned int, width);
	I_Method1(void, setFontHeight, IN, unsigned int, height);
	I_Method4(void, addGlyph, IN, unsigned int, width, IN, unsigned int, height, IN, unsigned int, charcode, IN, osgText::Font::Glyph *, glyph);
	I_ReadOnlyProperty(std::string, FileName);
	I_WriteOnlyProperty(unsigned int, FontHeight);
	I_WriteOnlyProperty(unsigned int, FontWidth);
END_REFLECTOR

BEGIN_OBJECT_REFLECTOR(osgText::Font::Glyph)
	I_BaseType(osg::Image);
	I_Constructor0();
	I_Method0(unsigned int, getGlyphCode);
	I_Method1(void, setHorizontalBearing, IN, const osg::Vec2 &, bearing);
	I_Method0(const osg::Vec2 &, getHorizontalBearing);
	I_Method1(void, setHorizontalAdvance, IN, float, advance);
	I_Method0(float, getHorizontalAdvance);
	I_Method1(void, setVerticalBearing, IN, const osg::Vec2 &, bearing);
	I_Method0(const osg::Vec2 &, getVerticalBearing);
	I_Method1(void, setVerticalAdvance, IN, float, advance);
	I_Method0(float, getVerticalAdvance);
	I_Method1(void, setTexture, IN, osgText::Font::GlyphTexture *, texture);
	I_Method0(osgText::Font::GlyphTexture *, getTexture);
	I_Method0(const osgText::Font::GlyphTexture *, getTexture);
	I_Method0(osg::StateSet *, getStateSet);
	I_Method0(const osg::StateSet *, getStateSet);
	I_Method2(void, setTexturePosition, IN, int, posX, IN, int, posY);
	I_Method0(int, getTexturePositionX);
	I_Method0(int, getTexturePositionY);
	I_Method1(void, setMinTexCoord, IN, const osg::Vec2 &, coord);
	I_Method0(const osg::Vec2 &, getMinTexCoord);
	I_Method1(void, setMaxTexCoord, IN, const osg::Vec2 &, coord);
	I_Method0(const osg::Vec2 &, getMaxTexCoord);
	I_Method0(void, subload);
	I_Method1(void, draw, IN, osg::State &, state);
	I_ReadOnlyProperty(unsigned int, GlyphCode);
	I_Property(float, HorizontalAdvance);
	I_Property(const osg::Vec2 &, HorizontalBearing);
	I_Property(const osg::Vec2 &, MaxTexCoord);
	I_Property(const osg::Vec2 &, MinTexCoord);
	I_ReadOnlyProperty(osg::StateSet *, StateSet);
	I_Property(osgText::Font::GlyphTexture *, Texture);
	I_ReadOnlyProperty(int, TexturePositionX);
	I_ReadOnlyProperty(int, TexturePositionY);
	I_Property(float, VerticalAdvance);
	I_Property(const osg::Vec2 &, VerticalBearing);
END_REFLECTOR

BEGIN_ABSTRACT_OBJECT_REFLECTOR(osgText::Font::GlyphTexture)
	I_BaseType(osg::Texture2D);
	I_Constructor0();
	I_Method0(const char *, className);
	I_Method1(int, compare, IN, const osg::StateAttribute &, rhs);
	I_Method1(void, setStateSet, IN, osg::StateSet *, stateset);
	I_Method0(osg::StateSet *, getStateSet);
	I_Method0(const osg::StateSet *, getStateSet);
	I_Method1(void, setGlyphImageMargin, IN, unsigned int, margin);
	I_Method0(unsigned int, getGlyphImageMargin);
	I_Method3(bool, getSpaceForGlyph, IN, osgText::Font::Glyph *, glyph, IN, int &, posX, IN, int &, posY);
	I_Method3(void, addGlyph, IN, osgText::Font::Glyph *, glyph, IN, int, posX, IN, int, posY);
	I_Method1(void, apply, IN, osg::State &, state);
	I_Property(unsigned int, GlyphImageMargin);
	I_Property(osg::StateSet *, StateSet);
END_REFLECTOR

BEGIN_ENUM_REFLECTOR(osgText::KerningType)
	I_EnumLabel(osgText::KERNING_DEFAULT);
	I_EnumLabel(osgText::KERNING_UNFITTED);
	I_EnumLabel(osgText::KERNING_NONE);
END_REFLECTOR

<|endoftext|>


<commit_before>#include "DoorEntity.h"

DoorEntity::DoorEntity()
{
}

DoorEntity::~DoorEntity()
{
}
<commit_msg>ADD function declaration<commit_after>#include "DoorEntity.h"

DoorEntity::DoorEntity()
{
}

DoorEntity::~DoorEntity()
{
}

int DoorEntity::Initialize(int entityID, PhysicsComponent * pComp, GraphicsComponent * gComp)
{
	this->InitializeBase(entityID, pComp, gComp);

	return 0;
}

int DoorEntity::Update(float dT, InputHandler * inputHandler)
{
	return 0;
}

int DoorEntity::React(int entityID, EVENT reactEvent)
{
	return 0;
}
<|endoftext|>


<commit_before>#include "DoorEntity.h"

DoorEntity::DoorEntity()
{
}

DoorEntity::~DoorEntity()
{
}

int DoorEntity::Initialize(int entityID, PhysicsComponent * pComp, GraphicsComponent * gComp, float minRotation, float maxRotation, float rotateTime)
{
	this->InitializeBase(entityID, pComp, gComp);

	this->m_isOpened = false;
	this->m_minRotation = minRotation;
	this->m_maxRotation = maxRotation;
	this->m_rotateTime = rotateTime;
	this->m_rotatePerSec = (this->m_maxRotation - this->m_minRotation) / this->m_rotateTime;
	this->SyncComponents();

	return 0;
}

int DoorEntity::Update(float dT, InputHandler * inputHandler)
{
	if (this->m_isOpened)
	{
		if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) < this->m_maxRotation)
		{
			this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, DirectX::XMVectorGetY(this->m_pComp->PC_rotation) + (this->m_rotatePerSec * dT));
			if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) > this->m_maxRotation)
			{
				this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, this->m_maxRotation);
			}
			this->SyncComponents();
		}
	}
	else
	{
		if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) > this->m_minRotation)
		{
			this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, DirectX::XMVectorGetY(this->m_pComp->PC_rotation) - (this->m_rotatePerSec * dT));
			if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) < this->m_minRotation)
			{
				this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, this->m_minRotation);
			}
			this->SyncComponents();
		}
	}

	return 0;
}

int DoorEntity::React(int entityID, EVENT reactEvent)
{
	if (reactEvent == EVENT::BUTTON_PRESSED)
	{
		if (!this->m_isOpened)
		{
			this->m_isOpened = true;
			this->m_subject.Notify(this->m_entityID, EVENT::DOOR_OPENED);
		}
		else
		{
			this->m_isOpened = false;
			this->m_subject.Notify(this->m_entityID, EVENT::DOOR_CLOSED);
		}
	}
	else if (reactEvent == EVENT::WHEEL_0)
	{
		this->m_isOpened = false;
	}
	else if (reactEvent == EVENT::WHEEL_100)
	{
		this->m_isOpened = true;
	}

	return 0;
}

bool DoorEntity::SetIsOpened(bool isOpened)
{
	bool lastValue = this->m_isOpened;
	this->m_isOpened = isOpened;
	return lastValue;
}

bool DoorEntity::GetIsOpened()
{
	return this->m_isOpened;
}
<commit_msg>UPDATE DOOR now utilizes the new events correctly<commit_after>#include "DoorEntity.h"

DoorEntity::DoorEntity()
{
}

DoorEntity::~DoorEntity()
{
}

int DoorEntity::Initialize(int entityID, PhysicsComponent * pComp, GraphicsComponent * gComp, float minRotation, float maxRotation, float rotateTime)
{
	this->InitializeBase(entityID, pComp, gComp);

	this->m_isOpened = false;
	this->m_minRotation = minRotation;
	this->m_maxRotation = maxRotation;
	this->m_rotateTime = rotateTime;
	this->m_rotatePerSec = (this->m_maxRotation - this->m_minRotation) / this->m_rotateTime;
	this->SyncComponents();

	return 0;
}

int DoorEntity::Update(float dT, InputHandler * inputHandler)
{
	if (this->m_isOpened)
	{
		if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) < this->m_maxRotation)
		{
			this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, DirectX::XMVectorGetY(this->m_pComp->PC_rotation) + (this->m_rotatePerSec * dT));
			if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) > this->m_maxRotation)
			{
				this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, this->m_maxRotation);
			}
			this->SyncComponents();
		}
	}
	else
	{
		if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) > this->m_minRotation)
		{
			this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, DirectX::XMVectorGetY(this->m_pComp->PC_rotation) - (this->m_rotatePerSec * dT));
			if (DirectX::XMVectorGetY(this->m_pComp->PC_rotation) < this->m_minRotation)
			{
				this->m_pComp->PC_rotation = DirectX::XMVectorSetY(this->m_pComp->PC_rotation, this->m_minRotation);
			}
			this->SyncComponents();
		}
	}

	return 0;
}

int DoorEntity::React(int entityID, EVENT reactEvent)
{
	//Kims stuff, "crazy but elegant" - Oscar 2017-01-23
	//this->m_isOpened = reactEvent == EVENT::BUTTON_ACTIVE;
	if (reactEvent == EVENT::BUTTON_ACTIVE)
	{
		this->m_isOpened = true;
		this->m_subject.Notify(this->m_entityID, EVENT::DOOR_OPENED);
	}
	else if(reactEvent == EVENT::BUTTON_DEACTIVE)
	{
		this->m_isOpened = false;
		this->m_subject.Notify(this->m_entityID, EVENT::DOOR_CLOSED);
	}
	else if (reactEvent == EVENT::WHEEL_0)
	{
		this->m_isOpened = false;
	}
	else if (reactEvent == EVENT::WHEEL_100)
	{
		this->m_isOpened = true;
	}

	return 0;
}

bool DoorEntity::SetIsOpened(bool isOpened)
{
	bool lastValue = this->m_isOpened;
	this->m_isOpened = isOpened;
	return lastValue;
}

bool DoorEntity::GetIsOpened()
{
	return this->m_isOpened;
}
<|endoftext|>


<commit_before>//===- GraphChecker.cpp - Assert that various graph properties hold -------===//
//
// This pass is used to test DSA with regression tests.  It can be used to check
// that certain graph properties hold, such as two nodes being disjoint, whether
// or not a node is collapsed, etc.  These are the command line arguments that
// it supports:
//
//   --dsgc-dsapass={local,bu,td}     - Specify what flavor of graph to check
//   --dsgc-abort-if-any-collapsed    - Abort if any collapsed nodes are found
//   --dsgc-abort-if-collapsed=<list> - Abort if a node pointed to by an SSA
//                                      value with name in <list> is collapsed
//   --dsgc-check-flags=<list>        - Abort if the specified nodes have flags
//                                      that are not specified.
//   --dsgc-abort-if-merged=<list>    - Abort if any of the named SSA values
//                                      point to the same node.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "Support/CommandLine.h"
#include "llvm/Value.h"
#include <set>

namespace {
  enum DSPass { local, bu, td };
  cl::opt<DSPass>
  DSPass("dsgc-dspass", cl::Hidden,
       cl::desc("Specify which DSA pass the -datastructure-gc pass should use"),
         cl::values(clEnumVal(local, "Local pass"),
                    clEnumVal(bu,    "Bottom-up pass"),
                    clEnumVal(td,    "Top-down pass"), 0), cl::init(local));

  cl::opt<bool>
  AbortIfAnyCollapsed("dsgc-abort-if-any-collapsed", cl::Hidden,
                      cl::desc("Abort if any collapsed nodes are found"));
  cl::list<std::string>
  AbortIfCollapsed("dsgc-abort-if-collapsed", cl::Hidden, cl::CommaSeparated,
                   cl::desc("Abort if any of the named symbols is collapsed"));
  cl::list<std::string>
  CheckFlags("dsgc-check-flags", cl::Hidden, cl::CommaSeparated,
             cl::desc("Check that flags are specified for nodes"));
  cl::list<std::string>
  AbortIfMerged("dsgc-abort-if-merged", cl::Hidden, cl::CommaSeparated,
             cl::desc("Abort if any of the named symbols are merged together"));

  struct DSGC : public FunctionPass {
    DSGC();
    bool doFinalization(Module &M);
    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      switch (DSPass) {
      case local: AU.addRequired<LocalDataStructures>(); break;
      case bu:    AU.addRequired<BUDataStructures>(); break;
      case td:    AU.addRequired<TDDataStructures>(); break;
      }
      AU.setPreservesAll();
    }
    void print(std::ostream &O, const Module *M) const {}

  private:
    void verify(const DSGraph &G);
  };

  RegisterAnalysis<DSGC> X("datastructure-gc", "DSA Graph Checking Pass");
}

DSGC::DSGC() {
  if (!AbortIfAnyCollapsed && AbortIfCollapsed.empty() &&
      CheckFlags.empty() && AbortIfMerged.empty()) {
    std::cerr << "The -datastructure-gc is useless if you don't specify any"
                 " -dsgc-* options.  See the -help-hidden output for a list.\n";
    abort();
  }
}

/// doFinalization - Verify that the globals graph is in good shape...
///
bool DSGC::doFinalization(Module &M) {
  switch (DSPass) {
  case local:verify(getAnalysis<LocalDataStructures>().getGlobalsGraph());break;
  case bu:   verify(getAnalysis<BUDataStructures>().getGlobalsGraph()); break;
  case td:   verify(getAnalysis<TDDataStructures>().getGlobalsGraph()); break;
  }
  return false;
}

/// runOnFunction - Get the DSGraph for this function and verify that it is ok.
///
bool DSGC::runOnFunction(Function &F) {
  switch (DSPass) {
  case local: verify(getAnalysis<LocalDataStructures>().getDSGraph(F)); break;
  case bu:    verify(getAnalysis<BUDataStructures>().getDSGraph(F)); break;
  case td:    verify(getAnalysis<TDDataStructures>().getDSGraph(F)); break;
  }

  return false;
}

/// verify - This is the function which checks to make sure that all of the
/// invariants established on the command line are true.
///
void DSGC::verify(const DSGraph &G) {
  // Loop over all of the nodes, checking to see if any are collapsed...
  if (AbortIfAnyCollapsed) {
    const std::vector<DSNode*> &Nodes = G.getNodes();
    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
      if (Nodes[i]->isNodeCompletelyFolded()) {
        std::cerr << "Node is collapsed: ";
        Nodes[i]->print(std::cerr, &G);
        abort();
      }
  }

  if (!AbortIfCollapsed.empty() || !CheckFlags.empty() ||
      !AbortIfMerged.empty()) {
    // Convert from a list to a set, because we don't have cl::set's yet.  FIXME
    std::set<std::string> AbortIfCollapsedS(AbortIfCollapsed.begin(),
                                            AbortIfCollapsed.end());
    std::set<std::string> AbortIfMergedS(AbortIfMerged.begin(),
                                         AbortIfMerged.end());
    std::map<std::string, unsigned> CheckFlagsM;

    for (cl::list<std::string>::iterator I = CheckFlags.begin(),
           E = CheckFlags.end(); I != E; ++I) {
      unsigned ColonPos = I->rfind(':');
      if (ColonPos == std::string::npos) {
        std::cerr << "Error: '" << *I
               << "' is an invalid value for the --dsgc-check-flags option!\n";
        abort();
      }

      unsigned Flags = 0;
      for (unsigned C = ColonPos+1; C != I->size(); ++C)
        switch ((*I)[C]) {
        case 'S': Flags |= DSNode::AllocaNode;  break;
        case 'H': Flags |= DSNode::HeapNode;    break;
        case 'G': Flags |= DSNode::GlobalNode;  break;
        case 'U': Flags |= DSNode::UnknownNode; break;
        case 'I': Flags |= DSNode::Incomplete;  break;
        case 'M': Flags |= DSNode::Modified;    break;
        case 'R': Flags |= DSNode::Read;        break;
        case 'A': Flags |= DSNode::Array;       break;
        default: std::cerr << "Invalid DSNode flag!\n"; abort();
        }
      CheckFlagsM[std::string(I->begin(), I->begin()+ColonPos)] = Flags;
    }

    // Now we loop over all of the scalars, checking to see if any are collapsed
    // that are not supposed to be, or if any are merged together.
    const DSGraph::ScalarMapTy &SM = G.getScalarMap();
    std::map<DSNode*, std::string> AbortIfMergedNodes;

    for (DSGraph::ScalarMapTy::const_iterator I = SM.begin(), E = SM.end();
         I != E; ++I)
      if (I->first->hasName() && I->second.getNode()) {
        const std::string &Name = I->first->getName();
        DSNode *N = I->second.getNode();

        // Verify it is not collapsed if it is not supposed to be...
        if (N->isNodeCompletelyFolded() && AbortIfCollapsedS.count(Name)) {
          std::cerr << "Node for value '%" << Name << "' is collapsed: ";
          N->print(std::cerr, &G);
          abort();
        }

        if (CheckFlagsM.count(Name) && CheckFlagsM[Name] != N->getNodeFlags()) {
          std::cerr << "Node flags are not as expected for node: " << Name
                    << "\n";
          N->print(std::cerr, &G);
          abort();
        }

        // Verify that it is not merged if it is not supposed to be...
        if (AbortIfMergedS.count(Name)) {
          if (AbortIfMergedNodes.count(N)) {
            std::cerr << "Nodes for values '%" << Name << "' and '%"
                      << AbortIfMergedNodes[N] << "' is merged: ";
            N->print(std::cerr, &G);
            abort();
          }
          AbortIfMergedNodes[N] = Name;
        }
      }
  }
}
<commit_msg>Use std::string::size_type for for ColonPos to stop gcc from giving a warning<commit_after>//===- GraphChecker.cpp - Assert that various graph properties hold -------===//
//
// This pass is used to test DSA with regression tests.  It can be used to check
// that certain graph properties hold, such as two nodes being disjoint, whether
// or not a node is collapsed, etc.  These are the command line arguments that
// it supports:
//
//   --dsgc-dsapass={local,bu,td}     - Specify what flavor of graph to check
//   --dsgc-abort-if-any-collapsed    - Abort if any collapsed nodes are found
//   --dsgc-abort-if-collapsed=<list> - Abort if a node pointed to by an SSA
//                                      value with name in <list> is collapsed
//   --dsgc-check-flags=<list>        - Abort if the specified nodes have flags
//                                      that are not specified.
//   --dsgc-abort-if-merged=<list>    - Abort if any of the named SSA values
//                                      point to the same node.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "Support/CommandLine.h"
#include "llvm/Value.h"
#include <set>

namespace {
  enum DSPass { local, bu, td };
  cl::opt<DSPass>
  DSPass("dsgc-dspass", cl::Hidden,
       cl::desc("Specify which DSA pass the -datastructure-gc pass should use"),
         cl::values(clEnumVal(local, "Local pass"),
                    clEnumVal(bu,    "Bottom-up pass"),
                    clEnumVal(td,    "Top-down pass"), 0), cl::init(local));

  cl::opt<bool>
  AbortIfAnyCollapsed("dsgc-abort-if-any-collapsed", cl::Hidden,
                      cl::desc("Abort if any collapsed nodes are found"));
  cl::list<std::string>
  AbortIfCollapsed("dsgc-abort-if-collapsed", cl::Hidden, cl::CommaSeparated,
                   cl::desc("Abort if any of the named symbols is collapsed"));
  cl::list<std::string>
  CheckFlags("dsgc-check-flags", cl::Hidden, cl::CommaSeparated,
             cl::desc("Check that flags are specified for nodes"));
  cl::list<std::string>
  AbortIfMerged("dsgc-abort-if-merged", cl::Hidden, cl::CommaSeparated,
             cl::desc("Abort if any of the named symbols are merged together"));

  struct DSGC : public FunctionPass {
    DSGC();
    bool doFinalization(Module &M);
    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      switch (DSPass) {
      case local: AU.addRequired<LocalDataStructures>(); break;
      case bu:    AU.addRequired<BUDataStructures>(); break;
      case td:    AU.addRequired<TDDataStructures>(); break;
      }
      AU.setPreservesAll();
    }
    void print(std::ostream &O, const Module *M) const {}

  private:
    void verify(const DSGraph &G);
  };

  RegisterAnalysis<DSGC> X("datastructure-gc", "DSA Graph Checking Pass");
}

DSGC::DSGC() {
  if (!AbortIfAnyCollapsed && AbortIfCollapsed.empty() &&
      CheckFlags.empty() && AbortIfMerged.empty()) {
    std::cerr << "The -datastructure-gc is useless if you don't specify any"
                 " -dsgc-* options.  See the -help-hidden output for a list.\n";
    abort();
  }
}

/// doFinalization - Verify that the globals graph is in good shape...
///
bool DSGC::doFinalization(Module &M) {
  switch (DSPass) {
  case local:verify(getAnalysis<LocalDataStructures>().getGlobalsGraph());break;
  case bu:   verify(getAnalysis<BUDataStructures>().getGlobalsGraph()); break;
  case td:   verify(getAnalysis<TDDataStructures>().getGlobalsGraph()); break;
  }
  return false;
}

/// runOnFunction - Get the DSGraph for this function and verify that it is ok.
///
bool DSGC::runOnFunction(Function &F) {
  switch (DSPass) {
  case local: verify(getAnalysis<LocalDataStructures>().getDSGraph(F)); break;
  case bu:    verify(getAnalysis<BUDataStructures>().getDSGraph(F)); break;
  case td:    verify(getAnalysis<TDDataStructures>().getDSGraph(F)); break;
  }

  return false;
}

/// verify - This is the function which checks to make sure that all of the
/// invariants established on the command line are true.
///
void DSGC::verify(const DSGraph &G) {
  // Loop over all of the nodes, checking to see if any are collapsed...
  if (AbortIfAnyCollapsed) {
    const std::vector<DSNode*> &Nodes = G.getNodes();
    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
      if (Nodes[i]->isNodeCompletelyFolded()) {
        std::cerr << "Node is collapsed: ";
        Nodes[i]->print(std::cerr, &G);
        abort();
      }
  }

  if (!AbortIfCollapsed.empty() || !CheckFlags.empty() ||
      !AbortIfMerged.empty()) {
    // Convert from a list to a set, because we don't have cl::set's yet.  FIXME
    std::set<std::string> AbortIfCollapsedS(AbortIfCollapsed.begin(),
                                            AbortIfCollapsed.end());
    std::set<std::string> AbortIfMergedS(AbortIfMerged.begin(),
                                         AbortIfMerged.end());
    std::map<std::string, unsigned> CheckFlagsM;

    for (cl::list<std::string>::iterator I = CheckFlags.begin(),
           E = CheckFlags.end(); I != E; ++I) {
      std::string::size_type ColonPos = I->rfind(':');
      if (ColonPos == std::string::npos) {
        std::cerr << "Error: '" << *I
               << "' is an invalid value for the --dsgc-check-flags option!\n";
        abort();
      }

      unsigned Flags = 0;
      for (unsigned C = ColonPos+1; C != I->size(); ++C)
        switch ((*I)[C]) {
        case 'S': Flags |= DSNode::AllocaNode;  break;
        case 'H': Flags |= DSNode::HeapNode;    break;
        case 'G': Flags |= DSNode::GlobalNode;  break;
        case 'U': Flags |= DSNode::UnknownNode; break;
        case 'I': Flags |= DSNode::Incomplete;  break;
        case 'M': Flags |= DSNode::Modified;    break;
        case 'R': Flags |= DSNode::Read;        break;
        case 'A': Flags |= DSNode::Array;       break;
        default: std::cerr << "Invalid DSNode flag!\n"; abort();
        }
      CheckFlagsM[std::string(I->begin(), I->begin()+ColonPos)] = Flags;
    }

    // Now we loop over all of the scalars, checking to see if any are collapsed
    // that are not supposed to be, or if any are merged together.
    const DSGraph::ScalarMapTy &SM = G.getScalarMap();
    std::map<DSNode*, std::string> AbortIfMergedNodes;

    for (DSGraph::ScalarMapTy::const_iterator I = SM.begin(), E = SM.end();
         I != E; ++I)
      if (I->first->hasName() && I->second.getNode()) {
        const std::string &Name = I->first->getName();
        DSNode *N = I->second.getNode();

        // Verify it is not collapsed if it is not supposed to be...
        if (N->isNodeCompletelyFolded() && AbortIfCollapsedS.count(Name)) {
          std::cerr << "Node for value '%" << Name << "' is collapsed: ";
          N->print(std::cerr, &G);
          abort();
        }

        if (CheckFlagsM.count(Name) && CheckFlagsM[Name] != N->getNodeFlags()) {
          std::cerr << "Node flags are not as expected for node: " << Name
                    << "\n";
          N->print(std::cerr, &G);
          abort();
        }

        // Verify that it is not merged if it is not supposed to be...
        if (AbortIfMergedS.count(Name)) {
          if (AbortIfMergedNodes.count(N)) {
            std::cerr << "Nodes for values '%" << Name << "' and '%"
                      << AbortIfMergedNodes[N] << "' is merged: ";
            N->print(std::cerr, &G);
            abort();
          }
          AbortIfMergedNodes[N] = Name;
        }
      }
  }
}
<|endoftext|>