<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "Node.h"
#include "core/Engine.h"
#include "SceneManager.h"
#include "Layer.h"
#include "animators/Animator.h"
#include "Camera.h"
#include "utils/Utils.h"
#include "math/MathUtils.h"
#include "Component.h"

namespace ouzel
{
    namespace scene
    {
        Node::Node()
        {
            animationUpdateCallback.callback = std::bind(&Node::updateAnimation, this, std::placeholders::_1);
        }

        Node::~Node()
        {
            if (currentAnimator) currentAnimator->parentNode = nullptr;

            for (Component* component : components)
            {
                component->node = nullptr;
            }

            for (Node* child : children)
            {
                child->parent = nullptr;
            }

            if (parent) parent->removeChild(this);
        }

        void Node::visit(std::vector<Node*>& drawQueue,
                         const Matrix4& newParentTransform,
                         bool parentTransformDirty,
                         Camera* camera,
                         int32_t parentOrder,
                         bool parentHidden)
        {
            worldOrder = parentOrder + order;
            worldHidden = parentHidden || hidden;

            if (parentTransformDirty)
            {
                updateTransform(newParentTransform);
            }

            if (transformDirty)
            {
                calculateTransform();
            }

            if (!worldHidden)
            {
                Box3 boundingBox = getBoundingBox();

                if (cullDisabled || (!boundingBox.isEmpty() && camera->checkVisibility(getTransform(), boundingBox)))
                {
                    auto upperBound = std::upper_bound(drawQueue.begin(), drawQueue.end(), this,
                                                       [](Node* a, Node* b) {
                                                           return a->worldOrder > b->worldOrder;
                                                       });

                    drawQueue.insert(upperBound, this);
                }
            }

            for (Node* child : children)
            {
                child->visit(drawQueue, transform, updateChildrenTransform, camera, worldOrder, worldHidden);
            }

            updateChildrenTransform = false;
        }

