<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#include "../../Characters/ToString.h"
#include "../../Containers/Bijection.h"
#include "../../Containers/Sequence.h"
#include "../../Debug/Assertions.h"
#include "../../Execution/Exceptions.h"
#include "../../Execution/Thread.h"
#include "../../Execution/WaitForIOReady.h"

#include "ConnectionOrientedMasterSocket.h"

#include "Listener.h"

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::IO::Network;
using namespace Stroika::Foundation::Traversal;

/*
 ********************************************************************************
 ************************* IO::Network::Listener::Rep_ **************************
 ********************************************************************************
 */
struct Listener::Rep_ {
    Rep_ (const Iterable<SocketAddress>& addrs, const Socket::BindFlags& bindFlags, unsigned int backlog, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor)
        : fNewConnectionAcceptor (newConnectionAcceptor)
    {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace (L"Listener::Rep_::CTOR (addres=%s, ...)", Characters::ToString (addrs).c_str ());
#endif
        for (auto addr : addrs) {
            ConnectionOrientedMasterSocket::Ptr ms = ConnectionOrientedMasterSocket::New (addr.GetAddressFamily (), Socket::STREAM);
            ms.Bind (addr, bindFlags); // do in CTOR so throw propagated
            ms.Listen (backlog);
            fMasterSockets += ms;
        }
        fListenThread = Execution::Thread::New ([this]() {
            Containers::Bijection<ConnectionOrientedMasterSocket::Ptr, WaitForIOReady::FileDescriptorType> socket2FDBijection;
            for (auto&& s : fMasterSockets) {
                socket2FDBijection.Add (s, s.GetNativeSocket ());
            }
            //Execution::WaitForIOReady sockSetPoller { fMasterSockets.Select<Execution::WaitForIOReady::FileDescriptorType> ([] (Socket i) { return i.GetNativeSocket (); }) };
            Execution::WaitForIOReady sockSetPoller{socket2FDBijection.Image ()};
            while (true) {
                try {
                    for (auto readyFD : sockSetPoller.WaitQuietly ().Value ()) {
                        ConnectionOrientedMasterSocket::Ptr localSocketToAcceptOn = *socket2FDBijection.InverseLookup (readyFD);
                        ConnectionOrientedSocket::Ptr       s                     = localSocketToAcceptOn.Accept ();
                        fNewConnectionAcceptor (s);
                    }
                }
                catch (const Execution::Thread::AbortException&) {
                    Execution::ReThrow ();
                }
                catch (...) {
                    // unclear what todo with expcetions here
                    // probnably ignore all but for theradabort.
                    // may need virtual fucntions to handle? Or std::function passed in?
                    DbgTrace (L"Exception accepting new connection: %s - ignored", Characters::ToString (current_exception ()).c_str ());
                }
            }
        });
        fListenThread.SetThreadName (L"Socket Listener"); // @todo include sockaddr 'pretty print' in name?
        fListenThread.Start ();
    }
    ~Rep_ ()
    {
        // critical we wait for finish of thread cuz it has bare 'this' pointer captured
        Thread::SuppressInterruptionInContext suppressInterruption;
        IgnoreExceptionsForCall (fListenThread.AbortAndWaitForDone ());
    }

    function<void(const ConnectionOrientedSocket::Ptr& newConnection)> fNewConnectionAcceptor;
    Sequence<ConnectionOrientedMasterSocket::Ptr>                      fMasterSockets;
    Execution::Thread::Ptr                                             fListenThread;
};

/*
********************************************************************************
**************************** IO::Network::Listener *****************************
********************************************************************************
*/
Listener::Listener (const SocketAddress& addr, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (Sequence<SocketAddress>{addr}, Socket::BindFlags{}, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const SocketAddress& addr, const Socket::BindFlags& bindFlags, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (Sequence<SocketAddress>{addr}, bindFlags, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const Traversal::Iterable<SocketAddress>& addrs, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (addrs, Socket::BindFlags{}, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const Traversal::Iterable<SocketAddress>& addrs, const Socket::BindFlags& bindFlags, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : fRep_ (make_shared<Rep_> (addrs, bindFlags, backlog, newConnectionAcceptor))
{
}

Listener::Listener (const Listener&& rhs)
    : fRep_ (move (rhs.fRep_))
{
}
<commit_msg>Cleanups to IO/Network/Listener use of threads (minor/mostly cosmetic)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#include "../../Characters/ToString.h"
#include "../../Containers/Bijection.h"
#include "../../Containers/Sequence.h"
#include "../../Debug/Assertions.h"
#include "../../Execution/Exceptions.h"
#include "../../Execution/Thread.h"
#include "../../Execution/WaitForIOReady.h"

#include "ConnectionOrientedMasterSocket.h"

#include "Listener.h"

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::IO::Network;
using namespace Stroika::Foundation::Traversal;

/*
 ********************************************************************************
 ************************* IO::Network::Listener::Rep_ **************************
 ********************************************************************************
 */
struct Listener::Rep_ {
    Rep_ (const Iterable<SocketAddress>& addrs, const Socket::BindFlags& bindFlags, unsigned int backlog, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor)
        : fNewConnectionAcceptor (newConnectionAcceptor)
    {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
        DbgTrace (L"Listener::Rep_::CTOR (addres=%s, ...)", Characters::ToString (addrs).c_str ());
#endif
        for (auto addr : addrs) {
            ConnectionOrientedMasterSocket::Ptr ms = ConnectionOrientedMasterSocket::New (addr.GetAddressFamily (), Socket::STREAM);
            ms.Bind (addr, bindFlags); // do in CTOR so throw propagated
            ms.Listen (backlog);
            fMasterSockets += ms;
        }
        fListenThread = Execution::Thread::New (
				[this]() {
				Containers::Bijection<ConnectionOrientedMasterSocket::Ptr, WaitForIOReady::FileDescriptorType> socket2FDBijection;
				for (auto&& s : fMasterSockets) {
					socket2FDBijection.Add (s, s.GetNativeSocket ());
				}
				//Execution::WaitForIOReady sockSetPoller { fMasterSockets.Select<Execution::WaitForIOReady::FileDescriptorType> ([] (Socket i) { return i.GetNativeSocket (); }) };
				Execution::WaitForIOReady sockSetPoller{socket2FDBijection.Image ()};
				while (true) {
					try {
						for (auto readyFD : sockSetPoller.WaitQuietly ().Value ()) {
							ConnectionOrientedMasterSocket::Ptr localSocketToAcceptOn = *socket2FDBijection.InverseLookup (readyFD);
							ConnectionOrientedSocket::Ptr       s                     = localSocketToAcceptOn.Accept ();
							fNewConnectionAcceptor (s);
						}
					}
					catch (const Execution::Thread::AbortException&) {
						Execution::ReThrow ();
					}
					catch (...) {
						// unclear what todo with expcetions here
						// probnably ignore all but for theradabort.
						// may need virtual fucntions to handle? Or std::function passed in?
						DbgTrace (L"Exception accepting new connection: %s - ignored", Characters::ToString (current_exception ()).c_str ());
					}
				}
			},
			Thread::eAutoStart,
			L"Socket Listener: " + Characters::ToString (addrs)
		);
    }

    function<void(const ConnectionOrientedSocket::Ptr& newConnection)> fNewConnectionAcceptor;
    Sequence<ConnectionOrientedMasterSocket::Ptr>                      fMasterSockets;
    Execution::Thread::CleanupPtr                                      fListenThread{Execution::Thread::CleanupPtr::eAbortBeforeWaiting};
};

/*
********************************************************************************
**************************** IO::Network::Listener *****************************
********************************************************************************
*/
Listener::Listener (const SocketAddress& addr, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (Sequence<SocketAddress>{addr}, Socket::BindFlags{}, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const SocketAddress& addr, const Socket::BindFlags& bindFlags, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (Sequence<SocketAddress>{addr}, bindFlags, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const Traversal::Iterable<SocketAddress>& addrs, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : Listener (addrs, Socket::BindFlags{}, newConnectionAcceptor, backlog)
{
}

Listener::Listener (const Traversal::Iterable<SocketAddress>& addrs, const Socket::BindFlags& bindFlags, const function<void(const ConnectionOrientedSocket::Ptr& newConnection)>& newConnectionAcceptor, unsigned int backlog)
    : fRep_ (make_shared<Rep_> (addrs, bindFlags, backlog, newConnectionAcceptor))
{
}

Listener::Listener (const Listener&& rhs)
    : fRep_ (move (rhs.fRep_))
{
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13 Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkFocusManager.h"
#include "mitkTestingMacros.h"
#include "mitkVtkPropRenderer.h"
#include "mitkGlobalInteraction.h"

int mitkFocusManagerTest(int /*argc*/, char* /*argv*/[])
{
  MITK_TEST_BEGIN("FocusManager");

  // Global interaction must(!) be initialized if used
  mitk::GlobalInteraction::GetInstance()->Initialize("global");

  //building up necessary objects
  vtkRenderWindow* renderWindow = vtkRenderWindow::New();
  mitk::VtkPropRenderer::Pointer element1 = mitk::VtkPropRenderer::New( "renderer1", renderWindow );
  mitk::VtkPropRenderer::Pointer element2 = mitk::VtkPropRenderer::New( "renderer2", renderWindow );
  mitk::VtkPropRenderer::Pointer element3 = mitk::VtkPropRenderer::New( "renderer3", renderWindow );

  //the FocusManager itself
  mitk::FocusManager::Pointer focusManager = mitk::FocusManager::New();

  //testing
  MITK_TEST_CONDITION_REQUIRED(focusManager.IsNotNull(), "Testing Instatiation");

  MITK_TEST_CONDITION_REQUIRED(element1.IsNotNull(), "Testing Instatiation of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element is focused on");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == NULL, "Testing focused on an empty list");

  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element; Elements in list: 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element2), "Testing addition of a second element; Elements in list: 1 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element3), "Testing addition of a third element; Elements in list: 1 2 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");

  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element1), "Testing setting focused to element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "focus on element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element2), "Testing setting focused to element 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "focus on element 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element3), "Testing setting focused to element 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "focus on element 3");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing first element; Elements in list: 2 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is the one behind the deleted one: 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element again; Elements in list: 2 3 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element3), "Testing removing element 3; Elements in list: 2 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if focused element is the one behind the deleted one: 1");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing last element 1; Elements in list: 2 ");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is 2");

  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing same element");
  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element2), "Testing removing last element in list (2)");

  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element3), "Testing removing from empty list ");
  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element2), "Testing removing from empty list with different object");
  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing from empty list with different object again");

  //focusManager = NULL;
  //focusManager->Delete();

  //TODO: test IsLast() IsFirst() GetFirst() GetLast() GoToNext() GetIter() SetLoop(bool loop)

  MITK_TEST_END();
}<commit_msg>COMP (#1432): reverted wrong delete of object under smart pointer<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-13 14:52:01 +0200 (Mi, 13 Mai 2009) $
Version:   $Revision: 17230 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkFocusManager.h"
#include "mitkTestingMacros.h"
#include "mitkVtkPropRenderer.h"
#include "mitkGlobalInteraction.h"

int mitkFocusManagerTest(int /*argc*/, char* /*argv*/[])
{
  MITK_TEST_BEGIN("FocusManager");

  // Global interaction must(!) be initialized if used
  mitk::GlobalInteraction::GetInstance()->Initialize("global");

  //building up necessary objects
  vtkRenderWindow* renderWindow = vtkRenderWindow::New();
  mitk::VtkPropRenderer::Pointer element1 = mitk::VtkPropRenderer::New( "renderer1", renderWindow );
  mitk::VtkPropRenderer::Pointer element2 = mitk::VtkPropRenderer::New( "renderer2", renderWindow );
  mitk::VtkPropRenderer::Pointer element3 = mitk::VtkPropRenderer::New( "renderer3", renderWindow );

  //the FocusManager itself
  mitk::FocusManager::Pointer focusManager = mitk::FocusManager::New();

  //testing
  MITK_TEST_CONDITION_REQUIRED(focusManager.IsNotNull(), "Testing Instatiation");

  MITK_TEST_CONDITION_REQUIRED(element1.IsNotNull(), "Testing Instatiation of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element is focused on");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing of an element");

  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == NULL, "Testing focused on an empty list");

  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element; Elements in list: 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element2), "Testing addition of a second element; Elements in list: 1 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element3), "Testing addition of a third element; Elements in list: 1 2 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");

  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element1), "Testing setting focused to element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "focus on element 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element2), "Testing setting focused to element 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "focus on element 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element3), "Testing setting focused to element 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "focus on element 3");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing first element; Elements in list: 2 3");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is the one behind the deleted one: 2");
  MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element again; Elements in list: 2 3 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element3), "Testing removing element 3; Elements in list: 2 1");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if focused element is the one behind the deleted one: 1");

  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing last element 1; Elements in list: 2 ");
  MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is 2");

  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing same element");
  MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element2), "Testing removing last element in list (2)");

  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element3), "Testing removing from empty list ");
  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element2), "Testing removing from empty list with different object");
  MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing from empty list with different object again");

  focusManager = NULL;

  //TODO: test IsLast() IsFirst() GetFirst() GetLast() GoToNext() GetIter() SetLoop(bool loop)

  MITK_TEST_END();
}<|endoftext|>


