<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "component.hxx"

#include "bridges/cpp_uno/shared/bridge.hxx"

#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "osl/time.h"
#include "rtl/process.h"
#include "rtl/unload.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "uno/environment.h"
#include "uno/lbnames.h"
#include "uno/mapping.h"
#include "cppu/EnvDcp.hxx"

namespace bridges { namespace cpp_uno { namespace shared {

rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

} } }

namespace {

#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__))
static ::rtl::OUString * s_pStaticOidPart = 0;
#endif

const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW(())
{
#if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__)))
    static ::rtl::OUString * s_pStaticOidPart = 0;
#endif
    if (! s_pStaticOidPart)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! s_pStaticOidPart)
        {
            ::rtl::OUStringBuffer aRet( 64 );
            aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
            // good guid
            sal_uInt8 ar[16];
            ::rtl_getGlobalProcessId( ar );
            for ( sal_Int32 i = 0; i < 16; ++i )
            {
                aRet.append( (sal_Int32)ar[i], 16 );
            }
#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__))
            s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() );
#else
            static ::rtl::OUString s_aStaticOidPart(
                aRet.makeStringAndClear() );
            s_pStaticOidPart = &s_aStaticOidPart;
#endif
        }
    }
    return *s_pStaticOidPart;
}

}

extern "C" {

static void s_stub_computeObjectIdentifier(va_list * pParam)
    SAL_THROW(())
{
    uno_ExtEnvironment  * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
    rtl_uString        ** ppOId      = va_arg(*pParam, rtl_uString **);
    void                * pInterface = va_arg(*pParam, void *);

    OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
    if (pEnv && ppOId && pInterface)
    {
        if (*ppOId)
        {
            rtl_uString_release( *ppOId );
            *ppOId = 0;
        }

        try
        {
            ::com::sun::star::uno::Reference<
                  ::com::sun::star::uno::XInterface > xHome(
                      reinterpret_cast< ::com::sun::star::uno::XInterface * >(
                          pInterface ),
                      ::com::sun::star::uno::UNO_QUERY );
            OSL_ENSURE( xHome.is(), "### query to XInterface failed!" );
            if (xHome.is())
            {
                // interface
                ::rtl::OUStringBuffer oid( 64 );
                oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 );
                oid.append( (sal_Unicode)';' );
                // ;environment[context]
                oid.append(
                    *reinterpret_cast< ::rtl::OUString const * >(
                        &((uno_Environment *) pEnv)->pTypeName ) );
                oid.append( (sal_Unicode)'[' );
                oid.append(
                    reinterpret_cast< sal_Int64 >(
                        ((uno_Environment *)pEnv)->pContext),
                    16 );
                // ];good guid
                oid.append( cppu_cppenv_getStaticOIdPart() );
                ::rtl::OUString aRet( oid.makeStringAndClear() );
                ::rtl_uString_acquire( *ppOId = aRet.pData );
            }
        }
        catch (const ::com::sun::star::uno::RuntimeException &)
        {
            OSL_FAIL(
                "### RuntimeException occurred during queryInterface()!" );
        }
    }
}

static void SAL_CALL computeObjectIdentifier(
    uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface);
}

static void s_stub_acquireInterface(va_list * pParam)
    SAL_THROW(())
{
    /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
    void               * pCppI   = va_arg(*pParam, void *);

    reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire();
}

static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI);
}

static void s_stub_releaseInterface(va_list * pParam)
    SAL_THROW(())
{
    /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
    void               * pCppI   = va_arg(*pParam, void *);

    reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release();
}

static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI);
}

static void SAL_CALL environmentDisposing(
    SAL_UNUSED_PARAMETER uno_Environment * ) SAL_THROW(())
{
    bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
        &bridges::cpp_uno::shared::g_moduleCount.modCnt );
}

#ifndef DISABLE_DYNLOADING

SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() {
    return bridges::cpp_uno::shared::g_moduleCount.canUnload(
        &bridges::cpp_uno::shared::g_moduleCount, pTime);
}

#endif

#ifdef DISABLE_DYNLOADING
#define uno_initEnvironment CPPU_ENV_uno_initEnvironment
#endif

void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv)
    SAL_THROW_EXTERN_C()
{
    OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" );
    OSL_ENSURE(
        ::rtl_ustr_ascii_compare_WithLength(
             pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME )
        == 0,
        "### wrong environment type!" );
    bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
        &bridges::cpp_uno::shared::g_moduleCount.modCnt );
    ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier
        = computeObjectIdentifier;
    ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface;
    ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface;
    pCppEnv->environmentDisposing = environmentDisposing;
}

#ifdef DISABLE_DYNLOADING
#define uno_ext_getMapping CPPU_ENV_uno_ext_getMapping
#endif

void SAL_CALL uno_ext_getMapping(
    uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo)
    SAL_THROW_EXTERN_C()
{
    OSL_ASSERT( ppMapping && pFrom && pTo );
    if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
    {
        uno_Mapping * pMapping = 0;

        rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName));
        rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName));

        if (0 == rtl_ustr_ascii_compare(
                from_envTypeName.pData->buffer,
                CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
            0 == rtl_ustr_ascii_compare(
                to_envTypeName.pData->buffer, UNO_LB_UNO ))
        {
            // ref count initially 1
            pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
                pFrom->pExtEnv, pTo->pExtEnv, sal_True );
            ::uno_registerMapping(
                &pMapping, bridges::cpp_uno::shared::freeMapping,
                (uno_Environment *)pFrom->pExtEnv,
                (uno_Environment *)pTo->pExtEnv, 0 );
        }
        else if (0 == rtl_ustr_ascii_compare(
                     to_envTypeName.pData->buffer,
                     CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
                 0 == rtl_ustr_ascii_compare(
                     from_envTypeName.pData->buffer, UNO_LB_UNO ))
        {
            // ref count initially 1
            pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
                pTo->pExtEnv, pFrom->pExtEnv, sal_False );
            ::uno_registerMapping(
                &pMapping, bridges::cpp_uno::shared::freeMapping,
                (uno_Environment *)pFrom->pExtEnv,
                (uno_Environment *)pTo->pExtEnv, 0 );
        }

        if (*ppMapping)
        {
            (*(*ppMapping)->release)( *ppMapping );
        }
        if (pMapping)
        *ppMapping = pMapping;
    }
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>add missing exports<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "component.hxx"

#include "bridges/cpp_uno/shared/bridge.hxx"

#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "osl/time.h"
#include "rtl/process.h"
#include "rtl/unload.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "uno/environment.h"
#include "uno/lbnames.h"
#include "uno/mapping.h"
#include "cppu/EnvDcp.hxx"

namespace bridges { namespace cpp_uno { namespace shared {

rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

} } }

namespace {

#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__))
static ::rtl::OUString * s_pStaticOidPart = 0;
#endif

const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW(())
{
#if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__)))
    static ::rtl::OUString * s_pStaticOidPart = 0;
#endif
    if (! s_pStaticOidPart)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! s_pStaticOidPart)
        {
            ::rtl::OUStringBuffer aRet( 64 );
            aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
            // good guid
            sal_uInt8 ar[16];
            ::rtl_getGlobalProcessId( ar );
            for ( sal_Int32 i = 0; i < 16; ++i )
            {
                aRet.append( (sal_Int32)ar[i], 16 );
            }
#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
    || (defined(__GNUC__) && defined(__APPLE__))
            s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() );
#else
            static ::rtl::OUString s_aStaticOidPart(
                aRet.makeStringAndClear() );
            s_pStaticOidPart = &s_aStaticOidPart;
#endif
        }
    }
    return *s_pStaticOidPart;
}

}

extern "C" {

static void s_stub_computeObjectIdentifier(va_list * pParam)
    SAL_THROW(())
{
    uno_ExtEnvironment  * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
    rtl_uString        ** ppOId      = va_arg(*pParam, rtl_uString **);
    void                * pInterface = va_arg(*pParam, void *);

    OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
    if (pEnv && ppOId && pInterface)
    {
        if (*ppOId)
        {
            rtl_uString_release( *ppOId );
            *ppOId = 0;
        }

        try
        {
            ::com::sun::star::uno::Reference<
                  ::com::sun::star::uno::XInterface > xHome(
                      reinterpret_cast< ::com::sun::star::uno::XInterface * >(
                          pInterface ),
                      ::com::sun::star::uno::UNO_QUERY );
            OSL_ENSURE( xHome.is(), "### query to XInterface failed!" );
            if (xHome.is())
            {
                // interface
                ::rtl::OUStringBuffer oid( 64 );
                oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 );
                oid.append( (sal_Unicode)';' );
                // ;environment[context]
                oid.append(
                    *reinterpret_cast< ::rtl::OUString const * >(
                        &((uno_Environment *) pEnv)->pTypeName ) );
                oid.append( (sal_Unicode)'[' );
                oid.append(
                    reinterpret_cast< sal_Int64 >(
                        ((uno_Environment *)pEnv)->pContext),
                    16 );
                // ];good guid
                oid.append( cppu_cppenv_getStaticOIdPart() );
                ::rtl::OUString aRet( oid.makeStringAndClear() );
                ::rtl_uString_acquire( *ppOId = aRet.pData );
            }
        }
        catch (const ::com::sun::star::uno::RuntimeException &)
        {
            OSL_FAIL(
                "### RuntimeException occurred during queryInterface()!" );
        }
    }
}

static void SAL_CALL computeObjectIdentifier(
    uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface);
}

static void s_stub_acquireInterface(va_list * pParam)
    SAL_THROW(())
{
    /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
    void               * pCppI   = va_arg(*pParam, void *);

    reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire();
}

static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI);
}

static void s_stub_releaseInterface(va_list * pParam)
    SAL_THROW(())
{
    /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
    void               * pCppI   = va_arg(*pParam, void *);

    reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release();
}