        void Node::draw(Camera* camera)
        {
            if (transformDirty)
            {
                calculateTransform();
            }

            Color drawColor(color.v[0], color.v[1], color.v[2], static_cast<uint8_t>(color.v[3] * opacity));

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    component->draw(transform, drawColor, camera);
                }
            }
        }

        void Node::drawWireframe(Camera* camera)
        {
            if (transformDirty)
            {
                calculateTransform();
            }

            Color drawColor(color.v[0], color.v[1], color.v[2], 255);

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    component->drawWireframe(transform, drawColor, camera);
                }
            }
        }

        void Node::addChild(Node* node)
        {
            NodeContainer::addChild(node);

            if (node)
            {
                node->updateTransform(getTransform());
            }
        }

        void Node::removeFromParent()
        {
            if (parent)
            {
                parent->removeChild(this);
            }
        }

        void Node::setPosition(const Vector2& newPosition)
        {
            if (position.v[0] != newPosition.v[0] ||
                position.v[1] != newPosition.v[1])
            {
                position.v[0] = newPosition.v[0];
                position.v[1] = newPosition.v[1];

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setPosition(const Vector3& newPosition)
        {
            if (position != newPosition)
            {
                position = newPosition;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setRotation(const Quaternion& newRotation)
        {
            if (rotation != newRotation)
            {
                rotation = newRotation;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setRotation(const Vector3& newRotation)
        {
            Quaternion roationQuaternion;
            roationQuaternion.setEulerAngles(newRotation);

            if (rotation != roationQuaternion)
            {
                rotation = roationQuaternion;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setRotation(float newRotation)
        {
            Quaternion roationQuaternion;
            roationQuaternion.rotate(newRotation, Vector3(0.0f, 0.0f, 1.0f));

            if (rotation != roationQuaternion)
            {
                rotation = roationQuaternion;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setScale(const Vector2& newScale)
        {
            if (scale.v[0] != newScale.v[0] ||
                scale.v[1] != newScale.v[1])
            {
                scale.v[0] = newScale.v[0];
                scale.v[1] = newScale.v[1];

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setScale(const Vector3& newScale)
        {
            if (scale != newScale)
            {
                scale = newScale;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setColor(const Color& newColor)
        {
            color = newColor;
        }

        void Node::setOpacity(float newOpacity)
        {
            opacity = clamp(newOpacity, 0.0f, 1.0f);
        }

        void Node::setFlipX(bool newFlipX)
        {
            if (flipX != newFlipX)
            {
                flipX = newFlipX;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setFlipY(bool newFlipY)
        {
            if (flipY != newFlipY)
            {
                flipY = newFlipY;

                localTransformDirty = transformDirty = inverseTransformDirty = true;
            }
        }

        void Node::setHidden(bool newHidden)
        {
            hidden = newHidden;
        }

        bool Node::pointOn(const Vector2& worldPosition) const
        {
            Vector2 localPosition = convertWorldToLocal(worldPosition);

            for (Component* component : components)
            {
                if (component->pointOn(localPosition))
                {
                    return true;
                }
            }

            return false;
        }

        bool Node::shapeOverlaps(const std::vector<Vector2>& edges) const
        {
            Matrix4 inverse = getInverseTransform();

            std::vector<Vector2> transformedEdges;

            for (const Vector2& edge : edges)
            {
                Vector3 transformedEdge = edge;

                inverse.transformPoint(transformedEdge);

                transformedEdges.push_back(Vector2(transformedEdge.v[0], transformedEdge.v[1]));
            }

            for (Component* component : components)
            {
                if (component->shapeOverlaps(transformedEdges))
                {
                    return true;
                }
            }

            return false;
        }

        void Node::updateTransform(const Matrix4& newParentTransform)
        {
            parentTransform = newParentTransform;
            transformDirty = inverseTransformDirty = true;
        }

        Vector3 Node::getWorldPosition() const
        {
            Vector3 result = position;
            getTransform().transformPoint(result);

            return position;
        }

        Vector3 Node::convertWorldToLocal(const Vector3& worldPosition) const
        {
            Vector3 localPosition = worldPosition;

            const Matrix4& currentInverseTransform = getInverseTransform();
            currentInverseTransform.transformPoint(localPosition);

            return localPosition;
        }

        Vector3 Node::convertLocalToWorld(const Vector3& localPosition) const
        {
            Vector3 worldPosition = localPosition;

            const Matrix4& currentTransform = getTransform();
            currentTransform.transformPoint(worldPosition);

            return worldPosition;
        }

        void Node::animate(Animator* animator)
        {
            if (currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
            }

            currentAnimator = animator;

            if (currentAnimator)
            {
                currentAnimator->removeFromParent();
                currentAnimator->parentNode = this;
                currentAnimator->start(this);
            }

            sharedEngine->scheduleUpdate(&animationUpdateCallback);
        }

        void Node::removeAnimator(Animator* animator)
        {
            if (animator && animator == currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
                currentAnimator = nullptr;
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        void Node::removeCurrentAnimator()
        {
            if (currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
                currentAnimator = nullptr;
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        void Node::calculateLocalTransform() const
        {
            localTransform.setIdentity();
            localTransform.translate(position);
            localTransform *= rotation.getMatrix();

            Vector3 realScale = Vector3(scale.v[0] * (flipX ? -1.0f : 1.0f),
                                        scale.v[1] * (flipY ? -1.0f : 1.0f),
                                        scale.v[2]);

            localTransform.scale(realScale);

            localTransformDirty = false;
        }

        void Node::calculateTransform() const
        {
            transform = parentTransform * getLocalTransform();
            transformDirty = false;

            updateChildrenTransform = true;
        }

        void Node::calculateInverseTransform() const
        {
            inverseTransform = getTransform();
            inverseTransform.invert();
            inverseTransformDirty = false;
        }

        void Node::addComponent(Component* component)
        {
            Node* oldNode = component->node;

            if (oldNode)
            {
                oldNode->removeComponent(component);
            }

            component->node = this;
            components.push_back(component);
        }

        bool Node::removeComponent(uint32_t index)
        {
            if (index >= components.size())
            {
                return false;
            }

            Component* component = components[index];
            component->node = nullptr;

            components.erase(components.begin() + static_cast<int>(index));

            return true;
        }

        bool Node::removeComponent(Component* component)
        {
            for (auto i = components.begin(); i != components.end();)
            {
                if (*i == component)
                {
                    component->node = nullptr;
                    components.erase(i);
                    return true;
                }
                else
                {
                    ++i;
                }
            }

            return false;
        }

        void Node::removeAllComponents()
        {
            components.clear();
        }

        void Node::updateAnimation(float delta)
        {
            if (currentAnimator)
            {
                currentAnimator->update(delta);

                if (currentAnimator->isDone())
                {
                    removeCurrentAnimator();
                    sharedEngine->unscheduleUpdate(&animationUpdateCallback);
                }
            }
            else
            {
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        Box3 Node::getBoundingBox() const
        {
            Box3 boundingBox;

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    boundingBox.merge(component->getBoundingBox());
                }
            }

            return boundingBox;
        }
    } // namespace scene
} // namespace ouzel
<commit_msg>Remove if checks from Node’s setters<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "Node.h"
#include "core/Engine.h"
#include "SceneManager.h"
#include "Layer.h"
#include "animators/Animator.h"
#include "Camera.h"
#include "utils/Utils.h"
#include "math/MathUtils.h"
#include "Component.h"

namespace ouzel
{
    namespace scene
    {
        Node::Node()
        {
            animationUpdateCallback.callback = std::bind(&Node::updateAnimation, this, std::placeholders::_1);
        }

        Node::~Node()
        {
            if (currentAnimator) currentAnimator->parentNode = nullptr;

            for (Component* component : components)
            {
                component->node = nullptr;
            }

            for (Node* child : children)
            {
                child->parent = nullptr;
            }

            if (parent) parent->removeChild(this);
        }

        void Node::visit(std::vector<Node*>& drawQueue,
                         const Matrix4& newParentTransform,
                         bool parentTransformDirty,
                         Camera* camera,
                         int32_t parentOrder,
                         bool parentHidden)
        {
            worldOrder = parentOrder + order;
            worldHidden = parentHidden || hidden;

            if (parentTransformDirty)
            {
                updateTransform(newParentTransform);
            }

            if (transformDirty)
            {
                calculateTransform();
            }

            if (!worldHidden)
            {
                Box3 boundingBox = getBoundingBox();

                if (cullDisabled || (!boundingBox.isEmpty() && camera->checkVisibility(getTransform(), boundingBox)))
                {
                    auto upperBound = std::upper_bound(drawQueue.begin(), drawQueue.end(), this,
                                                       [](Node* a, Node* b) {
                                                           return a->worldOrder > b->worldOrder;
                                                       });

                    drawQueue.insert(upperBound, this);
                }
            }

            for (Node* child : children)
            {
                child->visit(drawQueue, transform, updateChildrenTransform, camera, worldOrder, worldHidden);
            }

            updateChildrenTransform = false;
        }

        void Node::draw(Camera* camera)
        {
            if (transformDirty)
            {
                calculateTransform();
            }

            Color drawColor(color.v[0], color.v[1], color.v[2], static_cast<uint8_t>(color.v[3] * opacity));

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    component->draw(transform, drawColor, camera);
                }
            }
        }

        void Node::drawWireframe(Camera* camera)
        {
            if (transformDirty)
            {
                calculateTransform();
            }

            Color drawColor(color.v[0], color.v[1], color.v[2], 255);

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    component->drawWireframe(transform, drawColor, camera);
                }
            }
        }

        void Node::addChild(Node* node)
        {
            NodeContainer::addChild(node);

            if (node)
            {
                node->updateTransform(getTransform());
            }
        }

        void Node::removeFromParent()
        {
            if (parent)
            {
                parent->removeChild(this);
            }
        }

        void Node::setPosition(const Vector2& newPosition)
        {
            position.v[0] = newPosition.v[0];
            position.v[1] = newPosition.v[1];

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setPosition(const Vector3& newPosition)
        {
            position = newPosition;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setRotation(const Quaternion& newRotation)
        {
            rotation = newRotation;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setRotation(const Vector3& newRotation)
        {
            Quaternion roationQuaternion;
            roationQuaternion.setEulerAngles(newRotation);

            rotation = roationQuaternion;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setRotation(float newRotation)
        {
            Quaternion roationQuaternion;
            roationQuaternion.rotate(newRotation, Vector3(0.0f, 0.0f, 1.0f));

            rotation = roationQuaternion;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setScale(const Vector2& newScale)
        {
            scale.v[0] = newScale.v[0];
            scale.v[1] = newScale.v[1];

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setScale(const Vector3& newScale)
        {
            scale = newScale;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setColor(const Color& newColor)
        {
            color = newColor;
        }

        void Node::setOpacity(float newOpacity)
        {
            opacity = clamp(newOpacity, 0.0f, 1.0f);
        }

        void Node::setFlipX(bool newFlipX)
        {
            flipX = newFlipX;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setFlipY(bool newFlipY)
        {
            flipY = newFlipY;

            localTransformDirty = transformDirty = inverseTransformDirty = true;
        }

        void Node::setHidden(bool newHidden)
        {
            hidden = newHidden;
        }

        bool Node::pointOn(const Vector2& worldPosition) const
        {
            Vector2 localPosition = convertWorldToLocal(worldPosition);

            for (Component* component : components)
            {
                if (component->pointOn(localPosition))
                {
                    return true;
                }
            }

            return false;
        }

        bool Node::shapeOverlaps(const std::vector<Vector2>& edges) const
        {
            Matrix4 inverse = getInverseTransform();

            std::vector<Vector2> transformedEdges;

            for (const Vector2& edge : edges)
            {
                Vector3 transformedEdge = edge;

                inverse.transformPoint(transformedEdge);

                transformedEdges.push_back(Vector2(transformedEdge.v[0], transformedEdge.v[1]));
            }

            for (Component* component : components)
            {
                if (component->shapeOverlaps(transformedEdges))
                {
                    return true;
                }
            }

            return false;
        }

        void Node::updateTransform(const Matrix4& newParentTransform)
        {
            parentTransform = newParentTransform;
            transformDirty = inverseTransformDirty = true;
        }

        Vector3 Node::getWorldPosition() const
        {
            Vector3 result = position;
            getTransform().transformPoint(result);

            return position;
        }

        Vector3 Node::convertWorldToLocal(const Vector3& worldPosition) const
        {
            Vector3 localPosition = worldPosition;

            const Matrix4& currentInverseTransform = getInverseTransform();
            currentInverseTransform.transformPoint(localPosition);

            return localPosition;
        }

        Vector3 Node::convertLocalToWorld(const Vector3& localPosition) const
        {
            Vector3 worldPosition = localPosition;

            const Matrix4& currentTransform = getTransform();
            currentTransform.transformPoint(worldPosition);

            return worldPosition;
        }

        void Node::animate(Animator* animator)
        {
            if (currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
            }

            currentAnimator = animator;

            if (currentAnimator)
            {
                currentAnimator->removeFromParent();
                currentAnimator->parentNode = this;
                currentAnimator->start(this);
            }

            sharedEngine->scheduleUpdate(&animationUpdateCallback);
        }

        void Node::removeAnimator(Animator* animator)
        {
            if (animator && animator == currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
                currentAnimator = nullptr;
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        void Node::removeCurrentAnimator()
        {
            if (currentAnimator)
            {
                currentAnimator->parentNode = nullptr;
                currentAnimator->stop();
                currentAnimator = nullptr;
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        void Node::calculateLocalTransform() const
        {
            localTransform.setIdentity();
            localTransform.translate(position);
            localTransform *= rotation.getMatrix();

            Vector3 realScale = Vector3(scale.v[0] * (flipX ? -1.0f : 1.0f),
                                        scale.v[1] * (flipY ? -1.0f : 1.0f),
                                        scale.v[2]);

            localTransform.scale(realScale);

            localTransformDirty = false;
        }

        void Node::calculateTransform() const
        {
            transform = parentTransform * getLocalTransform();
            transformDirty = false;

            updateChildrenTransform = true;
        }

        void Node::calculateInverseTransform() const
        {
            inverseTransform = getTransform();
            inverseTransform.invert();
            inverseTransformDirty = false;
        }

        void Node::addComponent(Component* component)
        {
            Node* oldNode = component->node;

            if (oldNode)
            {
                oldNode->removeComponent(component);
            }

            component->node = this;
            components.push_back(component);
        }

        bool Node::removeComponent(uint32_t index)
        {
            if (index >= components.size())
            {
                return false;
            }

            Component* component = components[index];
            component->node = nullptr;

            components.erase(components.begin() + static_cast<int>(index));

            return true;
        }

        bool Node::removeComponent(Component* component)
        {
            for (auto i = components.begin(); i != components.end();)
            {
                if (*i == component)
                {
                    component->node = nullptr;
                    components.erase(i);
                    return true;
                }
                else
                {
                    ++i;
                }
            }

            return false;
        }

        void Node::removeAllComponents()
        {
            components.clear();
        }

        void Node::updateAnimation(float delta)
        {
            if (currentAnimator)
            {
                currentAnimator->update(delta);

                if (currentAnimator->isDone())
                {
                    removeCurrentAnimator();
                    sharedEngine->unscheduleUpdate(&animationUpdateCallback);
                }
            }
            else
            {
                sharedEngine->unscheduleUpdate(&animationUpdateCallback);
            }
        }

        Box3 Node::getBoundingBox() const
        {
            Box3 boundingBox;

            for (Component* component : components)
            {
                if (!component->isHidden())
                {
                    boundingBox.merge(component->getBoundingBox());
                }
            }

            return boundingBox;
        }
    } // namespace scene
} // namespace ouzel
<|endoftext|>


<commit_before><commit_msg>change include file of test_traits<commit_after><|endoftext|>


<commit_before>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/aec3/block_processor.h"

#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
#include "rtc_base/checks.h"
#include "rtc_base/random.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using testing::AtLeast;
using testing::Return;
using testing::StrictMock;
using testing::_;

// Verifies that the basic BlockProcessor functionality works and that the API
// methods are callable.
void RunBasicSetupAndApiCallTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(NumBandsForRate(sample_rate_hz),
                                        std::vector<float>(kBlockSize, 0.f));

  block_processor->BufferRender(block);
  block_processor->ProcessCapture(false, false, &block);
  block_processor->UpdateEchoLeakageStatus(false);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

  EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
}

void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

  EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
}
#endif

std::string ProduceDebugText(int sample_rate_hz) {
  std::ostringstream ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.str();
}

}  // namespace

// Verifies that the delay controller functionality is properly integrated with
// the render delay buffer inside block processor.
// TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
  constexpr size_t kNumBlocks = 310;
  constexpr size_t kDelayInSamples = 640;
  constexpr size_t kDelayHeadroom = 1;
  constexpr size_t kDelayInBlocks =
      kDelayInSamples / kBlockSize - kDelayHeadroom;
  Random random_generator(42U);
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(kDelayInBlocks))
        .Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks + 1)
        .WillRepeatedly(Return(0));
    std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
        EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
    }
  }
}

// Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
  constexpr size_t kNumBlocks = 310;
  Random random_generator(42U);
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
    std::unique_ptr<
        testing::StrictMock<webrtc::test::MockRenderDelayController>>
        render_delay_controller_mock(
            new StrictMock<webrtc::test::MockRenderDelayController>());
    std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
        echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());

    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks - 1)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, PrepareCaptureProcessing())
        .Times(kNumBlocks);
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(9)).Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks)
        .WillRepeatedly(Return(0));
    EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
        .Times(kNumBlocks);

    std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
        EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock),
        std::move(render_delay_controller_mock), std::move(echo_remover_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(640);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
      block_processor->UpdateEchoLeakageStatus(false);
    }
  }
}

TEST(BlockProcessor, BasicSetupAndApiCalls) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunBasicSetupAndApiCallTest(rate);
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
// DEATH tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_VerifyRenderBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyCaptureBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderNumBandsVerificationTest(rate);
  }
}

// TODO(peah): Verify the check for correct number of bands in the capture
// signal.
TEST(BlockProcessor, VerifyCaptureNumBandsCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureNumBandsVerificationTest(rate);
  }
}

// Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessor, NullProcessCaptureParameter) {
  EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8000))
                   ->ProcessCapture(false, false, nullptr),
               "");
}

// Verifies the check for correct sample rate.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
  EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8001)),
               "");
}