<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_GRAPHICS_RENDERDEVICE_HPP
#define OUZEL_GRAPHICS_RENDERDEVICE_HPP

#include <array>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <queue>
#include <set>
#include "graphics/Commands.hpp"
#include "graphics/Driver.hpp"
#include "graphics/SamplerFilter.hpp"
#include "graphics/Vertex.hpp"
#include "math/Matrix.hpp"
#include "math/Size.hpp"

namespace ouzel
{
    class Window;

    namespace graphics
    {
        class Renderer;

        struct ApiVersion
        {
            constexpr ApiVersion() = default;
            constexpr ApiVersion(std::uint16_t majorVersion, std::uint16_t minorVersion) noexcept:
                v{majorVersion, minorVersion} {}

            constexpr bool operator==(const ApiVersion& other) const
            {
                return v[0] == other.v[0] && v[1] == other.v[1];
            }

            constexpr bool operator>(const ApiVersion& other) const
            {
                return (v[0] == other.v[0]) ? (v[1] > other.v[1]) : (v[0] > other.v[0]);
            }

            constexpr bool operator>=(const ApiVersion& other) const
            {
                return (v[0] == other.v[0]) ? (v[1] >= other.v[1]) : (v[0] > other.v[0]);
            }

            std::uint16_t v[2]{0, 0};
        };

        class RenderDevice
        {
            friend Renderer;
        public:
            static const std::array<Vertex::Attribute, 5> VERTEX_ATTRIBUTES;

            struct Event
            {
                enum class Type
                {
                    Frame
                };

                Type type;
            };

            RenderDevice(Driver initDriver, const std::function<void(const Event&)>& initCallback);
            virtual ~RenderDevice() = default;

            RenderDevice(const RenderDevice&) = delete;
            RenderDevice& operator=(const RenderDevice&) = delete;

            RenderDevice(RenderDevice&&) = delete;
            RenderDevice& operator=(RenderDevice&&) = delete;

            inline auto getDriver() const noexcept { return driver; }

            virtual void process();

            inline auto getSampleCount() const noexcept { return sampleCount; }
            inline auto getTextureFilter() const noexcept { return textureFilter; }
            inline auto getMaxAnisotropy() const noexcept { return maxAnisotropy; }

            virtual std::vector<Size2U> getSupportedResolutions() const;

            void submitCommandBuffer(CommandBuffer&& commandBuffer)
            {
                std::unique_lock<std::mutex> lock(commandQueueMutex);
                commandQueue.push(std::move(commandBuffer));
                lock.unlock();
                commandQueueCondition.notify_all();
            }

            inline auto getDrawCallCount() const noexcept { return drawCallCount; }

            inline auto getAPIMajorVersion() const noexcept { return apiVersion.v[0]; }
            inline auto getAPIMinorVersion() const noexcept { return apiVersion.v[1]; }

            inline auto isNPOTTexturesSupported() const noexcept { return npotTexturesSupported; }
            inline auto isAnisotropicFilteringSupported() const noexcept { return anisotropicFilteringSupported; }
            inline auto isRenderTargetsSupported() const noexcept { return renderTargetsSupported; }

            auto& getProjectionTransform(bool renderTarget) const noexcept
            {
                return renderTarget ? renderTargetProjectionTransform : projectionTransform;
            }

            inline float getFPS() const noexcept { return currentFPS; }
            inline float getAccumulatedFPS() const noexcept { return accumulatedFPS; }

            void executeOnRenderThread(const std::function<void()>& func);

            class Resource final
            {
            public:
                Resource() = default;
                Resource(std::uintptr_t initId, const std::function<void(std::uintptr_t)>& initDeleter):
                    id(initId), deleter(initDeleter)
                {
                }

                ~Resource()
                {
                    if (id) deleter(id);
                }

                Resource(const Resource&) = delete;
                Resource& operator=(const Resource&) = delete;

                Resource(Resource&& other) noexcept:
                    id(other.id),
                    deleter(std::move(other.deleter))
                {
                    other.id = 0;
                }

                Resource& operator=(Resource&& other) noexcept
                {
                    if (&other == this) return *this;

                    id = other.id;
                    deleter = std::move(other.deleter);
                    other.id = 0;

                    return *this;
                }

                inline operator std::uintptr_t() const noexcept
                {
                    return id;
                }

            private:
                std::uintptr_t id = 0;
                std::function<void(std::uintptr_t)> deleter;
            };

            Resource createResource()
            {
                auto i = deletedResourceIds.begin();

                if (i == deletedResourceIds.end())
                    return Resource(++lastResourceId, [this](std::uintptr_t id){
                        deletedResourceIds.insert(id);
                    }); // zero is reserved for null resource
                else
                {
                    std::uintptr_t resourceId = *i;
                    deletedResourceIds.erase(i);
                    return Resource(resourceId, [this](std::uintptr_t id){
                        deletedResourceIds.insert(id);
                    });
                }
            }

        protected:
            virtual void init(Window* newWindow,
                              const Size2U& newSize,
                              std::uint32_t newSampleCount,
                              SamplerFilter newTextureFilter,
                              std::uint32_t newMaxAnisotropy,
                              bool newSrgb,
                              bool newVerticalSync,
                              bool newDepth,
                              bool newStencil,
                              bool newDebugRenderer);

            void executeAll();

            virtual void generateScreenshot(const std::string& filename);

            Driver driver;
            std::function<void(const Event&)> callback;

            Window* window = nullptr;

            ApiVersion apiVersion;

            std::uint32_t sampleCount = 1; // MSAA sample count
            SamplerFilter textureFilter = SamplerFilter::Point;
            std::uint32_t maxAnisotropy = 1;

            bool verticalSync = true;
            bool srgb = false;
            bool depth = false;
            bool stencil = false;
            bool debugRenderer = false;