static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
    SAL_THROW(())
{
    uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI);
}

static void SAL_CALL environmentDisposing(
    SAL_UNUSED_PARAMETER uno_Environment * ) SAL_THROW(())
{
    bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
        &bridges::cpp_uno::shared::g_moduleCount.modCnt );
}

#ifndef DISABLE_DYNLOADING

SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() {
    return bridges::cpp_uno::shared::g_moduleCount.canUnload(
        &bridges::cpp_uno::shared::g_moduleCount, pTime);
}

#endif

#ifdef DISABLE_DYNLOADING
#define uno_initEnvironment CPPU_ENV_uno_initEnvironment
#endif

SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv)
    SAL_THROW_EXTERN_C()
{
    OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" );
    OSL_ENSURE(
        ::rtl_ustr_ascii_compare_WithLength(
             pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME )
        == 0,
        "### wrong environment type!" );
    bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
        &bridges::cpp_uno::shared::g_moduleCount.modCnt );
    ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier
        = computeObjectIdentifier;
    ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface;
    ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface;
    pCppEnv->environmentDisposing = environmentDisposing;
}

#ifdef DISABLE_DYNLOADING
#define uno_ext_getMapping CPPU_ENV_uno_ext_getMapping
#endif

SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_ext_getMapping(
    uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo)
    SAL_THROW_EXTERN_C()
{
    OSL_ASSERT( ppMapping && pFrom && pTo );
    if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
    {
        uno_Mapping * pMapping = 0;

        rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName));
        rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName));

        if (0 == rtl_ustr_ascii_compare(
                from_envTypeName.pData->buffer,
                CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
            0 == rtl_ustr_ascii_compare(
                to_envTypeName.pData->buffer, UNO_LB_UNO ))
        {
            // ref count initially 1
            pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
                pFrom->pExtEnv, pTo->pExtEnv, sal_True );
            ::uno_registerMapping(
                &pMapping, bridges::cpp_uno::shared::freeMapping,
                (uno_Environment *)pFrom->pExtEnv,
                (uno_Environment *)pTo->pExtEnv, 0 );
        }
        else if (0 == rtl_ustr_ascii_compare(
                     to_envTypeName.pData->buffer,
                     CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
                 0 == rtl_ustr_ascii_compare(
                     from_envTypeName.pData->buffer, UNO_LB_UNO ))
        {
            // ref count initially 1
            pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
                pTo->pExtEnv, pFrom->pExtEnv, sal_False );
            ::uno_registerMapping(
                &pMapping, bridges::cpp_uno::shared::freeMapping,
                (uno_Environment *)pFrom->pExtEnv,
                (uno_Environment *)pTo->pExtEnv, 0 );
        }

        if (*ppMapping)
        {
            (*(*ppMapping)->release)( *ppMapping );
        }
        if (pMapping)
        *ppMapping = pMapping;
    }
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * + Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * + Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ARRAY_HH
#define ARRAY_HH

#include <vector>
#include <stdexcept>

#include "genericops.hh"

template <unsigned n, typename T>
class Array : public Equality<Array<n,T> >
{
public:
  Array() {}

  // Array can be explicitly constructed from a scalar, but no corresponding
  // assignment operator is defined -- because derived classes have different
  // behavior when assigned a scalar.
  explicit Array(const T &x)
  {
    for (int i = 0; i < n; ++i)
      data[i] = x;
  }

  // A "conversion constructor" for explicitly turning arrays of one type
  // into another as long as the sizes are the same and the element type
  // is (explicitly or implicitly) convertible.
  // This is more type-safe than a conversion operator, which can't be
  // made explicit.
  template <typename U>
  explicit Array(const Array<n,U> &xs)
  {
    for (unsigned i=0; i<n; ++i)
      data[i] = T(xs[i]);
  }

  // Similarly, a function for (explicitly) converting an array into an
  // STL vector
  std::vector<T> toVector() const
  {
    std::vector<T> r;
    for (int i = 0; i < n; ++i)
      r.push_back(data[i]);
    return r;
  }

  T &operator[](unsigned i)
  {
    check_index(i);
    return data[i];
  }
  const T &operator[](unsigned i) const
  {
    check_index(i);
    return data[i];
  }

  bool operator==(const Array<n,T> &rhs) const
  {
    for (int i = 0; i < n; ++i)
      if (data[i] != rhs.data[i])
        return false;
    return true;
  }

protected:
  T &unsafe_element(unsigned i)
  {
    return data[i];
  }
  const T &unsafe_element(unsigned i) const
  {
    return data[i];
  }

private:
  T data[n];

  void check_index(unsigned i) const
  {
    if (i >= n)
      throw_array_range_exception();
  }
  void throw_array_range_exception() const;
};

template <unsigned n, typename T>
void Array<n,T>::throw_array_range_exception() const
{
  throw std::range_error("Array<> index out of range");
}