#endif

}  // namespace webrtc
<commit_msg>Added unittest to the AEC3 BlockProcessor class that tests longer calls<commit_after>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/aec3/block_processor.h"

#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
#include "rtc_base/checks.h"
#include "rtc_base/random.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using testing::AtLeast;
using testing::Return;
using testing::StrictMock;
using testing::_;

// Verifies that the basic BlockProcessor functionality works and that the API
// methods are callable.
void RunBasicSetupAndApiCallTest(int sample_rate_hz, int num_iterations) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(NumBandsForRate(sample_rate_hz),
                                        std::vector<float>(kBlockSize, 1000.f));

  for (int k = 0; k < num_iterations; ++k) {
    block_processor->BufferRender(block);
    block_processor->ProcessCapture(false, false, &block);
    block_processor->UpdateEchoLeakageStatus(false);
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

  EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
}

void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

  EXPECT_DEATH(block_processor->ProcessCapture(false, false, &block), "");
}
#endif

std::string ProduceDebugText(int sample_rate_hz) {
  std::ostringstream ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.str();
}

}  // namespace

// Verifies that the delay controller functionality is properly integrated with
// the render delay buffer inside block processor.
// TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
  constexpr size_t kNumBlocks = 310;
  constexpr size_t kDelayInSamples = 640;
  constexpr size_t kDelayHeadroom = 1;
  constexpr size_t kDelayInBlocks =
      kDelayInSamples / kBlockSize - kDelayHeadroom;
  Random random_generator(42U);
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(kDelayInBlocks))
        .Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks + 1)
        .WillRepeatedly(Return(0));
    std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
        EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
    }
  }
}

// Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
  constexpr size_t kNumBlocks = 310;
  Random random_generator(42U);
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate));
    std::unique_ptr<
        testing::StrictMock<webrtc::test::MockRenderDelayController>>
        render_delay_controller_mock(
            new StrictMock<webrtc::test::MockRenderDelayController>());
    std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
        echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());

    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks - 1)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, PrepareCaptureProcessing())
        .Times(kNumBlocks);
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(9)).Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks)
        .WillRepeatedly(Return(0));
    EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
        .Times(kNumBlocks);

    std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
        EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock),
        std::move(render_delay_controller_mock), std::move(echo_remover_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(640);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
      block_processor->UpdateEchoLeakageStatus(false);
    }
  }
}