            // features
            bool npotTexturesSupported:1;
            bool anisotropicFilteringSupported:1;
            bool renderTargetsSupported:1;
            bool clampToBorderSupported:1;
            bool multisamplingSupported:1;
            bool uintIndicesSupported:1;

            Matrix4F projectionTransform = Matrix4F::identity();
            Matrix4F renderTargetProjectionTransform = Matrix4F::identity();

            std::uint32_t drawCallCount = 0;

            std::queue<CommandBuffer> commandQueue;
            std::mutex commandQueueMutex;
            std::condition_variable commandQueueCondition;

            std::atomic<float> currentFPS{0.0F};
            std::chrono::steady_clock::time_point previousFrameTime;

            float accumulatedTime = 0.0F;
            float currentAccumulatedFPS = 0.0F;
            std::atomic<float> accumulatedFPS{0.0F};

            std::queue<std::function<void()>> executeQueue;
            std::mutex executeMutex;

        private:
            std::uintptr_t lastResourceId = 0;
            std::set<std::uintptr_t> deletedResourceIds;
        };
    } // namespace graphics
} // namespace ouzel

#endif // OUZEL_GRAPHICS_RENDERDEVICE_HPP
<commit_msg>Make ApiVersion final and all its methods noexcept<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_GRAPHICS_RENDERDEVICE_HPP
#define OUZEL_GRAPHICS_RENDERDEVICE_HPP

#include <array>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <queue>
#include <set>
#include "graphics/Commands.hpp"
#include "graphics/Driver.hpp"
#include "graphics/SamplerFilter.hpp"
#include "graphics/Vertex.hpp"
#include "math/Matrix.hpp"
#include "math/Size.hpp"

namespace ouzel
{
    class Window;

    namespace graphics
    {
        class Renderer;

        struct ApiVersion final
        {
            constexpr ApiVersion() noexcept = default;
            constexpr ApiVersion(std::uint16_t majorVersion, std::uint16_t minorVersion) noexcept:
                v{majorVersion, minorVersion} {}

            constexpr bool operator==(const ApiVersion& other) const noexcept
            {
                return v[0] == other.v[0] && v[1] == other.v[1];
            }

            constexpr bool operator>(const ApiVersion& other) const noexcept
            {
                return (v[0] == other.v[0]) ? (v[1] > other.v[1]) : (v[0] > other.v[0]);
            }

            constexpr bool operator>=(const ApiVersion& other) const noexcept
            {
                return (v[0] == other.v[0]) ? (v[1] >= other.v[1]) : (v[0] > other.v[0]);
            }

            std::uint16_t v[2]{0, 0};
        };

        class RenderDevice
        {
            friend Renderer;
        public:
            static const std::array<Vertex::Attribute, 5> VERTEX_ATTRIBUTES;

            struct Event
            {
                enum class Type
                {
                    Frame
                };

                Type type;
            };

            RenderDevice(Driver initDriver, const std::function<void(const Event&)>& initCallback);
            virtual ~RenderDevice() = default;

            RenderDevice(const RenderDevice&) = delete;
            RenderDevice& operator=(const RenderDevice&) = delete;

            RenderDevice(RenderDevice&&) = delete;
            RenderDevice& operator=(RenderDevice&&) = delete;

            inline auto getDriver() const noexcept { return driver; }

            virtual void process();

            inline auto getSampleCount() const noexcept { return sampleCount; }
            inline auto getTextureFilter() const noexcept { return textureFilter; }
            inline auto getMaxAnisotropy() const noexcept { return maxAnisotropy; }

            virtual std::vector<Size2U> getSupportedResolutions() const;

            void submitCommandBuffer(CommandBuffer&& commandBuffer)
            {
                std::unique_lock<std::mutex> lock(commandQueueMutex);
                commandQueue.push(std::move(commandBuffer));
                lock.unlock();
                commandQueueCondition.notify_all();
            }

            inline auto getDrawCallCount() const noexcept { return drawCallCount; }

            inline auto getAPIMajorVersion() const noexcept { return apiVersion.v[0]; }
            inline auto getAPIMinorVersion() const noexcept { return apiVersion.v[1]; }

            inline auto isNPOTTexturesSupported() const noexcept { return npotTexturesSupported; }
            inline auto isAnisotropicFilteringSupported() const noexcept { return anisotropicFilteringSupported; }
            inline auto isRenderTargetsSupported() const noexcept { return renderTargetsSupported; }

            auto& getProjectionTransform(bool renderTarget) const noexcept
            {
                return renderTarget ? renderTargetProjectionTransform : projectionTransform;
            }

            inline float getFPS() const noexcept { return currentFPS; }
            inline float getAccumulatedFPS() const noexcept { return accumulatedFPS; }

            void executeOnRenderThread(const std::function<void()>& func);

            class Resource final
            {
            public:
                Resource() = default;
                Resource(std::uintptr_t initId, const std::function<void(std::uintptr_t)>& initDeleter):
                    id(initId), deleter(initDeleter)
                {
                }

                ~Resource()
                {
                    if (id) deleter(id);
                }

                Resource(const Resource&) = delete;
                Resource& operator=(const Resource&) = delete;

                Resource(Resource&& other) noexcept:
                    id(other.id),
                    deleter(std::move(other.deleter))
                {
                    other.id = 0;
                }

                Resource& operator=(Resource&& other) noexcept
                {
                    if (&other == this) return *this;

                    id = other.id;
                    deleter = std::move(other.deleter);
                    other.id = 0;

                    return *this;
                }

                inline operator std::uintptr_t() const noexcept
                {
                    return id;
                }

            private:
                std::uintptr_t id = 0;
                std::function<void(std::uintptr_t)> deleter;
            };

            Resource createResource()
            {
                auto i = deletedResourceIds.begin();

                if (i == deletedResourceIds.end())
                    return Resource(++lastResourceId, [this](std::uintptr_t id){
                        deletedResourceIds.insert(id);
                    }); // zero is reserved for null resource
                else
                {
                    std::uintptr_t resourceId = *i;
                    deletedResourceIds.erase(i);
                    return Resource(resourceId, [this](std::uintptr_t id){
                        deletedResourceIds.insert(id);
                    });
                }
            }

        protected:
            virtual void init(Window* newWindow,
                              const Size2U& newSize,
                              std::uint32_t newSampleCount,
                              SamplerFilter newTextureFilter,
                              std::uint32_t newMaxAnisotropy,
                              bool newSrgb,
                              bool newVerticalSync,
                              bool newDepth,
                              bool newStencil,
                              bool newDebugRenderer);

            void executeAll();

            virtual void generateScreenshot(const std::string& filename);

            Driver driver;
            std::function<void(const Event&)> callback;

            Window* window = nullptr;

            ApiVersion apiVersion;

            std::uint32_t sampleCount = 1; // MSAA sample count
            SamplerFilter textureFilter = SamplerFilter::Point;
            std::uint32_t maxAnisotropy = 1;

            bool verticalSync = true;
            bool srgb = false;
            bool depth = false;
            bool stencil = false;
            bool debugRenderer = false;

            // features
            bool npotTexturesSupported:1;
            bool anisotropicFilteringSupported:1;
            bool renderTargetsSupported:1;
            bool clampToBorderSupported:1;
            bool multisamplingSupported:1;
            bool uintIndicesSupported:1;

            Matrix4F projectionTransform = Matrix4F::identity();
            Matrix4F renderTargetProjectionTransform = Matrix4F::identity();

            std::uint32_t drawCallCount = 0;

            std::queue<CommandBuffer> commandQueue;
            std::mutex commandQueueMutex;
            std::condition_variable commandQueueCondition;

            std::atomic<float> currentFPS{0.0F};
            std::chrono::steady_clock::time_point previousFrameTime;

            float accumulatedTime = 0.0F;
            float currentAccumulatedFPS = 0.0F;
            std::atomic<float> accumulatedFPS{0.0F};

            std::queue<std::function<void()>> executeQueue;
            std::mutex executeMutex;

        private:
            std::uintptr_t lastResourceId = 0;
            std::set<std::uintptr_t> deletedResourceIds;
        };
    } // namespace graphics
} // namespace ouzel

#endif // OUZEL_GRAPHICS_RENDERDEVICE_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Lech Kulina
 *
 * This file is part of the Realms Of Steel.
 * For conditions of distribution and use, see copyright details in the LICENSE file.
 */
#include <Core/RawBuffer.h>

ros::RawBuffer::RawBuffer()
    : data(ROS_NULL)
    , size(0)
    , position(0) {
}

ros::RawBuffer::RawBuffer(U32 size)
    : data(ROS_NULL)
    , size(0)
    , position(0) {
    allocate(size);
}

ros::RawBuffer::~RawBuffer() {
    free();
}

ros::RawBuffer::RawBuffer(const RawBuffer& src)
    : data(ROS_NULL)
    , size(0)
    , position(0) {
    assign(src);
}

ros::RawBuffer& ros::RawBuffer::operator=(const RawBuffer& src) {
    assign(src);
    return *this;
}

bool ros::RawBuffer::allocate(U32 size) {
    if (size == 0) {
        return false;
    }

    U8* data = new (std::nothrow) U8[size];
    if (!data) {
        return false;
    }
    memset(data, 0, size);

    free();
    this->data = data;
    this->size = size;

    return true;
}

void ros::RawBuffer::free() {
    delete []data;
    data = ROS_NULL;
    size = 0;
    position = 0;
}

bool ros::RawBuffer::assign(const RawBuffer& src) {
    if (this == &src) {
        return true;
    }

    if (src.isNull() || !allocate(src.getSize())) {
        return false;
    }
    memcpy(data, src.at<U8>(), src.getSize());

    return true;
}