#endif
<commit_msg>Avoid signed vs unsigned comparison warning<commit_after>/*
 * This file is part of the Electron Orbital Explorer. The Electron
 * Orbital Explorer is distributed under the Simplified BSD License
 * (also called the "BSD 2-Clause License"), in hopes that these
 * rendering techniques might be used by other programmers in
 * applications such as scientific visualization, video gaming, and so
 * on. If you find value in this software and use its technologies for
 * another purpose, I would love to hear back from you at bjthinks (at)
 * gmail (dot) com. If you improve this software and agree to release
 * your modifications under the below license, I encourage you to fork
 * the development tree on github and push your modifications. The
 * Electron Orbital Explorer's development URL is:
 * https://github.com/bjthinks/orbital-explorer
 * (This paragraph is not part of the software license and may be
 * removed.)
 *
 * Copyright (c) 2013, Brian W. Johnson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * + Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * + Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ARRAY_HH
#define ARRAY_HH

#include <vector>
#include <stdexcept>

#include "genericops.hh"

template <unsigned n, typename T>
class Array : public Equality<Array<n,T> >
{
public:
  Array() {}

  // Array can be explicitly constructed from a scalar, but no corresponding
  // assignment operator is defined -- because derived classes have different
  // behavior when assigned a scalar.
  explicit Array(const T &x)
  {
    for (unsigned i = 0; i < n; ++i)
      data[i] = x;
  }

  // A "conversion constructor" for explicitly turning arrays of one type
  // into another as long as the sizes are the same and the element type
  // is (explicitly or implicitly) convertible.
  // This is more type-safe than a conversion operator, which can't be
  // made explicit.
  template <typename U>
  explicit Array(const Array<n,U> &xs)
  {
    for (unsigned i=0; i<n; ++i)
      data[i] = T(xs[i]);
  }

  // Similarly, a function for (explicitly) converting an array into an
  // STL vector
  std::vector<T> toVector() const
  {
    std::vector<T> r;
    for (int i = 0; i < n; ++i)
      r.push_back(data[i]);
    return r;
  }

  T &operator[](unsigned i)
  {
    check_index(i);
    return data[i];
  }
  const T &operator[](unsigned i) const
  {
    check_index(i);
    return data[i];
  }

  bool operator==(const Array<n,T> &rhs) const
  {
    for (int i = 0; i < n; ++i)
      if (data[i] != rhs.data[i])
        return false;
    return true;
  }

protected:
  T &unsafe_element(unsigned i)
  {
    return data[i];
  }
  const T &unsafe_element(unsigned i) const
  {
    return data[i];
  }

private:
  T data[n];

  void check_index(unsigned i) const
  {
    if (i >= n)
      throw_array_range_exception();
  }
  void throw_array_range_exception() const;
};

template <unsigned n, typename T>
void Array<n,T>::throw_array_range_exception() const
{
  throw std::range_error("Array<> index out of range");
}

#endif
<|endoftext|>


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

#include <memory>
#include <unordered_map>

#include <folly/AtomicLinkedList.h>
#include <folly/ThreadLocal.h>
#include <folly/Synchronized.h>

namespace folly { namespace fibers {

namespace {

class EventBaseOnDestructionCallback : public EventBase::LoopCallback {
 public:
  explicit EventBaseOnDestructionCallback(EventBase& evb) : evb_(evb) {}
  void runLoopCallback() noexcept override;

 private:
  EventBase& evb_;
};

class GlobalCache {
 public:
  static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
    return instance().getImpl(evb, opts);
  }

  static std::unique_ptr<FiberManager> erase(EventBase& evb) {
    return instance().eraseImpl(evb);
  }

 private:
  GlobalCache() {}

  // Leak this intentionally. During shutdown, we may call getFiberManager,
  // and want access to the fiber managers during that time.
  static GlobalCache& instance() {
    static auto ret = new GlobalCache();
    return *ret;
  }

  FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
    std::lock_guard<std::mutex> lg(mutex_);

    auto& fmPtrRef = map_[&evb];

    if (!fmPtrRef) {
      auto loopController = make_unique<EventBaseLoopController>();
      loopController->attachEventBase(evb);
      evb.runOnDestruction(new EventBaseOnDestructionCallback(evb));

      fmPtrRef = make_unique<FiberManager>(std::move(loopController), opts);
    }

    return *fmPtrRef;
  }

  std::unique_ptr<FiberManager> eraseImpl(EventBase& evb) {
    std::lock_guard<std::mutex> lg(mutex_);

    DCHECK_EQ(1, map_.count(&evb));

    auto ret = std::move(map_[&evb]);
    map_.erase(&evb);
    return ret;
  }

  std::mutex mutex_;
  std::unordered_map<EventBase*, std::unique_ptr<FiberManager>> map_;
};

constexpr size_t kEraseListMaxSize = 64;

class ThreadLocalCache {
 public:
  static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
    return instance()->getImpl(evb, opts);
  }

  static void erase(EventBase& evb) {
    for (auto& localInstance : instance().accessAllThreads()) {
      SYNCHRONIZED(info, localInstance.eraseInfo_) {
        if (info.eraseList.size() >= kEraseListMaxSize) {
          info.eraseAll = true;
        } else {
          info.eraseList.push_back(&evb);
        }
        localInstance.eraseRequested_ = true;
      }
    }
  }

 private:
  ThreadLocalCache() {}

  struct ThreadLocalCacheTag {};
  using ThreadThreadLocalCache = ThreadLocal<ThreadLocalCache, ThreadLocalCacheTag>;

  // Leak this intentionally. During shutdown, we may call getFiberManager,
  // and want access to the fiber managers during that time.
  static ThreadThreadLocalCache& instance() {
    static auto ret = new ThreadThreadLocalCache([]() { return new ThreadLocalCache(); });
    return *ret;
  }

  FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
    eraseImpl();

    auto& fmPtrRef = map_[&evb];
    if (!fmPtrRef) {
      fmPtrRef = &GlobalCache::get(evb, opts);
    }

    DCHECK(fmPtrRef != nullptr);

    return *fmPtrRef;
  }

  void eraseImpl() {
    if (!eraseRequested_.load()) {
      return;
    }

    SYNCHRONIZED(info, eraseInfo_) {
      if (info.eraseAll) {
        map_.clear();
      } else {
        for (auto evbPtr : info.eraseList) {
          map_.erase(evbPtr);
        }
      }

      info.eraseList.clear();
      info.eraseAll = false;
      eraseRequested_ = false;
    }
  }

  std::unordered_map<EventBase*, FiberManager*> map_;
  std::atomic<bool> eraseRequested_{false};

  struct EraseInfo {
    bool eraseAll{false};
    std::vector<EventBase*> eraseList;
  };

  folly::Synchronized<EraseInfo> eraseInfo_;
};

void EventBaseOnDestructionCallback::runLoopCallback() noexcept {
  auto fm = GlobalCache::erase(evb_);
  DCHECK(fm.get() != nullptr);
  ThreadLocalCache::erase(evb_);

  fm->loopUntilNoReady();

  delete this;
}

} // namespace

FiberManager& getFiberManager(EventBase& evb,
                              const FiberManager::Options& opts) {
  return ThreadLocalCache::get(evb, opts);
}

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

#include <memory>
#include <unordered_map>

#include <folly/AtomicLinkedList.h>
#include <folly/ThreadLocal.h>
#include <folly/Synchronized.h>

namespace folly { namespace fibers {

namespace {

class EventBaseOnDestructionCallback : public EventBase::LoopCallback {
 public:
  explicit EventBaseOnDestructionCallback(EventBase& evb) : evb_(evb) {}
  void runLoopCallback() noexcept override;

 private:
  EventBase& evb_;
};

class GlobalCache {
 public:
  static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
    return instance().getImpl(evb, opts);
  }

  static std::unique_ptr<FiberManager> erase(EventBase& evb) {
    return instance().eraseImpl(evb);
  }

 private:
  GlobalCache() {}

  // Leak this intentionally. During shutdown, we may call getFiberManager,
  // and want access to the fiber managers during that time.
  static GlobalCache& instance() {
    static auto ret = new GlobalCache();
    return *ret;
  }

  FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
    std::lock_guard<std::mutex> lg(mutex_);

    auto& fmPtrRef = map_[&evb];

    if (!fmPtrRef) {
      auto loopController = make_unique<EventBaseLoopController>();
      loopController->attachEventBase(evb);
      evb.runOnDestruction(new EventBaseOnDestructionCallback(evb));

      fmPtrRef = make_unique<FiberManager>(std::move(loopController), opts);
    }

    return *fmPtrRef;
  }

  std::unique_ptr<FiberManager> eraseImpl(EventBase& evb) {
    std::lock_guard<std::mutex> lg(mutex_);

    DCHECK_EQ(1, map_.count(&evb));

    auto ret = std::move(map_[&evb]);
    map_.erase(&evb);
    return ret;
  }

  std::mutex mutex_;
  std::unordered_map<EventBase*, std::unique_ptr<FiberManager>> map_;
};

constexpr size_t kEraseListMaxSize = 64;

class ThreadLocalCache {
 public:
  static FiberManager& get(EventBase& evb, const FiberManager::Options& opts) {
    return instance()->getImpl(evb, opts);
  }

  static void erase(EventBase& evb) {
    for (auto& localInstance : instance().accessAllThreads()) {
      SYNCHRONIZED(info, localInstance.eraseInfo_) {
        if (info.eraseList.size() >= kEraseListMaxSize) {
          info.eraseAll = true;
        } else {
          info.eraseList.push_back(&evb);
        }
        localInstance.eraseRequested_ = true;
      }
    }
  }

 private:
  ThreadLocalCache() {}

  struct ThreadLocalCacheTag {};
  using ThreadThreadLocalCache = ThreadLocal<ThreadLocalCache, ThreadLocalCacheTag>;

  // Leak this intentionally. During shutdown, we may call getFiberManager,
  // and want access to the fiber managers during that time.
  static ThreadThreadLocalCache& instance() {
    static auto ret = new ThreadThreadLocalCache([]() { return new ThreadLocalCache(); });
    return *ret;
  }

  FiberManager& getImpl(EventBase& evb, const FiberManager::Options& opts) {
    eraseImpl();

    auto& fmPtrRef = map_[&evb];
    if (!fmPtrRef) {
      fmPtrRef = &GlobalCache::get(evb, opts);
    }

    DCHECK(fmPtrRef != nullptr);

    return *fmPtrRef;
  }

  void eraseImpl() {
    if (!eraseRequested_.load()) {
      return;
    }

    SYNCHRONIZED(info, eraseInfo_) {
      if (info.eraseAll) {
        map_.clear();
      } else {
        for (auto evbPtr : info.eraseList) {
          map_.erase(evbPtr);
        }
      }

      info.eraseList.clear();
      info.eraseAll = false;
      eraseRequested_ = false;
    }
  }

  std::unordered_map<EventBase*, FiberManager*> map_;
  std::atomic<bool> eraseRequested_{false};

  struct EraseInfo {
    bool eraseAll{false};
    std::vector<EventBase*> eraseList;
  };

  folly::Synchronized<EraseInfo> eraseInfo_;
};

void EventBaseOnDestructionCallback::runLoopCallback() noexcept {
  auto fm = GlobalCache::erase(evb_);
  DCHECK(fm.get() != nullptr);
  ThreadLocalCache::erase(evb_);

  while (fm->hasTasks()) {
    evb_.loopOnce();
  }

  delete this;
}

} // namespace

FiberManager& getFiberManager(EventBase& evb,
                              const FiberManager::Options& opts) {
  return ThreadLocalCache::get(evb, opts);
}

}}
<|endoftext|>


<commit_before>#include "ReplayView.hpp"

#include "../Game/Replay.hpp"
#include "../Game/ParseError.hpp"
#include "../Game/GameReader.hpp"
#include "../Game/Players/Placeholder.hpp"

#include "../../app/FourInALine.hpp"
#include "../Settings/Sound.hpp"
#include "../Settings/View.hpp"
#include "../Settings/FourInALine.hpp"

#include "FileIO.hpp"

#include <QMessageBox>
#include <QWidget>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
#include <QBuffer>

namespace GUI
{

/**
 * Creates a new replay view.
 *
 * @param manager View manager to use.
 */
ReplayView::ReplayView(ViewManager* manager)
    : AbstractView(manager), currentMoveNo(0)
{
	auto settings = ::FourInALine::getInstance()->getSettings();
	auto viewSettings = settings->getViewSettings();

	this->widget = new Widgets::Board(viewSettings->getTheme(), 0);

	this->updateThemeConnection = this->connect(viewSettings, &Settings::View::changed, [=]() {
		this->widget->setTheme(viewSettings->getTheme());
	});

	auto application = ::FourInALine::getInstance();
	auto soundSettings = application->getSettings()->getSoundSettings();

	this->connect(soundSettings, &::Settings::Sound::changed, this, &ReplayView::updateSoundSettings);
	this->updateSoundSettings();
}

/**
 * Frees all used resources.
 */
ReplayView::~ReplayView()
{
	QObject::disconnect(this->updateThemeConnection);
}

/**
 * Returns the central widget of this view.
 *
 * @return Widget for the view.
 */
QWidget* ReplayView::getWidget() const
{
	return this->widget;
}

/**
 * Returns whether there is a replay loaded or not.
 *
 * @return When a replay is loaded true, otherwise false.
 */
bool ReplayView::hasReplay() const
{
	return !this->replay.isNull();
}

/**
 * Returns whether the currently loaded replay has a next move or not.
 *
 * Returns false when no replay is loaded.
 *
 * @return When there is a next move true, otherwise false.
 */
bool ReplayView::hasNextMove() const
{
	if (this->hasReplay())
	{
		return this->currentMoveNo + 1 < this->replay->getNumberOfMoves();
	}

	return false;
}

/**
 * Returns whether the currently loaded replay has a previous move or not.
 *
 * Returns false when no replay is loaded.
 *
 * @return When there is a previous move true, otherwise false.
 */
bool ReplayView::hasPreviousMove() const
{
	if (this->hasReplay())
	{
		return this->currentMoveNo > 0;
	}

	return false;
}

/**
 * Does nothing and returns true.
 *
 * This method is called by the view manager before deactivating the view.
 *
 * @return When the view should be deactivated true, otherwise false.
 */
bool ReplayView::confirmDeactivation()
{
	return true;
}

/**
 * Shows a dialog asking the user to open a replay file, then opens the file and loads the replay.
 */