TEST(BlockProcessor, BasicSetupAndApiCalls) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunBasicSetupAndApiCallTest(rate, 1);
  }
}

TEST(BlockProcessor, TestLongerCall) {
  RunBasicSetupAndApiCallTest(16000, 20 * kNumBlocksPerSecond);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
// DEATH tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_VerifyRenderBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyCaptureBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderNumBandsVerificationTest(rate);
  }
}

// TODO(peah): Verify the check for correct number of bands in the capture
// signal.
TEST(BlockProcessor, VerifyCaptureNumBandsCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureNumBandsVerificationTest(rate);
  }
}

// Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessor, NullProcessCaptureParameter) {
  EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8000))
                   ->ProcessCapture(false, false, nullptr),
               "");
}

// Verifies the check for correct sample rate.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
  EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8001)),
               "");
}

#endif

}  // namespace webrtc
<|endoftext|>


<commit_before>draw() {
  drawBackgroundPattern();
  drawBlackSquare([[amountOfSquares]]);
  drawBrickTile([[numberOfBricks]]);
}

drawBlackSquare() {
  for (each grid on background) {
    // draw a black square if
    // the random value is smaller than the amountOfSquares value
    if (random(0, 5) < [[amountOfSquares]]) {
      ofDrawRectangle(x, y, unitSize*2, unitSize*2);
    }
    counter++;
  }
}

drawBrickTile() {
  bool b = true;
  for ([[numberOfBricks]]) {
    for (each unit of 4*4 square grid) {
      // switch between white and black color and
      // draw a rectangle with the chosen color
      if (b) {
        fill(0);
      } else {
        fill(255);
      }
      drawRectangle(gridX, gridY, unitSize, unitSize);
      b = !b;
    }
  }
}
<commit_msg>Update exampleCode.cpp<commit_after>drawBlackSquare() {
  for (each grid on background) {
    // draw a black square if
    // the random value is smaller than the amountOfSquares value
    if (random(0, 5) < [[amountOfSquares]]) {
      ofDrawRectangle(x, y, unitSize*2, unitSize*2);
    }
    counter++;
  }
}

drawBrickTile() {
  bool b = true;
  for ([[numberOfBricks]]) {
    for (each unit of 4*4 square grid) {
      // switch between white and black color and
      // draw a rectangle with the chosen color
      if (b) {
        fill(0);
      } else {
        fill(255);
      }
      drawRectangle(gridX, gridY, unitSize, unitSize);
      b = !b;
    }
  }
}
<|endoftext|>


<commit_before>#include "thumbnail_manager.hpp"

#include <algorithm> // find

#include "algorithm.hpp"

thumbnail_manager::thumbnail_manager(x_connection & c,
                                     const layout_t * layout,
                                     const thumbnail_t::factory * factory)
  : _c(c), _layout(layout), _factory(factory)
{
  _c.register_handler(XCB_PROPERTY_NOTIFY, this);
  _c.update_input(_c.root_window(), XCB_EVENT_MASK_PROPERTY_CHANGE);
  update();
}

thumbnail_manager::~thumbnail_manager(void)
{
  _c.deregister_handler(XCB_PROPERTY_NOTIFY, this);
}

void
thumbnail_manager::show(void)
{
  _active = true;

  update();

  _cyclic_iterator = window_cyclic_iterator(&_windows);

  for (auto & item : _thumbnails) {
    item.second->show();
  }

  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;
}

void
thumbnail_manager::hide(void)
{
  _active = false;

  for (auto & item : _thumbnails) {
    item.second->hide();
    item.second->highlight(false);
  }
}

void
thumbnail_manager::next(void) { next_or_prev(true); }

void
thumbnail_manager::prev(void) { next_or_prev(false); }

void
thumbnail_manager::select(const xcb_window_t & window)
{
  if (window == XCB_NONE) {
    try {
      _thumbnails.at(*_cyclic_iterator)->select();
    } catch (...) {}

  } else {
    for (auto & item : _thumbnails) {
      if (item.second->id() == window) {
        item.second->select();
        break;
      }
    }
  }
}

void
thumbnail_manager::highlight(const unsigned int & window)
{
  for (auto & item : _thumbnails) {
    if (item.second->id() == window) {
      try {
        _thumbnails.at(_current_window)->highlight(false);
        item.second->highlight(true);
        while (*_cyclic_iterator != item.first) ++_cyclic_iterator;
        _next_window = *(_cyclic_iterator + 1);
        _current_window = *_cyclic_iterator;
      } catch (...) {}

      break;
    }
  }
}