bool ros::RawBuffer::resize(U32 size) {
    if (!this->data) {
        return allocate(size);
    }
    if (size == 0) {
        return false;
    }

    U8* data = new (std::nothrow) U8[size];
    if (!data) {
        return false;
    }
    memset(data, 0, size);
    memcpy(data, this->data, std::min(size, this->size));

    free();
    this->data = data;
    this->size = size;

    return true;
}

void ros::RawBuffer::clear() {
    if (data) {
        memset(data, 0, size);
    }
}

bool ros::RawBuffer::seek(S64 offset, BufferOrigin origin) const {
    if (!data) {
        return false;
    }
    if (offset == 0 && origin == BufferOrigin_Current) {
        return true;
    }

    switch(origin) {
        case BufferOrigin_Begin:
            if (offset >= static_cast<S64>(size)) {
                return false;
            }
            position = offset;
            break;
        case BufferOrigin_Current:
            if (position + offset >= static_cast<S64>(size) || position + offset < 0) {
                return false;
            }
            position += offset;
            break;
        case BufferOrigin_End:
            if (offset >= 0 || static_cast<S64>(size) + offset < 0) {
                return false;
            }
            position = size + offset;
            break;
    }

    return true;
}

bool ros::RawBuffer::rewind() const {
    if (!data) {
        return false;
    }
    position = 0;
    return true;
}

bool ros::RawBuffer::hasEnded() const {
    return position >= static_cast<S64>(size);
}

bool ros::RawBuffer::read(void* dst, U32 size) const {
    if (!data || position + size > this->size) {
        return false;
    }
    if (size == 0) {
        return true;
    }

    memcpy(dst, data + position, size);
    position += size;

    return true;
}

bool ros::RawBuffer::write(const void* src, U32 size) {
    if (!data || position + size > this->size)
        return false;
    if (size == 0) {
        return true;
    }

    memcpy(data + position, src, size);
    position += size;

    return true;
}
<commit_msg>Always free RawBuffer before allocating new memory<commit_after>/*
 * Copyright (c) 2016 Lech Kulina
 *
 * This file is part of the Realms Of Steel.
 * For conditions of distribution and use, see copyright details in the LICENSE file.
 */
#include <Core/RawBuffer.h>

ros::RawBuffer::RawBuffer()
    : data(ROS_NULL)
    , size(0)
    , position(0) {
}

ros::RawBuffer::RawBuffer(U32 size)
    : data(ROS_NULL)
    , size(0)
    , position(0) {
    allocate(size);
}

ros::RawBuffer::~RawBuffer() {
    free();
}

ros::RawBuffer::RawBuffer(const RawBuffer& src)
    : data(ROS_NULL)
    , size(0)
    , position(0) {
    assign(src);
}

ros::RawBuffer& ros::RawBuffer::operator=(const RawBuffer& src) {
    assign(src);
    return *this;
}

bool ros::RawBuffer::allocate(U32 size) {
    free();
    if (size == 0) {
        return false;
    }

    data = new (std::nothrow) U8[size];
    if (!data) {
        return false;
    }
    memset(data, 0, size);
    this->size = size;

    return true;
}

void ros::RawBuffer::free() {
    delete []data;
    data = ROS_NULL;
    size = 0;
    position = 0;
}

bool ros::RawBuffer::assign(const RawBuffer& src) {
    if (this == &src) {
        return true;
    }

    if (src.isNull() || !allocate(src.getSize())) {
        return false;
    }
    memcpy(data, src.at<U8>(), src.getSize());

    return true;
}

bool ros::RawBuffer::resize(U32 size) {
    if (!this->data) {
        return allocate(size);
    }

    if (size == 0) {
        return false;
    }

    U8* data = new (std::nothrow) U8[size];
    if (!data) {
        return false;
    }
    memset(data, 0, size);
    memcpy(data, this->data, std::min(size, this->size));

    free();
    this->data = data;
    this->size = size;

    return true;
}

void ros::RawBuffer::clear() {
    if (data) {
        memset(data, 0, size);
    }
}

bool ros::RawBuffer::seek(S64 offset, BufferOrigin origin) const {
    if (!data) {
        return false;
    }
    if (offset == 0 && origin == BufferOrigin_Current) {
        return true;
    }

    switch(origin) {
        case BufferOrigin_Begin:
            if (offset >= static_cast<S64>(size)) {
                return false;
            }
            position = offset;
            break;
        case BufferOrigin_Current:
            if (position + offset >= static_cast<S64>(size) || position + offset < 0) {
                return false;
            }
            position += offset;
            break;
        case BufferOrigin_End:
            if (offset >= 0 || static_cast<S64>(size) + offset < 0) {
                return false;
            }
            position = size + offset;
            break;
    }

    return true;
}

bool ros::RawBuffer::rewind() const {
    if (!data) {
        return false;
    }
    position = 0;
    return true;
}

bool ros::RawBuffer::hasEnded() const {
    return position >= static_cast<S64>(size);
}

bool ros::RawBuffer::read(void* dst, U32 size) const {
    if (!data || position + size > this->size) {
        return false;
    }
    if (size == 0) {
        return true;
    }

    memcpy(dst, data + position, size);
    position += size;

    return true;
}

bool ros::RawBuffer::write(const void* src, U32 size) {
    if (!data || position + size > this->size)
        return false;
    if (size == 0) {
        return true;
    }

    memcpy(data + position, src, size);
    position += size;

    return true;
}
<|endoftext|>


<commit_before><commit_msg>polish previous code<commit_after><|endoftext|>


<commit_before>#ifndef FIXED_VECTOR_HPP
#define FIXED_VECTOR_HPP
#include<algorithm>
#include<type_traits>
#include<utility>

namespace nContainer
{
	template<class T,auto N>
	class Fixed_vector
	{
	public:
		using value_type=T;
		using size_type=std::remove_cv_t<decltype(N)>;
		using pointer=T*;
		using const_pointer=const T*;
		using reference=T&;
		using const_reference=const T&;
		using iterator=T*;
		using const_iterator=const T*;
	private:
		value_type data_[N];
		pointer end_;
	public:
		constexpr Fixed_vector() noexcept(std::is_nothrow_default_constructible_v<T>)
			:end_(data_){}
		Fixed_vector(const Fixed_vector &rhs)
			:Fixed_vector(rhs.begin(),rhs.end()){}
		Fixed_vector(Fixed_vector &&rhs)
		{
			end_=std::move(rhs.begin(),rhs.end(),data_);
		}
		template<class InIter>
		constexpr Fixed_vector(InIter begin,InIter end)
		{
			end_=std::copy(begin,end,data_);
		}
		Fixed_vector(const Fixed_vector &rhs)=delete;
		constexpr reference back() noexcept
		{
			return *(end_-1);
		}
		constexpr const_reference back() const noexcept
		{
			return *(end_-1);
		}
		constexpr iterator begin() noexcept
		{
			return data_;
		}
		constexpr const_iterator begin() const noexcept
		{
			return data_;
		}
		constexpr size_type capacity() const noexcept
		{
			return N;
		}
		constexpr void clear() noexcept
		{
			end_=data_;
		}
		constexpr iterator end() noexcept
		{
			return end_;
		}
		constexpr const_iterator end() const noexcept
		{
			return end_;
		}
		constexpr bool empty() const noexcept
		{
			return data_==end_;
		}
		void erase(const const_iterator pos)
		{
			std::move(pos+1,end_,pos);
		}
		constexpr pointer data() noexcept
		{
			return data_;
		}
		constexpr const_pointer data() const noexcept
		{
			return data_;
		}
		constexpr reference front() noexcept
		{
			return data_[0];
		}
		constexpr const_reference front() const noexcept
		{
			return data_[0];
		}
		constexpr void pop_back() noexcept
		{
			--end_;
		}
		constexpr void push_back(const value_type &val) noexcept(std::is_nothrow_copy_assignable_v<value_type>)
		{
			*(end_++)=val;
		}
		constexpr void push_back(value_type &&val) noexcept(std::is_nothrow_move_assignable_v<value_type>)
		{
			*(end_++)=std::move(val);
		}
		constexpr void resize(const size_type new_size) noexcept
		{
			end_=data_+new_size;
		}
		constexpr size_type size() const noexcept
		{
			return end_-data_;
		}
		constexpr reference operator[](const size_type pos)
		{
			return data_[pos];
		}
		constexpr const_reference operator[](const size_type pos) const
		{
			return data_[pos];
		}
		Fixed_vector& operator=(const Fixed_vector &rhs)=delete;
	};
}

#endif<commit_msg>add copy assignment operator & move assignment operator<commit_after>#ifndef FIXED_VECTOR_HPP
#define FIXED_VECTOR_HPP
#include<algorithm>
#include<type_traits>
#include<utility>