void ReplayView::loadReplay()
{
	QByteArray content;
	QString fileName;
	QString nameFilter = tr("Replays (*.replay)");

	if (FileIO::GetExistingFileName(this->getWidget(), fileName, nameFilter) &&
	    FileIO::GetFileContent(this->getWidget(), fileName, content) &&
	    this->requestActivation())
	{
		try
		{
			QBuffer buffer(&content);
			buffer.open(QIODevice::ReadOnly);
			::Game::GameReader reader;
			auto loadedReplay = reader.readReplay(&buffer);

			if (loadedReplay->getNumberOfMoves() == 0)
			{
				throw ::Game::ParseError("Empty replays are not supported.");
			}

			this->closeReplay();
			this->replay = loadedReplay;
			this->currentMoveNo = 0;
			this->jumpToStart();

			emit this->stateChanged();
		}
		catch (const ::Game::ParseError& error)
		{
			QMessageBox::critical(this->getWidget(), tr("Failed to load replay"),
			                      tr("Failed to load replay due to parse error: %1").arg(error.what()));
		}
	}
}

/**
 * Closes the currently open replay.
 *
 * Does nothing if no replay is opened.
 */
void ReplayView::closeReplay()
{
	if (this->hasReplay())
	{
		this->replay.reset();
		this->currentMoveNo = 0;

		emit this->stateChanged();
	}
}

/**
 * Step to the next move.
 */
void ReplayView::nextMove()
{
	if (this->hasNextMove())
	{
		this->currentMoveNo++;

		auto currentMove = this->replay->getMove(this->currentMoveNo);
		auto position = this->replay->computeMovePosition(this->currentMoveNo);
		auto player = this->playerIdToPlayer(currentMove.first);

		this->widget->startPlayerTurn(player);
		this->widget->makeMove(position.first, position.second, player);
		this->widget->endPlayerTurn();

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Step to the previous move.
 */
void ReplayView::previousMove()
{
	if (this->hasPreviousMove())
	{
		auto position = this->replay->computeMovePosition(this->currentMoveNo);

		this->widget->makeCellEmpty(position.first, position.second);

		this->currentMoveNo--;

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Jump to the start of the replay.
 */
void ReplayView::jumpToStart()
{
	if (this->hasReplay())
	{
		this->widget->startNewGame(this->replay->getNumberOfColumns(),
		                           this->replay->getNumberOfRows(),
		                           this->replay->getFirstPlayer(),
		                           this->replay->getSecondPlayer(),
		                           false);

		this->currentMoveNo = 0;

		auto currentMove = this->replay->getMove(this->currentMoveNo);
		auto position = this->replay->computeMovePosition(this->currentMoveNo);
		auto player = this->playerIdToPlayer(currentMove.first);

		this->widget->startPlayerTurn(player);
		this->widget->makeMove(position.first, position.second, player);
		this->widget->endPlayerTurn();

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Jump to the end of the replay.
 */
void ReplayView::jumpToEnd()
{
	while (this->hasNextMove())
	{
		this->nextMove();
	}
}

/**
 * Sets highlighted state for all cells.
 *
 * This method will set the winning cells to highlighted and all other cells
 * to not highlighted.
 */
void ReplayView::highlightCells()
{
	auto board = this->replay->computeBoard(this->currentMoveNo);
	auto winningCells = board.findWinningCells();

	for (unsigned int y = 0; y < board.getNumberOfRows(); ++y)
	{
		for (unsigned int x = 0; x < board.getNumberOfColumns(); ++x)
		{
			this->widget->setCellHighlighted(x, y, false);
		}
	}

	if (!winningCells.isEmpty())
	{
		for (auto i = winningCells.begin(); i != winningCells.end(); i++)
		{
			this->widget->setCellHighlighted(i.getXPosition(), i.getYPosition(), true);
		}
	}
}

/**
 * Returns the placeholder player for the given player id.
 *
 * @param playerId Player id as used in the game engine.
 * @return Placeholder player with the given id.
 */
QSharedPointer< ::Game::Players::Placeholder> ReplayView::playerIdToPlayer(::GameLogic::FourInALine::Game::PlayerType playerId) const
{
	if (playerId == ::GameLogic::FourInALine::Game::PLAYER_ONE)
	{
		return this->replay->getFirstPlayer();
	}
	else
	{
		return this->replay->getSecondPlayer();
	}
}

/**
 * Reads sound settings from sound settings and updates game board.
 */
void ReplayView::updateSoundSettings()
{
	auto application = ::FourInALine::getInstance();
	auto soundSettings = application->getSettings()->getSoundSettings();

	this->widget->setSoundMuted(!soundSettings->isSoundEnabled());
	this->widget->setSoundVolume(soundSettings->getVolume());
}

}
<commit_msg>Added missing delete.<commit_after>#include "ReplayView.hpp"

#include "../Game/Replay.hpp"
#include "../Game/ParseError.hpp"
#include "../Game/GameReader.hpp"
#include "../Game/Players/Placeholder.hpp"

#include "../../app/FourInALine.hpp"
#include "../Settings/Sound.hpp"
#include "../Settings/View.hpp"
#include "../Settings/FourInALine.hpp"

#include "FileIO.hpp"

#include <QMessageBox>
#include <QWidget>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
#include <QBuffer>

namespace GUI
{

/**
 * Creates a new replay view.
 *
 * @param manager View manager to use.
 */
ReplayView::ReplayView(ViewManager* manager)
    : AbstractView(manager), currentMoveNo(0)
{
	auto settings = ::FourInALine::getInstance()->getSettings();
	auto viewSettings = settings->getViewSettings();

	this->widget = new Widgets::Board(viewSettings->getTheme(), 0);

	this->updateThemeConnection = this->connect(viewSettings, &Settings::View::changed, [=]() {
		this->widget->setTheme(viewSettings->getTheme());
	});

	auto application = ::FourInALine::getInstance();
	auto soundSettings = application->getSettings()->getSoundSettings();

	this->connect(soundSettings, &::Settings::Sound::changed, this, &ReplayView::updateSoundSettings);
	this->updateSoundSettings();
}

/**
 * Frees all used resources.
 */
ReplayView::~ReplayView()
{
	QObject::disconnect(this->updateThemeConnection);
	delete this->widget;
}

/**
 * Returns the central widget of this view.
 *
 * @return Widget for the view.
 */
QWidget* ReplayView::getWidget() const
{
	return this->widget;
}

/**
 * Returns whether there is a replay loaded or not.
 *
 * @return When a replay is loaded true, otherwise false.
 */
bool ReplayView::hasReplay() const
{
	return !this->replay.isNull();
}

/**
 * Returns whether the currently loaded replay has a next move or not.
 *
 * Returns false when no replay is loaded.
 *
 * @return When there is a next move true, otherwise false.
 */
bool ReplayView::hasNextMove() const
{
	if (this->hasReplay())
	{
		return this->currentMoveNo + 1 < this->replay->getNumberOfMoves();
	}

	return false;
}

/**
 * Returns whether the currently loaded replay has a previous move or not.
 *
 * Returns false when no replay is loaded.
 *
 * @return When there is a previous move true, otherwise false.
 */
bool ReplayView::hasPreviousMove() const
{
	if (this->hasReplay())
	{
		return this->currentMoveNo > 0;
	}

	return false;
}

/**
 * Does nothing and returns true.
 *
 * This method is called by the view manager before deactivating the view.
 *
 * @return When the view should be deactivated true, otherwise false.
 */
bool ReplayView::confirmDeactivation()
{
	return true;
}

/**
 * Shows a dialog asking the user to open a replay file, then opens the file and loads the replay.
 */
void ReplayView::loadReplay()
{
	QByteArray content;
	QString fileName;
	QString nameFilter = tr("Replays (*.replay)");

	if (FileIO::GetExistingFileName(this->getWidget(), fileName, nameFilter) &&
	    FileIO::GetFileContent(this->getWidget(), fileName, content) &&
	    this->requestActivation())
	{
		try
		{
			QBuffer buffer(&content);
			buffer.open(QIODevice::ReadOnly);
			::Game::GameReader reader;
			auto loadedReplay = reader.readReplay(&buffer);

			if (loadedReplay->getNumberOfMoves() == 0)
			{
				throw ::Game::ParseError("Empty replays are not supported.");
			}

			this->closeReplay();
			this->replay = loadedReplay;
			this->currentMoveNo = 0;
			this->jumpToStart();

			emit this->stateChanged();
		}
		catch (const ::Game::ParseError& error)
		{
			QMessageBox::critical(this->getWidget(), tr("Failed to load replay"),
			                      tr("Failed to load replay due to parse error: %1").arg(error.what()));
		}
	}
}

/**
 * Closes the currently open replay.
 *
 * Does nothing if no replay is opened.
 */
void ReplayView::closeReplay()
{
	if (this->hasReplay())
	{
		this->replay.reset();
		this->currentMoveNo = 0;

		emit this->stateChanged();
	}
}

/**
 * Step to the next move.
 */
void ReplayView::nextMove()
{
	if (this->hasNextMove())
	{
		this->currentMoveNo++;

		auto currentMove = this->replay->getMove(this->currentMoveNo);
		auto position = this->replay->computeMovePosition(this->currentMoveNo);
		auto player = this->playerIdToPlayer(currentMove.first);

		this->widget->startPlayerTurn(player);
		this->widget->makeMove(position.first, position.second, player);
		this->widget->endPlayerTurn();

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Step to the previous move.
 */
void ReplayView::previousMove()
{
	if (this->hasPreviousMove())
	{
		auto position = this->replay->computeMovePosition(this->currentMoveNo);

		this->widget->makeCellEmpty(position.first, position.second);

		this->currentMoveNo--;

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Jump to the start of the replay.
 */
void ReplayView::jumpToStart()
{
	if (this->hasReplay())
	{
		this->widget->startNewGame(this->replay->getNumberOfColumns(),
		                           this->replay->getNumberOfRows(),
		                           this->replay->getFirstPlayer(),
		                           this->replay->getSecondPlayer(),
		                           false);

		this->currentMoveNo = 0;

		auto currentMove = this->replay->getMove(this->currentMoveNo);
		auto position = this->replay->computeMovePosition(this->currentMoveNo);
		auto player = this->playerIdToPlayer(currentMove.first);

		this->widget->startPlayerTurn(player);
		this->widget->makeMove(position.first, position.second, player);
		this->widget->endPlayerTurn();

		this->highlightCells();

		emit this->stateChanged();
	}
}

/**
 * Jump to the end of the replay.
 */
void ReplayView::jumpToEnd()
{
	while (this->hasNextMove())
	{
		this->nextMove();
	}
}

/**
 * Sets highlighted state for all cells.
 *
 * This method will set the winning cells to highlighted and all other cells
 * to not highlighted.
 */
void ReplayView::highlightCells()
{
	auto board = this->replay->computeBoard(this->currentMoveNo);
	auto winningCells = board.findWinningCells();

	for (unsigned int y = 0; y < board.getNumberOfRows(); ++y)
	{
		for (unsigned int x = 0; x < board.getNumberOfColumns(); ++x)
		{
			this->widget->setCellHighlighted(x, y, false);
		}
	}

	if (!winningCells.isEmpty())
	{
		for (auto i = winningCells.begin(); i != winningCells.end(); i++)
		{
			this->widget->setCellHighlighted(i.getXPosition(), i.getYPosition(), true);
		}
	}
}

/**
 * Returns the placeholder player for the given player id.
 *
 * @param playerId Player id as used in the game engine.
 * @return Placeholder player with the given id.
 */
QSharedPointer< ::Game::Players::Placeholder> ReplayView::playerIdToPlayer(::GameLogic::FourInALine::Game::PlayerType playerId) const
{
	if (playerId == ::GameLogic::FourInALine::Game::PLAYER_ONE)
	{
		return this->replay->getFirstPlayer();
	}
	else
	{
		return this->replay->getSecondPlayer();
	}
}

/**
 * Reads sound settings from sound settings and updates game board.
 */
void ReplayView::updateSoundSettings()
{
	auto application = ::FourInALine::getInstance();
	auto soundSettings = application->getSettings()->getSoundSettings();

	this->widget->setSoundMuted(!soundSettings->isSoundEnabled());
	this->widget->setSoundVolume(soundSettings->getVolume());
}

}
<|endoftext|>


<commit_before>
#include "Globals.h"
#include "FireworksSerializer.h"
#include "WorldStorage/FastNBT.h"

void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type)
{
	switch (a_Type)
	{
		case E_ITEM_FIREWORK_ROCKET:
		{
			a_Writer.BeginCompound("Fireworks");
			a_Writer.AddByte("Flight", a_FireworkItem.m_FlightTimeInTicks / 20);
			a_Writer.BeginList("Explosions", TAG_Compound);
			a_Writer.BeginCompound("");
			a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker);
			a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail);
			a_Writer.AddByte("Type", a_FireworkItem.m_Type);
			a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size());
			a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size());
			a_Writer.EndCompound();
			a_Writer.EndList();
			a_Writer.EndCompound();
			break;
		}
		case E_ITEM_FIREWORK_STAR:
		{
			a_Writer.BeginCompound("Explosion");
			a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker);
			a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail);
			a_Writer.AddByte("Type", a_FireworkItem.m_Type);
			if (!a_FireworkItem.m_Colours.empty())
			{
				a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size());
			}
			if (!a_FireworkItem.m_FadeColours.empty())
			{
				a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size());
			}
			a_Writer.EndCompound();
			break;
		}
		default: ASSERT(!"Unhandled firework item!"); break;
	}
}