void
thumbnail_manager::east(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_east, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::west(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_west, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::north(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_north, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::south(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_south, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

bool
thumbnail_manager::handle(xcb_generic_event_t * ge)
{
  if (XCB_PROPERTY_NOTIFY == (ge->response_type & ~0x80)) {
    xcb_property_notify_event_t * e = (xcb_property_notify_event_t *)ge;
    if (e->window == _c.root_window()
        && e->atom == _c.intern_atom("_NET_CLIENT_LIST_STACKING")) {
      update();
    }
    return true;
  }

  return false;
}

inline void
thumbnail_manager::reset(void)
{
  if (! _active) return;

  for (auto & item : _thumbnails) {
    item.second->show();
    item.second->highlight(false);
  }

  bool found = false;
  _cyclic_iterator = window_cyclic_iterator(&_windows);

  // search for current thumbnail
  for (std::size_t i = 0; i < _windows.size(); ++i) {
    if (*_cyclic_iterator == _current_window) {
      found = true;
      break;
    } else {
      ++_cyclic_iterator;
    }
  }

  // search for next thumbnail if current was not found
  if (! found) {
    _cyclic_iterator = window_cyclic_iterator(&_windows);

    for (std::size_t i = 0; i < _windows.size(); ++i) {
      if (*_cyclic_iterator == _next_window) {
        break;
      } else {
        ++_cyclic_iterator;
      }
    }
  }

  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;

  try {
    _thumbnails.at(*_cyclic_iterator)->highlight(true);
  } catch (...) {}
}

inline void
thumbnail_manager::update(void)
{
  if (! _active) return;

  _windows = _c.net_client_list_stacking();
  auto rects = _layout->arrange(query_current_screen(), _windows.size());

  for (auto item = _thumbnails.begin(); item != _thumbnails.end(); ) {
    auto result = std::find(_windows.begin(), _windows.end(), item->first);
    if (result == _windows.end()) {
      item = _thumbnails.erase(item);
    } else {
      ++item;
    }
  }

  for (size_t i = 0; i < _windows.size(); ++i) {
    auto result = _thumbnails.find(_windows[i]);

    if (result == _thumbnails.end()) {
      _thumbnails[_windows[i]] = _factory->make(_c, _windows[i], rects[i]);
    } else {
      result->second->update(rects[i]);
    }
  }

  reset();
}

void
thumbnail_manager::next_or_prev(bool next)
{
  try {
    _thumbnails.at(*_cyclic_iterator)->highlight(false);
    next ? ++_cyclic_iterator : --_cyclic_iterator;
    _thumbnails.at(*_cyclic_iterator)->highlight(true);
  } catch (...) {}

  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;
}

inline xcb_window_t
thumbnail_manager::
nearest_thumbnail(const std::function<bool(double)> & direction)
{
  xcb_window_t thumbnail_id = XCB_NONE;

  try {
    auto & current = _thumbnails.at(_current_window);
    auto & r1 = current->rect();

    // in X (x,y) coordinates are actually flipped on the x axis
    // this means that (0,0) is in the top left corner, not in bottom left
    auto p1 = std::make_tuple(  r1.x() + (r1.width()  / 2),
                              -(r1.y() + (r1.height() / 2)));

    double min_distance = 0xffffffff;

    for (auto & item : _thumbnails) {
      if (item.second->id() == current->id()) {
        continue;
      } else {
        auto & r2 = item.second->rect();
        // in X (x,y) coordinates are actually flipped on the x axis
        // this means that (0,0) is in the top left corner, not in bottom left
        auto p2 = std::make_tuple(  r2.x() + (r2.width()  / 2),
                                  -(r2.y() + (r2.height() / 2)));

        if (direction(algorithm::angle()(p1, p2))) {
          double distance = algorithm::distance()(p1, p2);
          if (distance < min_distance) {
            min_distance = distance;
            thumbnail_id = item.second->id();
          }
        }
      }
    }

  } catch (...) {}

  return thumbnail_id;
}

// 2*M_PI ^= 360°
// 2*M_PI - M_PI/4 ^= 315°
// 2*M_PI - M_PI/2 ^= 270°
// M_PI + M_PI/4 ^= 225°
// M_PI ^= 180°
// M_PI - M_PI/4 ^= 135°
// M_PI/2 ^= 90°
// M_PI/4 ^= 45°

inline bool
thumbnail_manager::is_east(double angle)
{
  // (>=0° && <=67.5°) || >= 292.5°
  return (angle >= 0 && angle <= 3*M_PI/8) || angle >= 13*M_PI/8;
}

inline bool
thumbnail_manager::is_west(double angle)
{
  // >=112.5° && <=247.5°
  return angle >= 5*M_PI/8 && angle <= 11*M_PI/8;
}

inline bool
thumbnail_manager::is_north(double angle)
{
  // >=22.5° && <=157.5°
  return angle >= M_PI/8 && angle <= 7*M_PI/8;
}

inline bool
thumbnail_manager::is_south(double angle)
{
  // >=202.5° && <= 337.5
  return angle >= 9*M_PI/8 && angle <= 15*M_PI/8;
}

rectangle
thumbnail_manager::query_current_screen(void)
{
  rectangle screen = { 0, 0, 800, 600 };

  try {
    auto pos = _c.query_pointer();
    screen = _c.current_screen(pos.first);
  } catch (...) {}

  return screen;
}
<commit_msg>Improve call locations of update() and reset()<commit_after>#include "thumbnail_manager.hpp"

#include <algorithm> // find

#include "algorithm.hpp"

thumbnail_manager::thumbnail_manager(x_connection & c,
                                     const layout_t * layout,
                                     const thumbnail_t::factory * factory)
  : _c(c), _layout(layout), _factory(factory)
{
  _c.register_handler(XCB_PROPERTY_NOTIFY, this);
  _c.update_input(_c.root_window(), XCB_EVENT_MASK_PROPERTY_CHANGE);
}

thumbnail_manager::~thumbnail_manager(void)
{
  _c.deregister_handler(XCB_PROPERTY_NOTIFY, this);
}

void
thumbnail_manager::show(void)
{
  _active = true;

  update();

  _cyclic_iterator = window_cyclic_iterator(&_windows);
  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;

  for (auto & item : _thumbnails) {
    item.second->show();
  }
}

void
thumbnail_manager::hide(void)
{
  _active = false;

  for (auto & item : _thumbnails) {
    item.second->hide();
    item.second->highlight(false);
  }
}

void
thumbnail_manager::next(void) { next_or_prev(true); }

void
thumbnail_manager::prev(void) { next_or_prev(false); }

void
thumbnail_manager::select(const xcb_window_t & window)
{
  if (window == XCB_NONE) {
    try {
      _thumbnails.at(*_cyclic_iterator)->select();
    } catch (...) {}

  } else {
    for (auto & item : _thumbnails) {
      if (item.second->id() == window) {
        item.second->select();
        break;
      }
    }
  }
}

void
thumbnail_manager::highlight(const unsigned int & window)
{
  for (auto & item : _thumbnails) {
    if (item.second->id() == window) {
      try {
        _thumbnails.at(_current_window)->highlight(false);
        item.second->highlight(true);
        while (*_cyclic_iterator != item.first) ++_cyclic_iterator;
        _next_window = *(_cyclic_iterator + 1);
        _current_window = *_cyclic_iterator;
      } catch (...) {}

      break;
    }
  }
}

void
thumbnail_manager::east(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_east, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::west(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_west, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::north(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_north, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

void
thumbnail_manager::south(void)
{
  xcb_window_t tid = nearest_thumbnail(
      std::bind(&thumbnail_manager::is_south, this, std::placeholders::_1));
  if (tid != XCB_NONE) highlight(tid);
}

bool
thumbnail_manager::handle(xcb_generic_event_t * ge)
{
  if (XCB_PROPERTY_NOTIFY == (ge->response_type & ~0x80)) {
    xcb_property_notify_event_t * e = (xcb_property_notify_event_t *)ge;
    if (_active
        && e->window == _c.root_window()
        && e->atom == _c.intern_atom("_NET_CLIENT_LIST_STACKING"))
    {
      update();
      reset();
    }
    return true;
  }

  return false;
}

inline void
thumbnail_manager::reset(void)
{
  for (auto & item : _thumbnails) {
    item.second->show();
    item.second->highlight(false);
  }

  bool found = false;
  _cyclic_iterator = window_cyclic_iterator(&_windows);

  // search for current thumbnail
  for (std::size_t i = 0; i < _windows.size(); ++i) {
    if (*_cyclic_iterator == _current_window) {
      found = true;
      break;
    } else {
      ++_cyclic_iterator;
    }
  }

  // search for next thumbnail if current was not found
  if (! found) {
    _cyclic_iterator = window_cyclic_iterator(&_windows);

    for (std::size_t i = 0; i < _windows.size(); ++i) {
      if (*_cyclic_iterator == _next_window) {
        break;
      } else {
        ++_cyclic_iterator;
      }
    }
  }

  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;

  try {
    _thumbnails.at(*_cyclic_iterator)->highlight(true);
  } catch (...) {}
}

inline void
thumbnail_manager::update(void)
{
  _windows = _c.net_client_list_stacking();
  auto rects = _layout->arrange(query_current_screen(), _windows.size());

  for (auto item = _thumbnails.begin(); item != _thumbnails.end(); ) {
    auto result = std::find(_windows.begin(), _windows.end(), item->first);
    if (result == _windows.end()) {
      item = _thumbnails.erase(item);
    } else {
      ++item;
    }
  }

  for (size_t i = 0; i < _windows.size(); ++i) {
    auto result = _thumbnails.find(_windows[i]);

    if (result == _thumbnails.end()) {
      _thumbnails[_windows[i]] = _factory->make(_c, _windows[i], rects[i]);
    } else {
      result->second->update(rects[i]);
    }
  }
}

void
thumbnail_manager::next_or_prev(bool next)
{
  try {
    _thumbnails.at(*_cyclic_iterator)->highlight(false);
    next ? ++_cyclic_iterator : --_cyclic_iterator;
    _thumbnails.at(*_cyclic_iterator)->highlight(true);
  } catch (...) {}

  _next_window = *(_cyclic_iterator + 1);
  _current_window = *_cyclic_iterator;
}

inline xcb_window_t
thumbnail_manager::
nearest_thumbnail(const std::function<bool(double)> & direction)
{
  xcb_window_t thumbnail_id = XCB_NONE;

  try {
    auto & current = _thumbnails.at(_current_window);
    auto & r1 = current->rect();

    // in X (x,y) coordinates are actually flipped on the x axis
    // this means that (0,0) is in the top left corner, not in bottom left
    auto p1 = std::make_tuple(  r1.x() + (r1.width()  / 2),
                              -(r1.y() + (r1.height() / 2)));

    double min_distance = 0xffffffff;

    for (auto & item : _thumbnails) {
      if (item.second->id() == current->id()) {
        continue;
      } else {
        auto & r2 = item.second->rect();
        // in X (x,y) coordinates are actually flipped on the x axis
        // this means that (0,0) is in the top left corner, not in bottom left
        auto p2 = std::make_tuple(  r2.x() + (r2.width()  / 2),
                                  -(r2.y() + (r2.height() / 2)));

        if (direction(algorithm::angle()(p1, p2))) {
          double distance = algorithm::distance()(p1, p2);
          if (distance < min_distance) {
            min_distance = distance;
            thumbnail_id = item.second->id();
          }
        }
      }
    }

  } catch (...) {}

  return thumbnail_id;
}

// 2*M_PI ^= 360°
// 2*M_PI - M_PI/4 ^= 315°
// 2*M_PI - M_PI/2 ^= 270°
// M_PI + M_PI/4 ^= 225°
// M_PI ^= 180°
// M_PI - M_PI/4 ^= 135°
// M_PI/2 ^= 90°
// M_PI/4 ^= 45°

inline bool
thumbnail_manager::is_east(double angle)
{
  // (>=0° && <=67.5°) || >= 292.5°
  return (angle >= 0 && angle <= 3*M_PI/8) || angle >= 13*M_PI/8;
}

inline bool
thumbnail_manager::is_west(double angle)
{
  // >=112.5° && <=247.5°
  return angle >= 5*M_PI/8 && angle <= 11*M_PI/8;
}

inline bool
thumbnail_manager::is_north(double angle)
{
  // >=22.5° && <=157.5°
  return angle >= M_PI/8 && angle <= 7*M_PI/8;
}

inline bool
thumbnail_manager::is_south(double angle)
{
  // >=202.5° && <= 337.5
  return angle >= 9*M_PI/8 && angle <= 15*M_PI/8;
}

rectangle
thumbnail_manager::query_current_screen(void)
{
  rectangle screen = { 0, 0, 800, 600 };

  try {
    auto pos = _c.query_pointer();
    screen = _c.current_screen(pos.first);
  } catch (...) {}

  return screen;
}
<|endoftext|>


<commit_before><commit_msg>Extended Union--Find data structure with component extraction<commit_after><|endoftext|>


<commit_before><commit_msg>UI: paintcontainers member renames<commit_after><|endoftext|>


<commit_before>#include <QCoreApplication>
#include <QDebug>
#include <updater.h>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

#if defined(Q_OS_WIN32)
	QtAutoUpdater::Updater *updater = new QtAutoUpdater::Updater("D:/Program Files/IcoDroid/maintenancetool", nullptr);
#elif defined(Q_OS_OSX)
	QtAutoUpdater::Updater *updater = new QtAutoUpdater::Updater("/Applications/IcoDroid.app/maintenancetool", nullptr);
#elif defined(Q_OS_UNIX)
	QtAutoUpdater::Updater *updater = new QtAutoUpdater::Updater("/home/sky/IcoDroid/maintenancetool", nullptr);
#endif
	updater->runUpdaterOnExit();

	QObject::connect(updater, &QtAutoUpdater::Updater::checkUpdatesDone, [updater](bool a, bool b){
		qDebug() << "Has updates:" << a
				 << "\nHas errors:" << b
				 << "\nError string:" << updater->errorLog();
		qDebug() << updater->updateInfo();
		qApp->quit();
	});

	updater->checkForUpdates();
	return a.exec();
}
<commit_msg>updated console updater test<commit_after>#include <QCoreApplication>
#include <QDebug>
#include <QStandardPaths>
#include <updater.h>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
	QtAutoUpdater::Updater *updater = new QtAutoUpdater::Updater(homePath + "/QtAutoUpdaterTestInstaller/maintenancetool",
																 nullptr);
	updater->runUpdaterOnExit();

	QObject::connect(updater, &QtAutoUpdater::Updater::checkUpdatesDone, [updater](bool a, bool b){
		qDebug() << "Has updates:" << a
				 << "\nHas errors:" << b
				 << "\nError string:" << updater->errorLog();
		qDebug() << updater->updateInfo();
		qApp->quit();
	});

	updater->checkForUpdates();
	return a.exec();
}
<|endoftext|>


<commit_before>#include "Scene.h"

Scene::Scene()
:level(0)
{
	//Generate the world on launch
	resetScene();
}

void Scene::resetScene()
{
	//Empty the state data
	particleSystem.empty();

	/*
	//TODO: leaks memory here, because stuff is not removed!

	for (int i = 0; i < entities.size(); i++)
	{
		delete entities[i];
	}

	for (int i = 0; i < planets.size() - 1; ++i)
	{
		delete planets[i];
	}
	*/

	entities.clear();
	planets.clear();

	//Reset player
	player = Player();

	int count = 3 + (level * 2);
	bool hit = false;

	Planet* tempPlanet;

	while(count > 0)
	{
		--count;

		tempPlanet = new Planet( Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT) ), randomRange(100,250 ) ) ;

		//Check that the planet is not on top of other planes
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = tempPlanet->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= tempPlanet->size;

			if(dist < 0){
				//Hit! break from the loop
				hit = true;
			}
		}

		if(hit)
		{
			printf("planet collision!");
			delete tempPlanet;
		}
		else
		{
			printf("planet creation");
			planets.push_back(tempPlanet);
		}

		hit = false;
	}

	//Then add the pickups.
	count = SCENE_PICKUP_COUNT; //10 pickups

	hit = false;

	Entity *ent;

	while( count > 0 )
	{
		//Entity *ent = new Entity(Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT)), ENTITYTYPE_PICKUP);
		ent = new Entity();

		ent->position = Vector( (float)randomRange(0,WORLD_WIDTH), (float)randomRange(0,WORLD_HEIGHT));
		ent->type = ENTITYTYPE_PICKUP;

//		printf("|%f %f|\n",ent->position.x,ent->position.y);

		//Check that the pickup is not inside a planet
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = ent->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= 150; //Some space between the planets and pickups...

			if(dist < 0){
				//Hit! break from the loop
				//printf("planet collision!");
				hit = true;
			}
		}

		if(hit)
		{
			delete ent;
		}
		else
		{
			entities.push_back(ent);
		}

		--count;
		hit = false;
	}

	printf("entities.size() : %i \n", entities.size());

	count = SCENE_FUEL_COUNT; //5 fuel

	while( count > 0 )
	{
		//Entity *ent = new Entity(Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT)), ENTITYTYPE_PICKUP);
		ent = new Entity();

		ent->position = Vector( (float)randomRange(0,WORLD_WIDTH), (float)randomRange(0,WORLD_HEIGHT));
		ent->type = ENTITYTYPE_FUEL;

//		printf("|%f %f|\n",ent->position.x,ent->position.y);

		//Check that the pickup is not inside a planet
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = ent->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= 150; //Some space between the planets and pickups...

			if(dist < 0){
				//Hit! break from the loop
				printf("planet collision!");
				hit = true;
			}
		}

		if(hit)
		{
			delete ent;
		}
		else
		{
			entities.push_back(ent);
		}

		--count;
		hit = false;
	}

	printf("entities.size() : %i \n", entities.size());
}