namespace nContainer
{
	template<class T,auto N>
	class Fixed_vector
	{
	public:
		using value_type=T;
		using size_type=std::remove_cv_t<decltype(N)>;
		using pointer=T*;
		using const_pointer=const T*;
		using reference=T&;
		using const_reference=const T&;
		using iterator=T*;
		using const_iterator=const T*;
	private:
		value_type data_[N];
		pointer end_;
	public:
		constexpr Fixed_vector() noexcept(std::is_nothrow_default_constructible_v<T>)
			:end_(data_){}
		Fixed_vector(const Fixed_vector &rhs)
			:Fixed_vector(rhs.begin(),rhs.end()){}
		Fixed_vector(Fixed_vector &&rhs)
		{
			end_=std::move(rhs.begin(),rhs.end(),data_);
		}
		template<class InIter>
		constexpr Fixed_vector(InIter begin,InIter end)
		{
			end_=std::copy(begin,end,data_);
		}
		Fixed_vector(const Fixed_vector &rhs)=delete;
		constexpr reference back() noexcept
		{
			return *(end_-1);
		}
		constexpr const_reference back() const noexcept
		{
			return *(end_-1);
		}
		constexpr iterator begin() noexcept
		{
			return data_;
		}
		constexpr const_iterator begin() const noexcept
		{
			return data_;
		}
		constexpr size_type capacity() const noexcept
		{
			return N;
		}
		constexpr void clear() noexcept
		{
			end_=data_;
		}
		constexpr iterator end() noexcept
		{
			return end_;
		}
		constexpr const_iterator end() const noexcept
		{
			return end_;
		}
		constexpr bool empty() const noexcept
		{
			return data_==end_;
		}
		void erase(const const_iterator pos)
		{
			std::move(pos+1,end_,pos);
		}
		constexpr pointer data() noexcept
		{
			return data_;
		}
		constexpr const_pointer data() const noexcept
		{
			return data_;
		}
		constexpr reference front() noexcept
		{
			return data_[0];
		}
		constexpr const_reference front() const noexcept
		{
			return data_[0];
		}
		constexpr void pop_back() noexcept
		{
			--end_;
		}
		constexpr void push_back(const value_type &val) noexcept(std::is_nothrow_copy_assignable_v<value_type>)
		{
			*(end_++)=val;
		}
		constexpr void push_back(value_type &&val) noexcept(std::is_nothrow_move_assignable_v<value_type>)
		{
			*(end_++)=std::move(val);
		}
		constexpr void resize(const size_type new_size) noexcept
		{
			end_=data_+new_size;
		}
		constexpr size_type size() const noexcept
		{
			return end_-data_;
		}
		constexpr reference operator[](const size_type pos)
		{
			return data_[pos];
		}
		constexpr const_reference operator[](const size_type pos) const
		{
			return data_[pos];
		}
		Fixed_vector& operator=(const Fixed_vector &rhs)
		{
			if(this!=&rhs)
				end_=std::copy(rhs.begin(),rhs.end(),data_);
			return *this;
		}
		Fixed_vector& operator=(Fixed_vector &&rhs)
		{
			if(this!=&rhs)
				end_=std::move(rhs.begin(),rhs.end(),data_);
			return *this;
		}
	};
}

#endif<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#include "tic_tac_toe.hpp"

using namespace eosio;
namespace tic_tac_toe {
struct impl {
   /**
    * @brief Check if cell is empty
    * @param cell - value of the cell (should be either 0, 1, or 2)
    * @return true if cell is empty
    */
   bool is_empty_cell(const uint8_t& cell) {
      return cell == 0;
   }

   /**
    * @brief Check for valid movement
    * @detail Movement is considered valid if it is inside the board and done on empty cell
    * @param mvt - the movement made by the player
    * @param game_for_movement - the game on which the movement is being made
    * @return true if movement is valid
    */
   bool is_valid_movement(const movement& mvt, const game& game_for_movement) {
      uint32_t movement_location = mvt.row * 3 + mvt.column;
      bool is_valid = movement_location < board_len && is_empty_cell(game_for_movement.board[movement_location]);
      return is_valid;
   }

   /**
    * @brief Get winner of the game
    * @detail Winner of the game is the first player who made three consecutive aligned movement
    * @param current_game - the game which we want to determine the winner of
    * @return winner of the game (can be either none/ draw/ account name of host/ account name of challenger)
    */
   account_name get_winner(const game& current_game) {
      if((current_game.board[0] == current_game.board[4] && current_game.board[4] == current_game.board[8]) ||
         (current_game.board[1] == current_game.board[4] && current_game.board[4] == current_game.board[7]) ||
         (current_game.board[2] == current_game.board[4] && current_game.board[4] == current_game.board[6]) ||
         (current_game.board[3] == current_game.board[4] && current_game.board[4] == current_game.board[5])) {
         //  - | - | x    x | - | -    - | - | -    - | x | -
         //  - | x | -    - | x | -    x | x | x    - | x | -
         //  x | - | -    - | - | x    - | - | -    - | x | -
         if (current_game.board[4] == 1) {
            return current_game.host;
         } else if (current_game.board[4] == 2) {
            return current_game.challenger;
         }
      } else if ((current_game.board[0] == current_game.board[1] && current_game.board[1] == current_game.board[2]) ||
                 (current_game.board[0] == current_game.board[3] && current_game.board[3] == current_game.board[6])) {
         //  x | x | x       x | - | -
         //  - | - | -       x | - | -
         //  - | - | -       x | - | -
         if (current_game.board[0] == 1) {
            return current_game.host;
         } else if (current_game.board[0] == 2) {
            return current_game.challenger;
         }
      } else if ((current_game.board[2] == current_game.board[5] && current_game.board[5] == current_game.board[8]) ||
                 (current_game.board[6] == current_game.board[7] && current_game.board[7] == current_game.board[8])) {
         //  - | - | -       - | - | x
         //  - | - | -       - | - | x
         //  x | x | x       - | - | x
         if (current_game.board[8] == 1) {
            return current_game.host;
         } else if (current_game.board[8] == 2) {
            return current_game.challenger;
         }
      } else {
         bool is_board_full = true;
         for (uint8_t i = 0; i < board_len; i++) {
            if (is_empty_cell(current_game.board[i])) {
               is_board_full = false;
               break;
            }
         }
         if (is_board_full) {
            return N(draw);
         }
      }
      return N(none);
   }

   /**
    * @brief Apply create action
    * @param c - action to be applied
    */
   void on(const create& c) {
      require_auth(c.host);
      eosio_assert(c.challenger != c.host, "challenger shouldn't be the same as host");

      // Check if game already exists
      games existing_host_games(code_account, c.host);
      auto itr = existing_host_games.find( c.challenger );
      eosio_assert(itr == existing_host_games.end(), "game already exists");

      existing_host_games.emplace(c.host, [&]( auto& g ) {
         g.challenger = c.challenger;
         g.host = c.host;
         g.turn = c.host;
      });
   }

   /**
    * @brief Apply restart action
    * @param r - action to be applied
    */
   void on(const restart& r) {
      require_auth(r.by);

      // Check if game exists
      games existing_host_games(code_account, r.host);
      auto itr = existing_host_games.find( r.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Check if this game belongs to the action sender
      eosio_assert(r.by == itr->host || r.by == itr->challenger, "this is not your game!");

      // Reset game
      existing_host_games.modify(itr, itr->host, []( auto& g ) {
         g.reset_game();
      });
   }

   /**
    * @brief Apply close action
    * @param c - action to be applied
    */
   void on(const close& c) {
      require_auth(c.host);

      // Check if game exists
      games existing_host_games(code_account, c.host);
      auto itr = existing_host_games.find( c.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Remove game
      existing_host_games.erase(itr);
   }

   /**
    * @brief Apply move action
    * @param m - action to be applied
    */
   void on(const move& m) {
      require_auth(m.by);

      // Check if game exists
      games existing_host_games(code_account, m.host);
      auto itr = existing_host_games.find( m.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Check if this game hasn't ended yet
      eosio_assert(itr->winner == N(none), "the game has ended!");
      // Check if this game belongs to the action sender
      eosio_assert(m.by == itr->host || m.by == itr->challenger, "this is not your game!");
      // Check if this is the  action sender's turn
      eosio_assert(m.by == itr->turn, "it's not your turn yet!");

      // Check if user makes a valid movement
      eosio_assert(is_valid_movement(m.mvt, *itr), "not a valid movement!");

      // Fill the cell, 1 for host, 2 for challenger
      const uint8_t cell_value = itr->turn == itr->host ? 1 : 2;
      const auto turn = itr->turn == itr->host ? itr->challenger : itr->host;
      existing_host_games.modify(itr, itr->host, [&]( auto& g ) {
         g.board[m.mvt.row * 3 + m.mvt.column] = cell_value;
         g.turn = turn;

         //check to see if we have a winner
         g.winner = get_winner(g);
      });
   }

   /// The apply method implements the dispatch of events to this contract
   void apply( uint64_t /*receiver*/, uint64_t code, uint64_t action ) {

      if (code == code_account) {
         if (action == N(create)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::create>());
         } else if (action == N(restart)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::restart>());
         } else if (action == N(close)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::close>());
         } else if (action == N(move)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::move>());
         }
      }
   }

};
}

/**
*  The apply() methods must have C calling convention so that the blockchain can lookup and
*  call these methods.
*/
extern "C" {

   using namespace tic_tac_toe;
   /// The apply method implements the dispatch of events to this contract
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) {
      impl().apply(receiver, code, action);
   }

} // extern "C"
<commit_msg>fix unordered boards<commit_after>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#include "tic_tac_toe.hpp"

using namespace eosio;
namespace tic_tac_toe {
struct impl {
   /**
    * @brief Check if cell is empty
    * @param cell - value of the cell (should be either 0, 1, or 2)
    * @return true if cell is empty
    */
   bool is_empty_cell(const uint8_t& cell) {
      return cell == 0;
   }

   /**
    * @brief Check for valid movement
    * @detail Movement is considered valid if it is inside the board and done on empty cell
    * @param mvt - the movement made by the player
    * @param game_for_movement - the game on which the movement is being made
    * @return true if movement is valid
    */
   bool is_valid_movement(const movement& mvt, const game& game_for_movement) {
      uint32_t movement_location = mvt.row * 3 + mvt.column;
      bool is_valid = movement_location < board_len && is_empty_cell(game_for_movement.board[movement_location]);
      return is_valid;
   }