void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type)
{
	if (a_TagIdx < 0)
	{
		return;
	}

	switch (a_Type)
	{
		case E_ITEM_FIREWORK_STAR:
		{
			for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag))
			{
				eTagType TagType = a_NBT.GetType(explosiontag);
				if (TagType == TAG_Byte) // Custon name tag
				{
					AString ExplosionName = a_NBT.GetName(explosiontag);

					if (ExplosionName == "Flicker")
					{
						a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1);
					}
					else if (ExplosionName == "Trail")
					{
						a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1);
					}
					else if (ExplosionName == "Type")
					{
						a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag);
					}
				}
				else if (TagType == TAG_IntArray)
				{
					AString ExplosionName = a_NBT.GetName(explosiontag);

					if (ExplosionName == "Colors")
					{
						// Divide by four as data length returned in bytes
						int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
						if (DataLength == 0)
						{
							continue;
						}

						const int * ColourData = (const int *)(a_NBT.GetData(explosiontag));
						for (int i = 0; i < DataLength; i++)
						{
							a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i]));
						}
					}
					else if (ExplosionName == "FadeColors")
					{
						int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
						if (DataLength == 0)
						{
							continue;
						}

						const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag));
						for (int i = 0; i < DataLength; i++)
						{
							a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i]));
						}
					}
				}
			}
			break;
		}
		case E_ITEM_FIREWORK_ROCKET:
		{
			for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag))
			{
				eTagType TagType = a_NBT.GetType(fireworkstag);
				if (TagType == TAG_Byte) // Custon name tag
				{
					if (a_NBT.GetName(fireworkstag) == "Flight")
					{
						a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20;
					}
				}
				else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions"))
				{
					int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag);
					if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty()))
					{
						ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR);
					}
				}
			}
			break;
		}
		default: ASSERT(!"Unhandled firework item!"); break;
	}
}

AString cFireworkItem::ColoursToString(const cFireworkItem & a_FireworkItem)
{
	AString Result;

	for (std::vector<int>::const_iterator itr = a_FireworkItem.m_Colours.begin(); itr != a_FireworkItem.m_Colours.end(); ++itr)
	{
		AppendPrintf(Result, "%i;", *itr);
	}

	return Result;
}

void cFireworkItem::ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem)
{
	AStringVector Split = StringSplit(a_String, ";");

	for (size_t itr = 0; itr < Split.size(); ++itr)
	{
		if (Split[itr].empty())
		{
			continue;
		}

		a_FireworkItem.m_Colours.push_back(atoi(Split[itr].c_str()));
	}
}

AString cFireworkItem::FadeColoursToString(const cFireworkItem & a_FireworkItem)
{
	AString Result;

	for (std::vector<int>::const_iterator itr = a_FireworkItem.m_FadeColours.begin(); itr != a_FireworkItem.m_FadeColours.end(); ++itr)
	{
		AppendPrintf(Result, "%i;", *itr);
	}

	return Result;
}

void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem)
{
	AStringVector Split = StringSplit(a_String, ";");

	for (size_t itr = 0; itr < Split.size(); ++itr)
	{
		if (Split[itr].empty())
		{
			continue;
		}

		a_FireworkItem.m_FadeColours.push_back(atoi(Split[itr].c_str()));
	}
}

int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta)
{
	/*
	Colours are supposed to be calculated via: R << 16 + G << 8 + B
	However, the RGB values fireworks use aren't the same as the ones for dyes (the ones listed in the MC Wiki)
	Therefore, here is a list of numbers gotten via the Protocol Proxy
	*/

	switch (a_DyeMeta)
	{
		case E_META_DYE_BLACK: return 0x1E1B1B;
		case E_META_DYE_RED: return 0xB3312C;
		case E_META_DYE_GREEN: return 0x3B511A;
		case E_META_DYE_BROWN:  return 0x51301A;
		case E_META_DYE_BLUE: return 0x253192;
		case E_META_DYE_PURPLE: return 0x7B2FBE;
		case E_META_DYE_CYAN: return 0x287697;
		case E_META_DYE_LIGHTGRAY: return 0xABABAB;
		case E_META_DYE_GRAY: return 0x434343;
		case E_META_DYE_PINK: return 0xD88198;
		case E_META_DYE_LIGHTGREEN: return 0x41CD34;
		case E_META_DYE_YELLOW: return 0xDECF2A;
		case E_META_DYE_LIGHTBLUE: return 0x6689D3;
		case E_META_DYE_MAGENTA: return 0xC354CD;
		case E_META_DYE_ORANGE: return 0xEB8844;
		case E_META_DYE_WHITE: return 0xF0F0F0;
		default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0;
	}
}
<commit_msg>Fixed MSVC2008 compilation.<commit_after>
#include "Globals.h"
#include "FireworksSerializer.h"
#include "WorldStorage/FastNBT.h"

void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type)
{
	switch (a_Type)
	{
		case E_ITEM_FIREWORK_ROCKET:
		{
			a_Writer.BeginCompound("Fireworks");
			a_Writer.AddByte("Flight", a_FireworkItem.m_FlightTimeInTicks / 20);
			a_Writer.BeginList("Explosions", TAG_Compound);
			a_Writer.BeginCompound("");
			a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker);
			a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail);
			a_Writer.AddByte("Type", a_FireworkItem.m_Type);
			a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size());
			a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size());
			a_Writer.EndCompound();
			a_Writer.EndList();
			a_Writer.EndCompound();
			break;
		}
		case E_ITEM_FIREWORK_STAR:
		{
			a_Writer.BeginCompound("Explosion");
			a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker);
			a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail);
			a_Writer.AddByte("Type", a_FireworkItem.m_Type);
			if (!a_FireworkItem.m_Colours.empty())
			{
				a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size());
			}
			if (!a_FireworkItem.m_FadeColours.empty())
			{
				a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size());
			}
			a_Writer.EndCompound();
			break;
		}
		default: ASSERT(!"Unhandled firework item!"); break;
	}
}