void Scene::update()
{
	//calculate gravity from nearby planets

	for(int i = 0; i < planets.size(); ++i)
	{
		//get distance from player
		Vector vec = planets[i]->position - player.position;

		int dist = abs( vec.getLenght() );
		int radius = planets[i]->size;

		//#######################
		//Planets generate particles!
		//particleSystem.addParticles(1,4,planets[i]->position,0,0,-2,2,radius / 10,radius / 5 + radius / 2, sf::Color::Red,3);
		//Disabled because it would "eat" all the avaivable slots with current setup.
		//#######################

		if (dist < radius)
		{
			if (player.hp > 0) //Don't kill the player if he is dead already.
			{
				--player.hp;
				particleSystem.addParticles(5, 10, player.position, Vector(0, 1), 360, 5, 10, 100, 200 / 2, sf::Color::White, 2);

				if (player.hp < 1)
				{
					//Player died on this frame! BETTER EXPLOSIONS!
					particleSystem.empty();
					particleSystem.addParticles(500, 500, player.position, Vector(0,1), 360, 5, 10, 20000, 20000 / 2, sf::Color::White, 2);

					level = 0;
				}
			}
		}

		//if distance is larger than the size, no gravity applies
		if(dist / GRAVITY_MULTIPLIER > radius)
			continue;

		dist -= radius / 2; //gravity "starts" from the surface, not center

		float str = dist / (1000000.f / 0.8);

		//printf("# %f #\n",str);
		if(str < 0)
			continue;

		//apply force
		player.impulse(vec,str);
	}

	//Check the entities

	for ( int i = 0; i < entities.size(); ++i )
	{
		Vector vec = entities[i]->position - player.position;
		int dist = abs( vec.getLenght() );

		if(dist < 65)
		{
			//printf("PICKUP!");
			printf("dist: %i", dist);

			if(entities[i]->type == ENTITYTYPE_PICKUP)
			{
				particleSystem.addParticles(200, 200, entities[i]->position , Vector(0,1) ,360,50,80,50,100,sf::Color::Green,4);
				++player.points;
			}

			if(entities[i]->type == ENTITYTYPE_FUEL)
			{
				particleSystem.addParticles(200, 200, entities[i]->position , Vector(0,1) ,360,30,50,50,100,sf::Color::Red,4);
				player.fuel += FUEL_PER_CANISTER;
			}

			delete entities[i];
			entities.erase(entities.begin() + i);
			--i;
		}
	}

	//Only update player if hp is positive
	if (player.hp > 0){
		player.update();
	}

	//If player wins! Reset the level and move to the next one

	printf("%i\n", player.points);
	if (player.points > 7)
	{
		//This may be bit reduntant as resetScene should handle these
		player.points = 0;
		player.hp = PLAYER_START_HP;
		player.fuel = PLAYER_START_FUEL;

		//Next difficulty!
		++level;

		resetScene();
	}
}<commit_msg>Fixed the memory leak<commit_after>#include "Scene.h"