   /**
    * @brief Get winner of the game
    * @detail Winner of the game is the first player who made three consecutive aligned movement
    * @param current_game - the game which we want to determine the winner of
    * @return winner of the game (can be either none/ draw/ account name of host/ account name of challenger)
    */
   account_name get_winner(const game& current_game) {
      if((current_game.board[0] == current_game.board[4] && current_game.board[4] == current_game.board[8]) ||
         (current_game.board[1] == current_game.board[4] && current_game.board[4] == current_game.board[7]) ||
         (current_game.board[2] == current_game.board[4] && current_game.board[4] == current_game.board[6]) ||
         (current_game.board[3] == current_game.board[4] && current_game.board[4] == current_game.board[5])) {
         //  x | - | -    - | x | -    - | - | x    - | - | -
         //  - | x | -    - | x | -    - | x | -    x | x | x
         //  - | - | x    - | x | -    x | - | -    - | - | -
         if (current_game.board[4] == 1) {
            return current_game.host;
         } else if (current_game.board[4] == 2) {
            return current_game.challenger;
         }
      } else if ((current_game.board[0] == current_game.board[1] && current_game.board[1] == current_game.board[2]) ||
                 (current_game.board[0] == current_game.board[3] && current_game.board[3] == current_game.board[6])) {
         //  x | x | x       x | - | -
         //  - | - | -       x | - | -
         //  - | - | -       x | - | -
         if (current_game.board[0] == 1) {
            return current_game.host;
         } else if (current_game.board[0] == 2) {
            return current_game.challenger;
         }
      } else if ((current_game.board[2] == current_game.board[5] && current_game.board[5] == current_game.board[8]) ||
                 (current_game.board[6] == current_game.board[7] && current_game.board[7] == current_game.board[8])) {
         //  - | - | x       - | - | -
         //  - | - | x       - | - | -
         //  - | - | x       x | x | x
         if (current_game.board[8] == 1) {
            return current_game.host;
         } else if (current_game.board[8] == 2) {
            return current_game.challenger;
         }
      } else {
         bool is_board_full = true;
         for (uint8_t i = 0; i < board_len; i++) {
            if (is_empty_cell(current_game.board[i])) {
               is_board_full = false;
               break;
            }
         }
         if (is_board_full) {
            return N(draw);
         }
      }
      return N(none);
   }

   /**
    * @brief Apply create action
    * @param c - action to be applied
    */
   void on(const create& c) {
      require_auth(c.host);
      eosio_assert(c.challenger != c.host, "challenger shouldn't be the same as host");

      // Check if game already exists
      games existing_host_games(code_account, c.host);
      auto itr = existing_host_games.find( c.challenger );
      eosio_assert(itr == existing_host_games.end(), "game already exists");

      existing_host_games.emplace(c.host, [&]( auto& g ) {
         g.challenger = c.challenger;
         g.host = c.host;
         g.turn = c.host;
      });
   }

   /**
    * @brief Apply restart action
    * @param r - action to be applied
    */
   void on(const restart& r) {
      require_auth(r.by);

      // Check if game exists
      games existing_host_games(code_account, r.host);
      auto itr = existing_host_games.find( r.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Check if this game belongs to the action sender
      eosio_assert(r.by == itr->host || r.by == itr->challenger, "this is not your game!");

      // Reset game
      existing_host_games.modify(itr, itr->host, []( auto& g ) {
         g.reset_game();
      });
   }

   /**
    * @brief Apply close action
    * @param c - action to be applied
    */
   void on(const close& c) {
      require_auth(c.host);

      // Check if game exists
      games existing_host_games(code_account, c.host);
      auto itr = existing_host_games.find( c.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Remove game
      existing_host_games.erase(itr);
   }

   /**
    * @brief Apply move action
    * @param m - action to be applied
    */
   void on(const move& m) {
      require_auth(m.by);

      // Check if game exists
      games existing_host_games(code_account, m.host);
      auto itr = existing_host_games.find( m.challenger );
      eosio_assert(itr != existing_host_games.end(), "game doesn't exists");

      // Check if this game hasn't ended yet
      eosio_assert(itr->winner == N(none), "the game has ended!");
      // Check if this game belongs to the action sender
      eosio_assert(m.by == itr->host || m.by == itr->challenger, "this is not your game!");
      // Check if this is the  action sender's turn
      eosio_assert(m.by == itr->turn, "it's not your turn yet!");

      // Check if user makes a valid movement
      eosio_assert(is_valid_movement(m.mvt, *itr), "not a valid movement!");

      // Fill the cell, 1 for host, 2 for challenger
      const uint8_t cell_value = itr->turn == itr->host ? 1 : 2;
      const auto turn = itr->turn == itr->host ? itr->challenger : itr->host;
      existing_host_games.modify(itr, itr->host, [&]( auto& g ) {
         g.board[m.mvt.row * 3 + m.mvt.column] = cell_value;
         g.turn = turn;

         //check to see if we have a winner
         g.winner = get_winner(g);
      });
   }

   /// The apply method implements the dispatch of events to this contract
   void apply( uint64_t /*receiver*/, uint64_t code, uint64_t action ) {

      if (code == code_account) {
         if (action == N(create)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::create>());
         } else if (action == N(restart)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::restart>());
         } else if (action == N(close)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::close>());
         } else if (action == N(move)) {
            impl::on(eosio::unpack_action_data<tic_tac_toe::move>());
         }
      }
   }

};
}

/**
*  The apply() methods must have C calling convention so that the blockchain can lookup and
*  call these methods.
*/
extern "C" {

   using namespace tic_tac_toe;
   /// The apply method implements the dispatch of events to this contract
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) {
      impl().apply(receiver, code, action);
   }

} // extern "C"
<|endoftext|>


<commit_before>#include "photoeffects.hpp"
#include <stdio.h>

TEST(photoeffects, VignetteTest)
{
	Mat image(10, 10, CV_8UC1);
	EXPECT_EQ(10, vignette(image, 5).cols);
}<commit_msg>changed vignette_test.cpp<commit_after>#include <gtest/gtest.h>
#include "photoeffects.hpp"

using namespace cv;

TEST(photoeffects, VignetteTest)
{
	Mat image(10, 10, CV_8UC1);
	EXPECT_EQ(10, vignette(image, 5).cols);
}
<|endoftext|>


<commit_before>#include <common/buffer.h>
#include <common/endian.h>

#include <xcodec/xcodec.h>
#include <xcodec/xcodec_cache.h>
#include <xcodec/xcodec_encoder.h>
#include <xcodec/xcodec_hash.h>

typedef	std::pair<unsigned, uint64_t> offset_hash_pair_t;

struct xcodec_special_p {
	bool operator() (uint8_t ch) const
	{
		return (XCODEC_CHAR_SPECIAL(ch));
	}
};

XCodecEncoder::XCodecEncoder(XCodec *codec)
: log_("/xcodec/encoder"),
  cache_(codec->cache_),
  window_()
{ }

XCodecEncoder::~XCodecEncoder()
{ }

/*
 * This takes a view of a data stream and turns it into a series of references
 * to other data, declarations of data to be referenced, and data that needs
 * escaped.
 */
void
XCodecEncoder::encode(Buffer *output, Buffer *input)
{
	if (input->length() < XCODEC_SEGMENT_LENGTH) {
		input->escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
		output->append(input);
		input->clear();
		return;
	}

	XCodecHash<XCODEC_SEGMENT_LENGTH> xcodec_hash;
	std::deque<offset_hash_pair_t> offset_hash_map;
	Buffer outq;
	unsigned o = 0;

	while (!input->empty()) {
		BufferSegment *seg;
		input->moveout(&seg);

		outq.append(seg);

		const uint8_t *p;
		for (p = seg->data(); p < seg->end(); p++) {
			xcodec_hash.roll(*p);
			if (++o < XCODEC_SEGMENT_LENGTH)
				continue;

			unsigned start = o - XCODEC_SEGMENT_LENGTH;
			uint64_t hash = xcodec_hash.mix();
			bool hash_collision;

			BufferSegment *oseg = cache_->lookup(hash);
			if (oseg != NULL) {
				/*
				 * This segment already exists.  If it's
				 * identical to this chunk of data, then that's
				 * positively fantastic.
				 */
				if (encode_reference(output, &outq, start, hash, oseg)) {
					oseg->unref();
					o = 0;
					offset_hash_map.clear();
					continue;
				}
				oseg->unref();
				DEBUG(log_) << "Collision in first pass.";
				hash_collision = true;

				/*
				 * Fall through to defining the previous hash if
				 * it is appropriate to do so.
				 */
			} else {
				hash_collision = false;
			}

			if (!offset_hash_map.empty()) {
				/*
				 * If there is a previous hash in the
				 * offset-hash map that would overlap with this
				 * hash, then we have no reason to remember this
				 * hash for later.
				 */
				const offset_hash_pair_t& last = offset_hash_map.back();

				if (last.first + XCODEC_SEGMENT_LENGTH > start) {
					/* We might still find an alternative.  */
					continue;
				}

				BufferSegment *nseg;
				encode_declaration(output, &outq, last.first, last.second, &nseg);

				o -= last.first + XCODEC_SEGMENT_LENGTH;
				start = o - XCODEC_SEGMENT_LENGTH;

				uint64_t ohash = last.second;
				offset_hash_map.clear();

				/*
				 * If this hash is the same as the has for
				 * the current data, then make sure that they
				 * are compatible before remembering the
				 * current hash
				 */
				if (!hash_collision && hash == ohash) {
					if (!encode_reference(output, &outq, start, hash, nseg)) {
						nseg->unref();
						DEBUG(log_) << "Collision in adjacent-declare pass.";
						continue;
					}
					nseg->unref();

					DEBUG(log_) << "Hit in adjacent-declare pass.";

					o = 0;
					continue;
				}
				nseg->unref();

				/*
				 * Remember the current hash.
				 */
			}

			/*
			 * No collision, remember this for later.
			 */
			if (!hash_collision) {
				offset_hash_pair_t ohp;
				ohp.first = start;
				ohp.second = hash;
				offset_hash_map.push_back(ohp);
			}

		}

		seg->unref();
	}

	/*
	 * There's a hash we can declare, do it.
	 */
	if (!offset_hash_map.empty()) {
		ASSERT(!outq.empty());
		const offset_hash_pair_t& last = offset_hash_map.back();

		encode_declaration(output, &outq, last.first, last.second, NULL);
		offset_hash_map.clear();
	}

	if (!outq.empty()) {
		Buffer suffix(outq);
		outq.clear();

		suffix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());

		output->append(suffix);
		outq.clear();
	}

	ASSERT(offset_hash_map.empty());
	ASSERT(outq.empty());
	ASSERT(input->empty());
}