void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type)
{
	if (a_TagIdx < 0)
	{
		return;
	}

	switch (a_Type)
	{
		case E_ITEM_FIREWORK_STAR:
		{
			for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag))
			{
				eTagType TagType = a_NBT.GetType(explosiontag);
				if (TagType == TAG_Byte) // Custon name tag
				{
					AString ExplosionName = a_NBT.GetName(explosiontag);

					if (ExplosionName == "Flicker")
					{
						a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1);
					}
					else if (ExplosionName == "Trail")
					{
						a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1);
					}
					else if (ExplosionName == "Type")
					{
						a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag);
					}
				}
				else if (TagType == TAG_IntArray)
				{
					AString ExplosionName = a_NBT.GetName(explosiontag);

					if (ExplosionName == "Colors")
					{
						// Divide by four as data length returned in bytes
						int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
						if (DataLength == 0)
						{
							continue;
						}

						const int * ColourData = (const int *)(a_NBT.GetData(explosiontag));
						for (int i = 0; i < DataLength; i++)
						{
							a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i]));
						}
					}
					else if (ExplosionName == "FadeColors")
					{
						int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
						if (DataLength == 0)
						{
							continue;
						}

						const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag));
						for (int i = 0; i < DataLength; i++)
						{
							a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i]));
						}
					}
				}
			}
			break;
		}
		case E_ITEM_FIREWORK_ROCKET:
		{
			for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag))
			{
				eTagType TagType = a_NBT.GetType(fireworkstag);
				if (TagType == TAG_Byte) // Custon name tag
				{
					if (a_NBT.GetName(fireworkstag) == "Flight")
					{
						a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20;
					}
				}
				else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions"))
				{
					int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag);
					if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty()))
					{
						ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR);
					}
				}
			}
			break;
		}
		default: ASSERT(!"Unhandled firework item!"); break;
	}
}

AString cFireworkItem::ColoursToString(const cFireworkItem & a_FireworkItem)
{
	AString Result;

	for (std::vector<int>::const_iterator itr = a_FireworkItem.m_Colours.begin(); itr != a_FireworkItem.m_Colours.end(); ++itr)
	{
		AppendPrintf(Result, "%i;", *itr);
	}

	return Result;
}

void cFireworkItem::ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem)
{
	AStringVector Split = StringSplit(a_String, ";");

	for (size_t itr = 0; itr < Split.size(); ++itr)
	{
		if (Split[itr].empty())
		{
			continue;
		}

		a_FireworkItem.m_Colours.push_back(atoi(Split[itr].c_str()));
	}
}

AString cFireworkItem::FadeColoursToString(const cFireworkItem & a_FireworkItem)
{
	AString Result;

	for (std::vector<int>::const_iterator itr = a_FireworkItem.m_FadeColours.begin(); itr != a_FireworkItem.m_FadeColours.end(); ++itr)
	{
		AppendPrintf(Result, "%i;", *itr);
	}

	return Result;
}

void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem)
{
	AStringVector Split = StringSplit(a_String, ";");

	for (size_t itr = 0; itr < Split.size(); ++itr)
	{
		if (Split[itr].empty())
		{
			continue;
		}

		a_FireworkItem.m_FadeColours.push_back(atoi(Split[itr].c_str()));
	}
}

int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta)
{
	/*
	Colours are supposed to be calculated via: R << 16 + G << 8 + B
	However, the RGB values fireworks use aren't the same as the ones for dyes (the ones listed in the MC Wiki)
	Therefore, here is a list of numbers gotten via the Protocol Proxy
	*/

	switch (a_DyeMeta)
	{
		case E_META_DYE_BLACK: return 0x1E1B1B;
		case E_META_DYE_RED: return 0xB3312C;
		case E_META_DYE_GREEN: return 0x3B511A;
		case E_META_DYE_BROWN:  return 0x51301A;
		case E_META_DYE_BLUE: return 0x253192;
		case E_META_DYE_PURPLE: return 0x7B2FBE;
		case E_META_DYE_CYAN: return 0x287697;
		case E_META_DYE_LIGHTGRAY: return 0xABABAB;
		case E_META_DYE_GRAY: return 0x434343;
		case E_META_DYE_PINK: return 0xD88198;
		case E_META_DYE_LIGHTGREEN: return 0x41CD34;
		case E_META_DYE_YELLOW: return 0xDECF2A;
		case E_META_DYE_LIGHTBLUE: return 0x6689D3;
		case E_META_DYE_MAGENTA: return 0xC354CD;
		case E_META_DYE_ORANGE: return 0xEB8844;
		case E_META_DYE_WHITE: return 0xF0F0F0;
		default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0;
	}
}
<|endoftext|>


<commit_before>#include "scenemanager.hpp"

#include <chrono>
#include <thread>
#include <mutex>
#include <typeinfo>

#include "glload/gl_3_2.h"
#include <GL/glfw.h>

#include "scenegroup.hpp"
#include "perspectivecamera.hpp"

#include "render/lightmanager.hpp"

#include "collisiondetection/collidable.hpp"
#include "collisiondetection/objectorientedboundingbox.hpp"

#include "config/globals.hpp"

using namespace scene;

SceneManager::SceneManager()
: world(3, collisiondetection::AABB(std::make_tuple(glm::vec3(-10.0f, -10.0f, 10.0f), glm::vec3(10.0f, 10.0f, -50.0f)))),
running(false){
}

void SceneManager::startSceneLoop() {
	scene::PerspectiveCamera& camera = scene::PerspectiveCamera::getInstance();

	running = true;

	std::thread updateThread([this, &camera]() {
		while(running) {
			universalGravity.update();

			world.visitScene([](std::shared_ptr<SceneItem> child) {
				child->update();

				child->buildModelMatrix();
			});

			world.visitGroups([](SceneGroup& group) {
				for (std::shared_ptr<SceneItem>& child : group.childItems) {
					auto collidable = std::dynamic_pointer_cast<collisiondetection::Collidable>(child);

					if(collidable.get() != nullptr) {
						for (std::shared_ptr<SceneItem>& other : group.childItems) {
							if(other != child) {
								//TODO Collidables should always have a copy of their bounds

								const collisiondetection::BoundingVolume& collidableBounds = child->getBounds();
								collidableBounds.attachToItem(child.get());

								const collisiondetection::BoundingVolume& otherBounds = other->getBounds();
								otherBounds.attachToItem(other.get());

								if(collidableBounds.intersects(otherBounds)) {
									collidable->handleCollision(*other);
								}
							}
						}

						if(group.childGroups != nullptr) {
							//Check underlying groups for edge cases
							for(SceneGroup& childGroup : *group.childGroups) {
								for (std::shared_ptr<SceneItem>& other : childGroup.childItems) {
									if(other != child) {
										//TODO Collidables should always have a copy of their bounds

										const collisiondetection::BoundingVolume& collidableBounds = child->getBounds();
										collidableBounds.attachToItem(child.get());

										const collisiondetection::BoundingVolume& otherBounds = other->getBounds();
										otherBounds.attachToItem(other.get());

										if(collidableBounds.intersects(otherBounds)) {
											collidable->handleCollision(*other);
										}
									}
								}
							}
						}
					}
				}
			});

			world.visitGroups([](SceneGroup& group) {
				if(group.constraints != nullptr) {
					auto it = group.childItems.begin();
					while(it != group.childItems.end()) {
						const collisiondetection::BoundingVolume& otherBounds = (*it)->getBounds();
						otherBounds.attachToItem((*it).get());

						if(!otherBounds.intersects(*(group.constraints))) {
							std::lock_guard<std::recursive_mutex> guard(group.rootNode->sceneMutex);

							group.rootNode->bubbleItem(*it);
							it = group.childItems.erase(it);
						} else {
							++it;
						}
					}
				}
			});

			std::this_thread::sleep_for(std::chrono::milliseconds((unsigned int)(1.0f/config::globals::updateRate)*1000));
		}
	});

	while(running) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

		render::LightManager::getInstance().upload();
		camera.render(&world);

		glfwSwapBuffers();

		std::this_thread::sleep_for(std::chrono::milliseconds((unsigned int)(1.0f/config::globals::frameRate)*1000));
	}

	updateThread.join();
}

void SceneManager::stopSceneLoop() {
	running = false;
}

void SceneManager::addItem(std::shared_ptr<SceneItem> item) {
	GravitationalObject* gravObject = dynamic_cast<GravitationalObject*>(item.get());
	if(gravObject != nullptr) {
		universalGravity.addObject(gravObject);
	}

	std::lock_guard<std::recursive_mutex> guard(world.rootNode->sceneMutex);
	world.bubbleItem(item);
}
<commit_msg>Broad phase collisions: Check parents for edge cases<commit_after>#include "scenemanager.hpp"

#include <chrono>
#include <thread>
#include <mutex>
#include <typeinfo>

#include "glload/gl_3_2.h"
#include <GL/glfw.h>

#include "scenegroup.hpp"
#include "perspectivecamera.hpp"

#include "render/lightmanager.hpp"

#include "collisiondetection/collidable.hpp"
#include "collisiondetection/objectorientedboundingbox.hpp"

#include "config/globals.hpp"

using namespace scene;

SceneManager::SceneManager()
: world(3, collisiondetection::AABB(std::make_tuple(glm::vec3(-10.0f, -10.0f, 10.0f), glm::vec3(10.0f, 10.0f, -50.0f)))),
running(false){
}