Scene::Scene()
:level(0)
{
	//Generate the world on launch
	resetScene();
}

void Scene::resetScene()
{
	//Empty the state data
	particleSystem.empty();

	for (int i = 0; i < entities.size(); ++i)
	{
		delete entities[i];
	}

	for (int i = 0; i < planets.size(); ++i)
	{
		delete planets[i];
	}

	entities.clear();
	planets.clear();

	//Reset player
	player = Player();

	int count = 3 + (level * 2);
	bool hit = false;

	Planet* tempPlanet;

	while(count > 0)
	{
		--count;

		tempPlanet = new Planet( Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT) ), randomRange(100,250 ) ) ;

		//Check that the planet is not on top of other planes
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = tempPlanet->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= tempPlanet->size;

			if(dist < 0){
				//Hit! break from the loop
				hit = true;
			}
		}

		if(hit)
		{
			printf("planet collision!");
			delete tempPlanet;
		}
		else
		{
			printf("planet creation");
			planets.push_back(tempPlanet);
		}

		hit = false;
	}

	//Then add the pickups.
	count = SCENE_PICKUP_COUNT; //10 pickups

	hit = false;

	Entity *ent;

	while( count > 0 )
	{
		//Entity *ent = new Entity(Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT)), ENTITYTYPE_PICKUP);
		ent = new Entity();

		ent->position = Vector( (float)randomRange(0,WORLD_WIDTH), (float)randomRange(0,WORLD_HEIGHT));
		ent->type = ENTITYTYPE_PICKUP;

//		printf("|%f %f|\n",ent->position.x,ent->position.y);

		//Check that the pickup is not inside a planet
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = ent->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= 150; //Some space between the planets and pickups...

			if(dist < 0){
				//Hit! break from the loop
				//printf("planet collision!");
				hit = true;
			}
		}

		if(hit)
		{
			delete ent;
		}
		else
		{
			entities.push_back(ent);
		}

		--count;
		hit = false;
	}

	printf("entities.size() : %i \n", entities.size());

	count = SCENE_FUEL_COUNT; //5 fuel

	while( count > 0 )
	{
		//Entity *ent = new Entity(Vector( randomRange(0,WORLD_WIDTH), randomRange(0,WORLD_HEIGHT)), ENTITYTYPE_PICKUP);
		ent = new Entity();

		ent->position = Vector( (float)randomRange(0,WORLD_WIDTH), (float)randomRange(0,WORLD_HEIGHT));
		ent->type = ENTITYTYPE_FUEL;

//		printf("|%f %f|\n",ent->position.x,ent->position.y);

		//Check that the pickup is not inside a planet
		for( int i = 0; i < planets.size(); ++i)
		{
			Vector vec = ent->position - planets[i]->position;
			float dist = abs ( vec.getLenght() );

			dist -= planets[i]->size;
			dist -= 150; //Some space between the planets and pickups...

			if(dist < 0){
				//Hit! break from the loop
				printf("planet collision!");
				hit = true;
			}
		}

		if(hit)
		{
			delete ent;
		}
		else
		{
			entities.push_back(ent);
		}

		--count;
		hit = false;
	}

	printf("entities.size() : %i \n", entities.size());
}

void Scene::update()
{
	//calculate gravity from nearby planets

	for(int i = 0; i < planets.size(); ++i)
	{
		//get distance from player
		Vector vec = planets[i]->position - player.position;

		int dist = abs( vec.getLenght() );
		int radius = planets[i]->size;

		//#######################
		//Planets generate particles!
		//particleSystem.addParticles(1,4,planets[i]->position,0,0,-2,2,radius / 10,radius / 5 + radius / 2, sf::Color::Red,3);
		//Disabled because it would "eat" all the avaivable slots with current setup.
		//#######################

		if (dist < radius)
		{
			if (player.hp > 0) //Don't kill the player if he is dead already.
			{
				--player.hp;
				particleSystem.addParticles(5, 10, player.position, Vector(0, 1), 360, 5, 10, 100, 200 / 2, sf::Color::White, 2);

				if (player.hp < 1)
				{
					//Player died on this frame! BETTER EXPLOSIONS!
					particleSystem.empty();
					particleSystem.addParticles(500, 500, player.position, Vector(0,1), 360, 5, 10, 20000, 20000 / 2, sf::Color::White, 2);

					level = 0;
				}
			}
		}

		//if distance is larger than the size, no gravity applies
		if(dist / GRAVITY_MULTIPLIER > radius)
			continue;

		dist -= radius / 2; //gravity "starts" from the surface, not center

		float str = dist / (1000000.f / 0.8);

		//printf("# %f #\n",str);
		if(str < 0)
			continue;

		//apply force
		player.impulse(vec,str);
	}

	//Check the entities

	for ( int i = 0; i < entities.size(); ++i )
	{
		Vector vec = entities[i]->position - player.position;
		int dist = abs( vec.getLenght() );

		if(dist < 65)
		{
			//printf("PICKUP!");
			printf("dist: %i", dist);

			if(entities[i]->type == ENTITYTYPE_PICKUP)
			{
				particleSystem.addParticles(200, 200, entities[i]->position , Vector(0,1) ,360,50,80,50,100,sf::Color::Green,4);
				++player.points;
			}

			if(entities[i]->type == ENTITYTYPE_FUEL)
			{
				particleSystem.addParticles(200, 200, entities[i]->position , Vector(0,1) ,360,30,50,50,100,sf::Color::Red,4);
				player.fuel += FUEL_PER_CANISTER;
			}

			delete entities[i];
			entities.erase(entities.begin() + i);
			--i;
		}
	}

	//Only update player if hp is positive
	if (player.hp > 0){
		player.update();
	}

	//If player wins! Reset the level and move to the next one

	printf("%i\n", player.points);
	if (player.points > 7)
	{
		//This may be bit reduntant as resetScene should handle these
		player.points = 0;
		player.hp = PLAYER_START_HP;
		player.fuel = PLAYER_START_FUEL;

		//Next difficulty!
		++level;

		resetScene();
	}
}<|endoftext|>