void
XCodecEncoder::encode_declaration(Buffer *output, Buffer *input, unsigned offset, uint64_t hash, BufferSegment **segp)
{
	if (offset != 0) {
		Buffer prefix;
		input->moveout(&prefix, 0, offset);

		prefix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
		output->append(prefix);
		prefix.clear();
	}

	BufferSegment *nseg;
	input->copyout(&nseg, XCODEC_SEGMENT_LENGTH);

	cache_->enter(hash, nseg);

	output->append(XCODEC_DECLARE_CHAR);
	uint64_t lehash = LittleEndian::encode(hash);
	output->append((const uint8_t *)&lehash, sizeof lehash);
	output->append(nseg);

	window_.declare(hash, nseg);
	if (segp == NULL)
		nseg->unref();

	/*
	 * Skip to the end.
	 */
	input->skip(XCODEC_SEGMENT_LENGTH);

	/*
	 * And output a reference.
	 */
	uint8_t b;
	if (window_.present(hash, &b)) {
		output->append(XCODEC_BACKREF_CHAR);
		output->append(b);
	} else {
		NOTREACHED();
	}

	if (segp != NULL)
		*segp = nseg;
}

bool
XCodecEncoder::encode_reference(Buffer *output, Buffer *input, unsigned offset, uint64_t hash, BufferSegment *oseg)
{
	uint8_t data[XCODEC_SEGMENT_LENGTH];
	input->copyout(data, offset, sizeof data);

	if (oseg->match(data, sizeof data)) {
		if (offset != 0) {
			Buffer prefix;
			input->moveout(&prefix, 0, offset);

			prefix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
			output->append(prefix);
			prefix.clear();
		}

		/*
		 * Skip to the end.
		 */
		input->skip(XCODEC_SEGMENT_LENGTH);

		/*
		 * And output a reference.
		 */
		uint8_t b;
		if (window_.present(hash, &b)) {
			output->append(XCODEC_BACKREF_CHAR);
			output->append(b);
		} else {
			output->append(XCODEC_HASHREF_CHAR);
			uint64_t lehash = LittleEndian::encode(hash);
			output->append((const uint8_t *)&lehash, sizeof lehash);

			window_.declare(hash, oseg);
		}

		return (true);
	}
	return (false);
}
<commit_msg>Make encode_reference look more like encode_declaration.<commit_after>#include <common/buffer.h>
#include <common/endian.h>

#include <xcodec/xcodec.h>
#include <xcodec/xcodec_cache.h>
#include <xcodec/xcodec_encoder.h>
#include <xcodec/xcodec_hash.h>

typedef	std::pair<unsigned, uint64_t> offset_hash_pair_t;

struct xcodec_special_p {
	bool operator() (uint8_t ch) const
	{
		return (XCODEC_CHAR_SPECIAL(ch));
	}
};

XCodecEncoder::XCodecEncoder(XCodec *codec)
: log_("/xcodec/encoder"),
  cache_(codec->cache_),
  window_()
{ }

XCodecEncoder::~XCodecEncoder()
{ }

/*
 * This takes a view of a data stream and turns it into a series of references
 * to other data, declarations of data to be referenced, and data that needs
 * escaped.
 */
void
XCodecEncoder::encode(Buffer *output, Buffer *input)
{
	if (input->length() < XCODEC_SEGMENT_LENGTH) {
		input->escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
		output->append(input);
		input->clear();
		return;
	}

	XCodecHash<XCODEC_SEGMENT_LENGTH> xcodec_hash;
	std::deque<offset_hash_pair_t> offset_hash_map;
	Buffer outq;
	unsigned o = 0;

	while (!input->empty()) {
		BufferSegment *seg;
		input->moveout(&seg);

		outq.append(seg);

		const uint8_t *p;
		for (p = seg->data(); p < seg->end(); p++) {
			xcodec_hash.roll(*p);
			if (++o < XCODEC_SEGMENT_LENGTH)
				continue;

			unsigned start = o - XCODEC_SEGMENT_LENGTH;
			uint64_t hash = xcodec_hash.mix();
			bool hash_collision;

			BufferSegment *oseg = cache_->lookup(hash);
			if (oseg != NULL) {
				/*
				 * This segment already exists.  If it's
				 * identical to this chunk of data, then that's
				 * positively fantastic.
				 */
				if (encode_reference(output, &outq, start, hash, oseg)) {
					oseg->unref();
					o = 0;
					offset_hash_map.clear();
					continue;
				}
				oseg->unref();
				DEBUG(log_) << "Collision in first pass.";
				hash_collision = true;

				/*
				 * Fall through to defining the previous hash if
				 * it is appropriate to do so.
				 */
			} else {
				hash_collision = false;
			}

			if (!offset_hash_map.empty()) {
				/*
				 * If there is a previous hash in the
				 * offset-hash map that would overlap with this
				 * hash, then we have no reason to remember this
				 * hash for later.
				 */
				const offset_hash_pair_t& last = offset_hash_map.back();

				if (last.first + XCODEC_SEGMENT_LENGTH > start) {
					/* We might still find an alternative.  */
					continue;
				}

				BufferSegment *nseg;
				encode_declaration(output, &outq, last.first, last.second, &nseg);

				o -= last.first + XCODEC_SEGMENT_LENGTH;
				start = o - XCODEC_SEGMENT_LENGTH;

				uint64_t ohash = last.second;
				offset_hash_map.clear();

				/*
				 * If this hash is the same as the has for
				 * the current data, then make sure that they
				 * are compatible before remembering the
				 * current hash
				 */
				if (!hash_collision && hash == ohash) {
					if (!encode_reference(output, &outq, start, hash, nseg)) {
						nseg->unref();
						DEBUG(log_) << "Collision in adjacent-declare pass.";
						continue;
					}
					nseg->unref();

					DEBUG(log_) << "Hit in adjacent-declare pass.";

					o = 0;
					continue;
				}
				nseg->unref();

				/*
				 * Remember the current hash.
				 */
			}

			/*
			 * No collision, remember this for later.
			 */
			if (!hash_collision) {
				offset_hash_pair_t ohp;
				ohp.first = start;
				ohp.second = hash;
				offset_hash_map.push_back(ohp);
			}

		}

		seg->unref();
	}

	/*
	 * There's a hash we can declare, do it.
	 */
	if (!offset_hash_map.empty()) {
		ASSERT(!outq.empty());
		const offset_hash_pair_t& last = offset_hash_map.back();

		encode_declaration(output, &outq, last.first, last.second, NULL);
		offset_hash_map.clear();
	}

	if (!outq.empty()) {
		Buffer suffix(outq);
		outq.clear();

		suffix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());

		output->append(suffix);
		outq.clear();
	}

	ASSERT(offset_hash_map.empty());
	ASSERT(outq.empty());
	ASSERT(input->empty());
}

void
XCodecEncoder::encode_declaration(Buffer *output, Buffer *input, unsigned offset, uint64_t hash, BufferSegment **segp)
{
	if (offset != 0) {
		Buffer prefix;
		input->moveout(&prefix, 0, offset);

		prefix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
		output->append(prefix);
		prefix.clear();
	}

	BufferSegment *nseg;
	input->copyout(&nseg, XCODEC_SEGMENT_LENGTH);

	cache_->enter(hash, nseg);

	output->append(XCODEC_DECLARE_CHAR);
	uint64_t lehash = LittleEndian::encode(hash);
	output->append((const uint8_t *)&lehash, sizeof lehash);
	output->append(nseg);

	window_.declare(hash, nseg);
	if (segp == NULL)
		nseg->unref();

	/*
	 * Skip to the end.
	 */
	input->skip(XCODEC_SEGMENT_LENGTH);

	/*
	 * And output a reference.
	 */
	uint8_t b;
	if (window_.present(hash, &b)) {
		output->append(XCODEC_BACKREF_CHAR);
		output->append(b);
	} else {
		NOTREACHED();
	}

	if (segp != NULL)
		*segp = nseg;
}