void SceneManager::startSceneLoop() {
	scene::PerspectiveCamera& camera = scene::PerspectiveCamera::getInstance();

	running = true;

	std::thread updateThread([this, &camera]() {
		while(running) {
			universalGravity.update();

			world.visitScene([](std::shared_ptr<SceneItem> child) {
				child->update();

				child->buildModelMatrix();
			});

			world.visitGroups([](SceneGroup& group) {
				for (std::shared_ptr<SceneItem>& child : group.childItems) {
					auto collidable = std::dynamic_pointer_cast<collisiondetection::Collidable>(child);

					if(collidable.get() != nullptr) {
						std::function<void(const SceneGroup&)> collisionCheck = [collidable, child](const SceneGroup& group) {
							for(const std::shared_ptr<SceneItem>& other : group.childItems) {
								//TODO Collidables should always have a copy of their bounds

								const collisiondetection::BoundingVolume& collidableBounds = child->getBounds();
								collidableBounds.attachToItem(child.get());

								const collisiondetection::BoundingVolume& otherBounds = other->getBounds();
								otherBounds.attachToItem(other.get());

								if(collidableBounds.intersects(otherBounds)) {
									collidable->handleCollision(*other);
								}
							}
						};

						collisionCheck(group);

						if(group.childGroups != nullptr) {
							//Check underlying groups for lower edge cases
							for(SceneGroup& childGroup : *group.childGroups) {
								collisionCheck(childGroup);
							}
						}

						//Check with parents for upper edge cases
						group.visitParentGroups(collisionCheck);
					}
				}
			});

			world.visitGroups([](SceneGroup& group) {
				if(group.constraints != nullptr) {
					auto it = group.childItems.begin();
					while(it != group.childItems.end()) {
						const collisiondetection::BoundingVolume& otherBounds = (*it)->getBounds();
						otherBounds.attachToItem((*it).get());

						if(!otherBounds.intersects(*(group.constraints))) {
							std::lock_guard<std::recursive_mutex> guard(group.rootNode->sceneMutex);

							group.rootNode->bubbleItem(*it);
							it = group.childItems.erase(it);
						} else {
							++it;
						}
					}
				}
			});

			std::this_thread::sleep_for(std::chrono::milliseconds((unsigned int)(1.0f/config::globals::updateRate)*1000));
		}
	});

	while(running) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

		render::LightManager::getInstance().upload();
		camera.render(&world);

		glfwSwapBuffers();

		std::this_thread::sleep_for(std::chrono::milliseconds((unsigned int)(1.0f/config::globals::frameRate)*1000));
	}

	updateThread.join();
}

void SceneManager::stopSceneLoop() {
	running = false;
}

void SceneManager::addItem(std::shared_ptr<SceneItem> item) {
	GravitationalObject* gravObject = dynamic_cast<GravitationalObject*>(item.get());
	if(gravObject != nullptr) {
		universalGravity.addObject(gravObject);
	}

	std::lock_guard<std::recursive_mutex> guard(world.rootNode->sceneMutex);
	world.bubbleItem(item);
}
<|endoftext|>


<commit_before><commit_msg>beginning work on pointers<commit_after>/************************************************************
COSC 501
Elliott Plack
19 NOV 2013                                   Due 25 NOV 2013
Problem: Create a 1-dimensional array with n elements; get
the size of the array as user input (validate!), max size
should be 10 (declared as class constant). Perform a
variety of functions with the array.
Algorithm: Get array size from user, validate, get values,
perform functions.
************************************************************/

#include <iostream>
using namespace std;

int main()
{
char runQuestion = 'Y';
int arraySize = 0;
const int maxArraySize = 10;

cout << "Do you want to start(Y/N): ";
cin >> runQuestion;

while (runQuestion == 'Y' || runQuestion == 'y')
{
	// declare array with pointers
	struct node
	{
		double data;
		node *next;
	};

	node *q = new node;
	node *head;
	head = q;
	q->data = maxArraySize;    // assume the list contains 10 numbers

	// fill array
	for (int i = 0; i < maxArraySize; i++)
	{
		node *p = new node;
		while (!(cin >> p->data)) // error check
		{
			cin.clear();     // Clear the error flags
			cin.ignore(100, '\n');    // Remove unwanted characters from buffer
			cout << "\aInvalid entry. Enter a number: ";   // Re-issue the prompt
		}
		q->next = p;
		q = p;

		}

	// print
	cout << "The array elements are: ";

	for (int i = 0; i < arraySize; i++)
	{
	cout << q->data;
	q = q->next;
	}

	cout << "Do you want to continue(Y/N): ";
	cin >> runQuestion;
	}

	return 0;
}
<|endoftext|>


<commit_before>//
// Platform-independent Ogg Vorbis/Theora/Opus decoder/player base
//
// Copyright (c) 2013-2015 Brion Vibber <brion@pobox.com>
// MIT-style license
// Please reuse and redistribute with the LICENSE notes intact.
//

// C++11
#include <string>
#include <iostream>
#include <cmath>

// good ol' C library
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

// And our own headers.
#include <OGVCore.h>
#include "Bisector.h"

namespace OGVCore {

#pragma mark - Declarations

    class Player::impl {
    public:

        impl(std::shared_ptr<Player::Delegate> aDelegate);
        ~impl();

        void load();
        void process();

        double getDuration();
        double getVideoWidth();
        double getVideoHeight();

        std::string getSourceURL();
        void setSourceURL(std::string aUrl);

        double getCurrentTime();
        void setCurrentTime(double aTime);

        bool getPaused();
        void setPaused(bool aPaused);

        bool getPlaying();
        bool getSeeking();

    private:
        std::shared_ptr<Player::Delegate> delegate;
        std::shared_ptr<Timer> timer;
        std::shared_ptr<FrameSink> frameSink;
        std::shared_ptr<AudioFeeder> audioFeeder;

        std::shared_ptr<StreamFile> stream;
        long byteLength;
        double duration;

        class StreamDelegate : public StreamFile::Delegate {
        public:
            Player::impl *owner;

            StreamDelegate(Player::impl *aOwner) :
                owner(aOwner)
            {}

            virtual void onStart()
            {
                // Fire off the read/decode/draw loop...
                owner->byteLength = owner->stream->bytesTotal();

                // If we get X-Content-Duration, that's as good as an explicit hint
                auto durationHeader = owner->stream->getResponseHeader("X-Content-Duration");
                if (durationHeader.length() > 0) {
                    owner->duration = std::atof(durationHeader.c_str());
                }
                owner->startProcessingVideo();
            }

            virtual void onBuffer()
            {}

            virtual void onRead(std::vector<unsigned char> data)
            {
                // Pass chunk into the codec's buffer
                owner->codec->receiveInput(data);

                // Continue the read/decode/draw loop...
                owner->pingProcessing();
            }

            virtual void onDone()
            {
                if (owner->state == STATE_SEEKING) {
                    owner->pingProcessing();
                } else if (owner->state == STATE_SEEKING_END) {
                    owner->pingProcessing();
                } else {
                    //throw new Error('wtf is this');
                    owner->stream.reset();

                    // Let the read/decode/draw loop know we're out!
                    owner->pingProcessing();
                }
            }

            virtual void onError(std::string err)
            {
                std::cout << "reading error: " << err;
            }
        };

        enum {
            STATE_INITIAL,
            STATE_SEEKING_END,
            STATE_LOADED,
            STATE_PLAYING,
            STATE_PAUSED,
            STATE_SEEKING,
            STATE_ENDED
        } state = STATE_INITIAL;

        std::unique_ptr<Decoder> codec;

        double lastFrameTimestamp = 0.0;
        double frameEndTimestamp = 0.0;
        std::shared_ptr<FrameBuffer> yCbCrBuffer = NULL;

        void processFrame();
        void drawFrame();
        void doFrameComplete();

        bool started = false;

        // Seeking
        enum {
            SEEKSTATE_NOT_SEEKING,
            SEEKSTATE_BISECT_TO_TARGET,
            SEEKSTATE_BISECT_TO_KEYPOINT,
            SEEKSTATE_LINEAR_TO_TARGET
        } seekState = SEEKSTATE_NOT_SEEKING;

        double seekTargetTime = 0.0;
        double seekTargetKeypoint = 0.0;
        double bisectTargetTime = 0.0;
        long lastSeekPosition = 0.0;
        bool lastFrameSkipped;
        std::unique_ptr<Bisector> seekBisector;

        void startBisection(double targetTime);
        void seek(double toTime);
        void continueSeekedPlayback();
        void doProcessLinearSeeking();
        void doProcessBisectionSeek();

        // Main stuff!
        void doProcessing();
        void pingProcessing(double delay = -1.0);
        void startProcessingVideo();
    };

#pragma mark - Player pimpl bounce methods

    Player::Player(std::shared_ptr<Player::Delegate> aDelegate):
        pimpl(new impl(aDelegate))
    {}

    Player::~Player()
    {}

    void Player::load()
    {
        pimpl->load();
    }

    void Player::process()
    {
        pimpl->process();
    }

    double Player::getDuration()
    {
        return pimpl->getDuration();
    }

    double Player::getVideoWidth()
    {
        return pimpl->getVideoWidth();
    }

    double Player::getVideoHeight()
    {
        return pimpl->getVideoHeight();
    }

    std::string Player::getSourceURL()
    {
        return pimpl->getSourceURL();
    }

    void Player::setSourceURL(std::string aUrl)
    {
        pimpl->setSourceURL(aUrl);
    }

    double Player::getCurrentTime()
    {
        return pimpl->getCurrentTime();
    }

    void Player::setCurrentTime(double aTime)
    {
        pimpl->setCurrentTime(aTime);
    }

    bool Player::getPaused()
    {
        return pimpl->getPaused();
    }

    void Player::setPaused(bool aPaused)
    {
        return pimpl->setPaused(aPaused);
    }

    bool Player::getPlaying()
    {
        return pimpl->getPlaying();
    }

    bool Player::getSeeking()
    {
        return pimpl->getSeeking();
    }

#pragma mark - impl methods

    Player::impl::impl(std::shared_ptr<Player::Delegate> aDelegate):
        delegate(aDelegate),
        timer(delegate->timer())
    {
    }