<commit_before>#include "ros/ros.h"
#include <linux/input.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <string>
#include <vector>

#include "lg_mirror/EvdevEvent.h"
#include "lg_mirror/EvdevEvents.h"
#include "constants.h"
#include "device_service.h"

using lg_mirror::TOUCH_EVENTS_TOPIC;
using lg_mirror::DEVICE_INFO_SERVICE;

const char* DEVICE_PATH_PARAM = "~device_path";

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

  /* initialize ros */

  ros::init(argc, argv, "lg_mirror_sender");

  ros::NodeHandle n;

  /* open the device */

  std::string device_path;
  int device_fd;

  if (ros::param::get(DEVICE_PATH_PARAM, device_path)) {
    ROS_INFO("Using device: %s", device_path.c_str());
  } else {
    ROS_ERROR("Private parameter 'device_path' must be set");
    ros::shutdown();
    exit(EXIT_FAILURE);
  }

  if ((device_fd = open(device_path.c_str(), O_RDONLY | O_NONBLOCK)) < 0) {
    perror("opening the file you specified");
    ros::shutdown();
    exit(EXIT_FAILURE);
  }

  /* set up fd polling */

  struct pollfd poll_fd;
  memset(&poll_fd, 0, sizeof(poll_fd));
  poll_fd.fd = device_fd;
  poll_fd.events = POLLIN;

  /* advertise the topic */

  ros::Publisher evdev_pub =
    n.advertise<lg_mirror::EvdevEvents>(TOUCH_EVENTS_TOPIC, 1);

  /* begin relaying from the device to the topic */

  lg_mirror::EvdevEvents events_msg;

  DeviceServicer ds(device_fd);
  ros::ServiceServer service = n.advertiseService(DEVICE_INFO_SERVICE,
		  &DeviceServicer::get_device_info, &ds);
  ros::AsyncSpinner as(1);
  as.start();

  while(ros::ok()) {
    struct input_event ev;
    struct input_event *event_data = &ev;
    lg_mirror::EvdevEvent event_msg;

    /* read an event */

    int status = poll(&poll_fd, 1, -1);
    if (status == 1) {
      // device is ready to read
      int num_read = read(device_fd, event_data, sizeof(ev));

      if (num_read != sizeof(ev)) {
        ROS_ERROR("Error getting next event");
        ros::shutdown();
        exit(EXIT_FAILURE);
      }

    } else {
      // an error has occurred
      perror("polling device");
      ros::shutdown();
      exit(EXIT_FAILURE);
    }

    /* handle the event */

    if (event_data->type == EV_SYN) {
      // only publish when a syn event is read
      if (!events_msg.events.empty()) {
        evdev_pub.publish(events_msg);
        events_msg.events.clear();
      }
      ros::spinOnce();
      continue;
    }

    // non-syn events are aggregated
    event_msg.type = event_data->type;
    event_msg.code = event_data->code;
    event_msg.value = event_data->value;
    events_msg.events.push_back(event_msg);

    ROS_DEBUG(
      "got type: %d code: %d value: %d\n",
      event_msg.type, event_msg.code, event_msg.value
    );
  }
}
<commit_msg>Increase lg_mirror touch sender event queue size<commit_after>#include "ros/ros.h"
#include <linux/input.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <string>
#include <vector>

#include "lg_mirror/EvdevEvent.h"
#include "lg_mirror/EvdevEvents.h"
#include "constants.h"
#include "device_service.h"

using lg_mirror::TOUCH_EVENTS_TOPIC;
using lg_mirror::DEVICE_INFO_SERVICE;

const char* DEVICE_PATH_PARAM = "~device_path";
const std::size_t EVENTS_QUEUE_LENGTH = 10;

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

  /* initialize ros */

  ros::init(argc, argv, "lg_mirror_sender");

  ros::NodeHandle n;

  /* open the device */

  std::string device_path;
  int device_fd;

  if (ros::param::get(DEVICE_PATH_PARAM, device_path)) {
    ROS_INFO("Using device: %s", device_path.c_str());
  } else {
    ROS_ERROR("Private parameter 'device_path' must be set");
    ros::shutdown();
    exit(EXIT_FAILURE);
  }

  if ((device_fd = open(device_path.c_str(), O_RDONLY | O_NONBLOCK)) < 0) {
    perror("opening the file you specified");
    ros::shutdown();
    exit(EXIT_FAILURE);
  }

  /* set up fd polling */

  struct pollfd poll_fd;
  memset(&poll_fd, 0, sizeof(poll_fd));
  poll_fd.fd = device_fd;
  poll_fd.events = POLLIN;

  /* advertise the topic */

  ros::Publisher evdev_pub =
    n.advertise<lg_mirror::EvdevEvents>(TOUCH_EVENTS_TOPIC,
                                        EVENTS_QUEUE_LENGTH);

  /* begin relaying from the device to the topic */

  lg_mirror::EvdevEvents events_msg;

  DeviceServicer ds(device_fd);
  ros::ServiceServer service = n.advertiseService(DEVICE_INFO_SERVICE,
		  &DeviceServicer::get_device_info, &ds);
  ros::AsyncSpinner as(1);
  as.start();

  while(ros::ok()) {
    struct input_event ev;
    struct input_event *event_data = &ev;
    lg_mirror::EvdevEvent event_msg;

    /* read an event */

    int status = poll(&poll_fd, 1, -1);
    if (status == 1) {
      // device is ready to read
      int num_read = read(device_fd, event_data, sizeof(ev));

      if (num_read != sizeof(ev)) {
        ROS_ERROR("Error getting next event");
        ros::shutdown();
        exit(EXIT_FAILURE);
      }

    } else {
      // an error has occurred
      perror("polling device");
      ros::shutdown();
      exit(EXIT_FAILURE);
    }

    /* handle the event */

    if (event_data->type == EV_SYN) {
      // only publish when a syn event is read
      if (!events_msg.events.empty()) {
        evdev_pub.publish(events_msg);
        events_msg.events.clear();
      }
      ros::spinOnce();
      continue;
    }

    // non-syn events are aggregated
    event_msg.type = event_data->type;
    event_msg.code = event_data->code;
    event_msg.value = event_data->value;
    events_msg.events.push_back(event_msg);

    ROS_DEBUG(
      "got type: %d code: %d value: %d\n",
      event_msg.type, event_msg.code, event_msg.value
    );
  }
}
<|endoftext|>