bool
XCodecEncoder::encode_reference(Buffer *output, Buffer *input, unsigned offset, uint64_t hash, BufferSegment *oseg)
{
	uint8_t data[XCODEC_SEGMENT_LENGTH];
	input->copyout(data, offset, sizeof data);

	if (!oseg->match(data, sizeof data))
		return (false);

	if (offset != 0) {
		Buffer prefix;
		input->moveout(&prefix, 0, offset);

		prefix.escape(XCODEC_ESCAPE_CHAR, xcodec_special_p());
		output->append(prefix);
		prefix.clear();
	}

	/*
	 * Skip to the end.
	 */
	input->skip(XCODEC_SEGMENT_LENGTH);

	/*
	 * And output a reference.
	 */
	uint8_t b;
	if (window_.present(hash, &b)) {
		output->append(XCODEC_BACKREF_CHAR);
		output->append(b);
	} else {
		output->append(XCODEC_HASHREF_CHAR);
		uint64_t lehash = LittleEndian::encode(hash);
		output->append((const uint8_t *)&lehash, sizeof lehash);

		window_.declare(hash, oseg);
	}

	return (true);
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;
int main (){

}
<commit_msg>Empezado ejercicio 12<commit_after>#include <iostream>
#include <cmath>
using namespace std;
int main (){

  double media=0, desviacion=0, gaussiana=0;
  const PI = 3.1415927;
}
<|endoftext|>


<commit_before>#include <memory>

#include "drake/Path.h"
#include "drake/systems/plants/RigidBodyTree.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace drake {
namespace systems {
namespace plants {
namespace test {
namespace {

using Eigen::Vector3d;
using Eigen::VectorXd;
using Eigen::Matrix3Xd;
using DrakeCollision::ElementId;

// Structure used to hold the analytical solution of the tests.
// It stores the collision point on the surface of a collision body in both
// world and body frames.
// See systems/plants/collision/test/model_test.cc.
struct SurfacePoint {
  SurfacePoint() {}
  SurfacePoint(Vector3d wf, Vector3d bf) : world_frame(wf), body_frame(bf) {}
  // Eigen variables are left uninitalized by default.
  Vector3d world_frame;
  Vector3d body_frame;
};

// Solutions are accessed by collision element id using an std::unordered_set.
// See detailed explanation in systems/plants/collision/test/model_test.cc.
typedef std::unordered_map<DrakeCollision::ElementId, SurfacePoint>
    ElementToSurfacePointMap;

class RBTCollisionTest: public ::testing::Test {
 protected:
  void SetUp() override {
    tree_.addRobotFromSDF(
        Drake::getDrakePath() +
            "/systems/plants/test/rigid_body_tree/small_box_on_large_box.sdf",
        DrakeJoint::QUATERNION);

    small_box_id_ = tree_.findLink("small_box")->collision_element_ids[0];
    large_box_id_ = tree_.findLink("large_box")->collision_element_ids[0];

    // Access the analytical solution to the contact point on the surface of
    // each collision element by element id.
    // Solutions are expressed in world and body frames.
    solution_ = {
        /*              world frame    , body frame  */
        {large_box_id_, {{0.0, 5.0, 0.0}, {0.0,  2.5, 0.0}}},
        {small_box_id_, {{0.0, 4.9, 0.0}, {0.0,  0.0, 0.6}}}};
  }

  double tolerance_;
  RigidBodyTree tree_;
  ElementId small_box_id_, large_box_id_;
  ElementToSurfacePointMap solution_;
};

TEST_F(RBTCollisionTest, FindAndComputeContactPoints) {
  // Numerical precision tolerance to perform floating point comparisons.
  // Its magnitude was chosen to be the minimum value for which these tests can
  // successfully pass.
  tolerance_ = 4.0e-16;

  int nq = tree_.number_of_positions();
  int nv = tree_.number_of_velocities();
  int num_states = nq + nv;
  VectorXd x = VectorXd::Zero(num_states);
  x.head(nq) = tree_.getZeroConfiguration();

  auto q = x.topRows(nq);
  auto v = x.bottomRows(nv);

  KinematicsCache<double> kinsol = tree_.doKinematics(q, v);

  VectorXd phi;
  Matrix3Xd normal, xA, xB;
  std::vector<int> bodyA_idx, bodyB_idx;

  tree_.ComputeMaximumDepthCollisionPoints(
      kinsol, phi, normal, xA, xB, bodyA_idx, bodyB_idx, false);

  ElementId bodyA_collision_element_id =
      tree_.bodies[bodyA_idx[0]]->collision_element_ids[0];
  ElementId bodyB_collision_element_id =
      tree_.bodies[bodyB_idx[0]]->collision_element_ids[0];

  // RigidBodyTree::ComputeMaximumDepthCollisionPoints returns only one point,
  // the maximum depth collision point.
  ASSERT_EQ(1, phi.size());
  EXPECT_NEAR(-0.1, phi(0), tolerance_);
  EXPECT_TRUE(normal.col(0).isApprox(Vector3d(0.0, -1.0, 0.0)));
  // Collision points are reported on each of the respective bodies' frames.
  // Only test for vertical position.
  EXPECT_NEAR(xA.col(0).y(),
              solution_[bodyA_collision_element_id].body_frame.y(), tolerance_);
  // In body's frame, which is rotated 90 degrees in pitch from
  // collision_test.sdf, the collision point is on the z-axis.
  // In addition, is not at z=0.5 but at z=0.6 since there is an offset of 0.1
  // in body's z-axis for the collision element as set from collision_test.sdf.
  EXPECT_NEAR(xB.col(0).z(),
              solution_[bodyB_collision_element_id].body_frame.z(), tolerance_);
}

}  // namespace
}  // namespace test
}  // namespace plants
}  // namespace systems
}  // namespace drake
<commit_msg>Updates namespaces<commit_after>#include <memory>

#include "drake/Path.h"
#include "drake/systems/plants/RigidBodyTree.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace drake {
namespace systems {
namespace plants {
namespace test {
namespace rigid_body_tree {
namespace {

using Eigen::Vector3d;
using Eigen::VectorXd;
using Eigen::Matrix3Xd;
using DrakeCollision::ElementId;

// Structure used to hold the analytical solution of the tests.
// It stores the collision point on the surface of a collision body in both
// world and body frames.
// See systems/plants/collision/test/model_test.cc.
struct SurfacePoint {
  SurfacePoint() { }
  SurfacePoint(Vector3d wf, Vector3d bf) : world_frame(wf), body_frame(bf) { }
  // Eigen variables are left uninitalized by default.
  Vector3d world_frame;
  Vector3d body_frame;
};

// Solutions are accessed by collision element id using an std::unordered_set.
// See detailed explanation in systems/plants/collision/test/model_test.cc.
typedef std::unordered_map<DrakeCollision::ElementId, SurfacePoint>
    ElementToSurfacePointMap;

class RBTCollisionTest: public ::testing::Test {
 protected:
  void SetUp() override {
    tree_.addRobotFromSDF(
        Drake::getDrakePath() +
            "/systems/plants/test/rigid_body_tree/small_box_on_large_box.sdf",
        DrakeJoint::QUATERNION);

    small_box_id_ = tree_.findLink("small_box")->collision_element_ids[0];
    large_box_id_ = tree_.findLink("large_box")->collision_element_ids[0];

    // Access the analytical solution to the contact point on the surface of
    // each collision element by element id.
    // Solutions are expressed in world and body frames.
    solution_ = {
        /*              world frame    , body frame  */
        {large_box_id_, {{0.0, 5.0, 0.0}, {0.0, 2.5, 0.0}}},
        {small_box_id_, {{0.0, 4.9, 0.0}, {0.0, 0.0, 0.6}}}};
  }

  double tolerance_;
  RigidBodyTree tree_;
  ElementId small_box_id_, large_box_id_;
  ElementToSurfacePointMap solution_;
};

TEST_F(RBTCollisionTest, FindAndComputeContactPoints) {
  // Numerical precision tolerance to perform floating point comparisons.
  // Its magnitude was chosen to be the minimum value for which these tests can
  // successfully pass.
  tolerance_ = 4.0e-16;

  int nq = tree_.number_of_positions();
  int nv = tree_.number_of_velocities();
  int num_states = nq + nv;
  VectorXd x = VectorXd::Zero(num_states);
  x.head(nq) = tree_.getZeroConfiguration();

  auto q = x.topRows(nq);
  auto v = x.bottomRows(nv);

  KinematicsCache<double> kinsol = tree_.doKinematics(q, v);

  VectorXd phi;
  Matrix3Xd normal, xA, xB;
  std::vector<int> bodyA_idx, bodyB_idx;

  tree_.ComputeMaximumDepthCollisionPoints(
      kinsol, phi, normal, xA, xB, bodyA_idx, bodyB_idx, false);

  ElementId bodyA_collision_element_id =
      tree_.bodies[bodyA_idx[0]]->collision_element_ids[0];
  ElementId bodyB_collision_element_id =
      tree_.bodies[bodyB_idx[0]]->collision_element_ids[0];

  // RigidBodyTree::ComputeMaximumDepthCollisionPoints returns only one point,
  // the maximum depth collision point.
  ASSERT_EQ(1, phi.size());
  EXPECT_NEAR(-0.1, phi(0), tolerance_);
  EXPECT_TRUE(normal.col(0).isApprox(Vector3d(0.0, -1.0, 0.0)));
  // Collision points are reported on each of the respective bodies' frames.
  // Only test for vertical position.
  EXPECT_NEAR(xA.col(0).y(),
              solution_[bodyA_collision_element_id].body_frame.y(), tolerance_);
  // In body's frame, which is rotated 90 degrees in pitch from
  // collision_test.sdf, the collision point is on the z-axis.
  // In addition, is not at z=0.5 but at z=0.6 since there is an offset of 0.1
  // in body's z-axis for the collision element as set from collision_test.sdf.
  EXPECT_NEAR(xB.col(0).z(),
              solution_[bodyB_collision_element_id].body_frame.z(), tolerance_);
}

}  // namespace
}  // namespace rigid_body_tree
}  // namespace test
}  // namespace plants
}  // namespace systems
}  // namespace drake
<|endoftext|>