    Player::impl::~impl()
    {
    }

    void Player::impl::load()
    {
        if (stream.get() != NULL) {
			// already loaded.
			return;
        }

		started = false;
		stream = delegate->streamFile(getSourceURL(), std::shared_ptr<StreamFile::Delegate>(new StreamDelegate(this)));
	}

    void Player::impl::process()
    {
        // TODO
    }

    double Player::impl::getDuration()
    {
        return NAN; // TODO
    }

    double Player::impl::getVideoWidth()
    {
        return NAN; // TODO
    }

    double Player::impl::getVideoHeight()
    {
        return NAN; // TODO
    }

    std::string Player::impl::getSourceURL()
    {
        return NULL;
    }

    void Player::impl::setSourceURL(std::string aUrl)
    {
        // TODO
    }

    double Player::impl::getCurrentTime()
    {
        return NAN; // TODO
    }

    void Player::impl::setCurrentTime(double aTime)
    {
        // TODO
    }

    bool Player::impl::getPaused()
    {
        return false; // TODO
    }

    void Player::impl::setPaused(bool aPaused)
    {
        // TODO
    }

    bool Player::impl::getPlaying()
    {
        return false; // TODO
    }

    bool Player::impl::getSeeking()
    {
        return false; // TODO
    }

    void Player::impl::processFrame()
    {
        yCbCrBuffer = codec->dequeueFrame();
        frameEndTimestamp = yCbCrBuffer->timestamp;
    }

    void Player::impl::drawFrame()
    {
        frameSink->drawFrame(yCbCrBuffer);
        doFrameComplete();
    }

    void Player::impl::doFrameComplete()
    {
        lastFrameTimestamp = timer->getTimestamp();
    }

    void Player::impl::startBisection(double targetTime)
    {
		bisectTargetTime = targetTime;
		seekBisector.reset(new Bisector(
			/* start */ 0,
			/* end */ byteLength - 1,
			/* process */ [this] (int start, int end, int position) {
				if (position == lastSeekPosition) {
					return false;
				} else {
					lastSeekPosition = position;
					lastFrameSkipped = false;
					codec->flush();
					stream->seek(position);
					stream->readBytes();
					return true;
				}
			}
		));
		seekBisector->start();
    }

    void Player::impl::seek(double toTime)
    {
    }

    void Player::impl::continueSeekedPlayback()
    {
    }

    void Player::impl::doProcessLinearSeeking()
    {
    }

    void Player::impl::doProcessBisectionSeek()
    {
    }

    void Player::impl::doProcessing()
    {
    }

    void Player::impl::pingProcessing(double delay)
    {
    }

    void Player::impl::startProcessingVideo()
    {
    }

}
<commit_msg>hey this is nicer<commit_after>//
// Platform-independent Ogg Vorbis/Theora/Opus decoder/player base
//
// Copyright (c) 2013-2015 Brion Vibber <brion@pobox.com>
// MIT-style license
// Please reuse and redistribute with the LICENSE notes intact.
//

// C++11
#include <string>
#include <iostream>
#include <cmath>

// good ol' C library
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

// And our own headers.
#include <OGVCore.h>
#include "Bisector.h"

namespace OGVCore {

#pragma mark - Declarations

    class Player::impl {
    public:

        impl(std::shared_ptr<Player::Delegate> aDelegate) :
            delegate(aDelegate),
            timer(delegate->timer())
        {}

        ~impl()
        {}

        void load()
        {
            if (stream.get() != NULL) {
                // already loaded.
                return;
            }

            started = false;
            stream = delegate->streamFile(getSourceURL(), std::shared_ptr<StreamFile::Delegate>(new StreamDelegate(this)));
        }

        void process()
        {
            // TODO
        }

        double getDuration()
        {
            return NAN; // TODO
        }

        double getVideoWidth()
        {
            return NAN; // TODO
        }

        double getVideoHeight()
        {
            return NAN; // TODO
        }

        std::string getSourceURL()
        {
            return NULL; // TODO
        }

        void setSourceURL(std::string aUrl)
        {
        }

        double getCurrentTime()
        {
            return NAN; // TODO
        }

        void setCurrentTime(double aTime)
        {
            // TODO
        }

        bool getPaused()
        {
            return false; // TODO
        }
        void setPaused(bool aPaused)
        {
            // TODO
        }

        bool getPlaying()
        {
            return false; // TODO
        }

        bool getSeeking()
        {
            return false; // TODO
        }

    private:
        std::shared_ptr<Player::Delegate> delegate;
        std::shared_ptr<Timer> timer;
        std::shared_ptr<FrameSink> frameSink;
        std::shared_ptr<AudioFeeder> audioFeeder;

        std::shared_ptr<StreamFile> stream;
        long byteLength;
        double duration;

        class StreamDelegate : public StreamFile::Delegate {
        public:
            Player::impl *owner;

            StreamDelegate(Player::impl *aOwner) :
                owner(aOwner)
            {}

            virtual void onStart()
            {
                // Fire off the read/decode/draw loop...
                owner->byteLength = owner->stream->bytesTotal();

                // If we get X-Content-Duration, that's as good as an explicit hint
                auto durationHeader = owner->stream->getResponseHeader("X-Content-Duration");
                if (durationHeader.length() > 0) {
                    owner->duration = std::atof(durationHeader.c_str());
                }
                owner->startProcessingVideo();
            }

            virtual void onBuffer()
            {}

            virtual void onRead(std::vector<unsigned char> data)
            {
                // Pass chunk into the codec's buffer
                owner->codec->receiveInput(data);

                // Continue the read/decode/draw loop...
                owner->pingProcessing();
            }

            virtual void onDone()
            {
                if (owner->state == STATE_SEEKING) {
                    owner->pingProcessing();
                } else if (owner->state == STATE_SEEKING_END) {
                    owner->pingProcessing();
                } else {
                    //throw new Error('wtf is this');
                    owner->stream.reset();

                    // Let the read/decode/draw loop know we're out!
                    owner->pingProcessing();
                }
            }

            virtual void onError(std::string err)
            {
                std::cout << "reading error: " << err;
            }
        };

        enum {
            STATE_INITIAL,
            STATE_SEEKING_END,
            STATE_LOADED,
            STATE_PLAYING,
            STATE_PAUSED,
            STATE_SEEKING,
            STATE_ENDED
        } state = STATE_INITIAL;

        std::unique_ptr<Decoder> codec;

        bool started = false;
        double lastFrameTimestamp = 0.0;
        double frameEndTimestamp = 0.0;
        std::shared_ptr<FrameBuffer> yCbCrBuffer = NULL;

        void processFrame()
        {
            yCbCrBuffer = codec->dequeueFrame();
            frameEndTimestamp = yCbCrBuffer->timestamp;
        }

        void drawFrame()
        {
            frameSink->drawFrame(yCbCrBuffer);
            doFrameComplete();
        }

        void doFrameComplete()
        {
            lastFrameTimestamp = timer->getTimestamp();
        }

        // Seeking
        enum {
            SEEKSTATE_NOT_SEEKING,
            SEEKSTATE_BISECT_TO_TARGET,
            SEEKSTATE_BISECT_TO_KEYPOINT,
            SEEKSTATE_LINEAR_TO_TARGET
        } seekState = SEEKSTATE_NOT_SEEKING;

        double seekTargetTime = 0.0;
        double seekTargetKeypoint = 0.0;
        double bisectTargetTime = 0.0;
        long lastSeekPosition = 0.0;
        bool lastFrameSkipped;
        std::unique_ptr<Bisector> seekBisector;

        void startBisection(double targetTime)
        {
            bisectTargetTime = targetTime;
            seekBisector.reset(new Bisector(
                /* start */ 0,
                /* end */ byteLength - 1,
                /* process */ [this] (int start, int end, int position) {
                    if (position == lastSeekPosition) {
                        return false;
                    } else {
                        lastSeekPosition = position;
                        lastFrameSkipped = false;
                        codec->flush();
                        stream->seek(position);
                        stream->readBytes();
                        return true;
                    }
                }
            ));
            seekBisector->start();
        }

        void seek(double toTime);
        void continueSeekedPlayback();
        void doProcessLinearSeeking();
        void doProcessBisectionSeek();

        // Main stuff!
        void doProcessing()
        {
            // TODO
        }

        void pingProcessing(double delay = -1.0)
        {
            // TODO
        }

        void startProcessingVideo()
        {
            // TODO
        }
    };

#pragma mark - Player pimpl bounce methods

    Player::Player(std::shared_ptr<Player::Delegate> aDelegate):
        pimpl(new impl(aDelegate))
    {}

    Player::~Player()
    {}

    void Player::load()
    {
        pimpl->load();
    }

    void Player::process()
    {
        pimpl->process();
    }

    double Player::getDuration()
    {
        return pimpl->getDuration();
    }

    double Player::getVideoWidth()
    {
        return pimpl->getVideoWidth();
    }

    double Player::getVideoHeight()
    {
        return pimpl->getVideoHeight();
    }

    std::string Player::getSourceURL()
    {
        return pimpl->getSourceURL();
    }

    void Player::setSourceURL(std::string aUrl)
    {
        pimpl->setSourceURL(aUrl);
    }

    double Player::getCurrentTime()
    {
        return pimpl->getCurrentTime();
    }

    void Player::setCurrentTime(double aTime)
    {
        pimpl->setCurrentTime(aTime);
    }

    bool Player::getPaused()
    {
        return pimpl->getPaused();
    }

    void Player::setPaused(bool aPaused)
    {
        return pimpl->setPaused(aPaused);
    }

    bool Player::getPlaying()
    {
        return pimpl->getPlaying();
    }

    bool Player::getSeeking()
    {
        return pimpl->getSeeking();
    }

}
<|endoftext|>