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

// Unit-test for QueuedWorkerPool

#include "net/instaweb/util/public/queued_worker_pool.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/function.h"
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/worker_test_base.h"

namespace net_instaweb {
namespace {

class QueuedWorkerPoolTest: public WorkerTestBase {
 public:
  QueuedWorkerPoolTest()
      : worker_(new QueuedWorkerPool(2, thread_runtime_.get())) {}

 protected:
  scoped_ptr<QueuedWorkerPool> worker_;

 private:
  DISALLOW_COPY_AND_ASSIGN(QueuedWorkerPoolTest);
};

// A function that, without protection of a mutex, increments a shared
// integer.  The intent is that the QueuedWorkerPool::Sequence is
// enforcing the sequentiality on our behalf so we don't have to worry
// about mutexing in here.
class Increment : public Function {
 public:
  Increment(int expected_value, int* count)
      : expected_value_(expected_value),
        count_(count) {
  }

 protected:
  virtual void Run() {
    ++*count_;
    EXPECT_EQ(expected_value_, *count_);
  }
  virtual void Cancel() {
    *count_ -= 100;
    EXPECT_EQ(expected_value_, *count_);
  }

 private:
  int expected_value_;
  int* count_;

  DISALLOW_COPY_AND_ASSIGN(Increment);
};

// Tests that all the jobs queued in one sequence should run sequentially.
TEST_F(QueuedWorkerPoolTest, BasicOperation) {
  const int kBound = 42;
  int count = 0;
  SyncPoint sync(thread_runtime_.get());

  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    sequence->Add(new Increment(i + 1, &count));
  }

  sequence->Add(new NotifyRunFunction(&sync));
  sync.Wait();
  EXPECT_EQ(kBound, count);
  worker_->FreeSequence(sequence);
}

// Test ordinary and cancelled AddFunction callback.
TEST_F(QueuedWorkerPoolTest, AddFunctionTest) {
  const int kBound = 5;
  int count1 = 0;
  int count2 = 0;
  SyncPoint sync(thread_runtime_.get());

  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    QueuedWorkerPool::Sequence::AddFunction
        add(sequence, new Increment(i + 1, &count1));
    add.set_delete_after_callback(false);
    add.CallRun();
    QueuedWorkerPool::Sequence::AddFunction
        cancel(sequence, new Increment(-100 * (i + 1), &count2));
    cancel.set_delete_after_callback(false);
    cancel.CallCancel();
  }

  sequence->Add(new NotifyRunFunction(&sync));
  sync.Wait();
  EXPECT_EQ(kBound, count1);
  EXPECT_EQ(-100 * kBound, count2);
  worker_->FreeSequence(sequence);
}

// Makes sure that even if one sequence is blocked, another can
// complete, because we have more than one thread at our disposal in
// this worker.
TEST_F(QueuedWorkerPoolTest, SlowAndFastSequences) {
  const int kBound = 42;
  int count = 0;
  SyncPoint sync(thread_runtime_.get());
  SyncPoint wait(thread_runtime_.get());

  QueuedWorkerPool::Sequence* slow_sequence = worker_->NewSequence();
  slow_sequence->Add(new WaitRunFunction(&wait));
  slow_sequence->Add(new NotifyRunFunction(&sync));

  QueuedWorkerPool::Sequence* fast_sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    fast_sequence->Add(new Increment(i + 1, &count));
  }

  // At this point the fast sequence is churning through its work, while the
  // slow sequence is blocked waiting for SyncPoint 'wait'.  Let the fast
  // sequence unblock it.
  fast_sequence->Add(new NotifyRunFunction(&wait));

  sync.Wait();
  EXPECT_EQ(kBound, count);
  worker_->FreeSequence(fast_sequence);
  worker_->FreeSequence(slow_sequence);
}

class MakeNewSequence : public Function {
 public:
  MakeNewSequence(WorkerTestBase::SyncPoint* sync,
                  QueuedWorkerPool* pool,
                  QueuedWorkerPool::Sequence* sequence)
      : sync_(sync),
        pool_(pool),
        sequence_(sequence) {
  }

  virtual void Run() {
    pool_->FreeSequence(sequence_);
    pool_->NewSequence()->Add(new WorkerTestBase::NotifyRunFunction(sync_));
  }

 private:
  WorkerTestBase::SyncPoint* sync_;
  QueuedWorkerPool* pool_;
  QueuedWorkerPool::Sequence* sequence_;

  DISALLOW_COPY_AND_ASSIGN(MakeNewSequence);
};

TEST_F(QueuedWorkerPoolTest, RestartSequenceFromFunction) {
  SyncPoint sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  sequence->Add(new MakeNewSequence(&sync, worker_.get(), sequence));
  sync.Wait();
}

// Keeps track of whether run or cancel were called.
class LogOpsFunction : public Function {
 public:
  LogOpsFunction() : run_called_(false), cancel_called_(false) {
    set_delete_after_callback(false);
  }
  virtual ~LogOpsFunction() {}

  bool run_called() const { return run_called_; }
  bool cancel_called() const { return cancel_called_; }

 protected:
  virtual void Run() { run_called_ = true; }
  virtual void Cancel() { cancel_called_ = true; }

 private:
  bool run_called_;
  bool cancel_called_;
};

// Make sure calling add after worker was shut down Cancel()s the function
// properly.
TEST_F(QueuedWorkerPoolTest, AddAfterShutDown) {
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  worker_->ShutDown();
  LogOpsFunction f;
  sequence->Add(&f);
  worker_.reset(NULL);
  EXPECT_TRUE(f.cancel_called());
  EXPECT_FALSE(f.run_called());
}

TEST_F(QueuedWorkerPoolTest, LoadShedding) {
  const int kThresh = 100;
  worker_->SetLoadSheddingThreshold(kThresh);
  // Tests that load shedding works, and does so in FIFO order.
  // We do it by first wedging the queues by 2 (as many as we have threads)
  // sequences that wait on SyncPoints followed by 2*kThresh
  // independent LogOpsFunction instances (each in a separate sequence),
  // then a notify. If everything works fine, we'll cancel the first
  // kThresh + 1 LogOps, run the kThresh - 1 last LogOps, and the notify.
  SyncPoint wedge1_sync(thread_runtime_.get());
  SyncPoint wedge2_sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* wedge1 = worker_->NewSequence();
  wedge1->Add(new WaitRunFunction(&wedge1_sync));
  QueuedWorkerPool::Sequence* wedge2 = worker_->NewSequence();
  wedge2->Add(new WaitRunFunction(&wedge2_sync));

  std::vector<QueuedWorkerPool::Sequence*> log_ops;
  std::vector<LogOpsFunction*> log_ops_functions;
  for (int i = 0; i < 2 * kThresh; ++i) {
    LogOpsFunction* fn = new LogOpsFunction;
    QueuedWorkerPool::Sequence* log_op = worker_->NewSequence();
    log_op->Add(fn);
    log_ops.push_back(log_op);
    log_ops_functions.push_back(fn);
  }

  SyncPoint done_sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* done = worker_->NewSequence();
  done->Add(new NotifyRunFunction(&done_sync));

  wedge1_sync.Notify();
  wedge2_sync.Notify();
  done_sync.Wait();

  // We want to shutdown here since even though done_sync signaled, there
  // may still be a log op running in the 2nd thread. This will wait for it.
  worker_->ShutDown();

  worker_->FreeSequence(wedge1);
  worker_->FreeSequence(wedge2);

  for (int i = 0; i <= kThresh; ++i) {
    EXPECT_TRUE(log_ops_functions[i]->cancel_called());
    EXPECT_FALSE(log_ops_functions[i]->run_called());
    delete log_ops_functions[i];
    worker_->FreeSequence(log_ops[i]);
  }

  for (int i = kThresh + 1; i < 2 * kThresh; ++i) {
    EXPECT_FALSE(log_ops_functions[i]->cancel_called());
    EXPECT_TRUE(log_ops_functions[i]->run_called());
    delete log_ops_functions[i];
    worker_->FreeSequence(log_ops[i]);
  }

  worker_->FreeSequence(done);
}

class NotifyAndWait : public Function {
 public:
  NotifyAndWait(WorkerTestBase::SyncPoint* notify,
                WorkerTestBase::SyncPoint* wait)
      : notify_(notify),
        wait_(wait) {
  }

  virtual void Run() {
    notify_->Notify();
    wait_->Wait();
  }

  virtual void Cancel() {
    CHECK(false);
  }

 private:
  WorkerTestBase::SyncPoint* notify_;
  WorkerTestBase::SyncPoint* wait_;
};

TEST_F(QueuedWorkerPoolTest, MaxQueueSize) {
  SyncPoint started(thread_runtime_.get());
  SyncPoint wait(thread_runtime_.get());
  SyncPoint done(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  sequence->set_max_queue_size(4);
  int count = 0;
  sequence->Add(new NotifyAndWait(&started, &wait));
  started.Wait();
  sequence->Add(new Increment(-100, &count));  // will be canceled: -100.
  sequence->Add(new Increment(-99, &count));   // will be run: +1 == -99.
  sequence->Add(new Increment(-98, &count));   // will be run: +1 == -98.
  sequence->Add(new NotifyRunFunction(&done));
  sequence->Add(new Increment(-97, &count));   // Cancels first increment.
  wait.Notify();
  done.Wait();
  worker_->FreeSequence(sequence);
  worker_->ShutDown();
  EXPECT_EQ(-97, count);
}

TEST_F(QueuedWorkerPoolTest, CancelPending) {
  SyncPoint wait(thread_runtime_.get());
  SyncPoint done(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  int count = 0;
  sequence->Add(new WaitRunFunction(&wait));
  sequence->Add(new Increment(-100, &count));
  sequence->Add(new Increment(-200, &count));
  sequence->Add(new Increment(-300, &count));
  sequence->CancelPendingFunctions();
  sequence->Add(new NotifyRunFunction(&done));
  wait.Notify();
  done.Wait();
  worker_->FreeSequence(sequence);
  worker_->ShutDown();
  EXPECT_EQ(-300, count);
}

}  // namespace

}  // namespace net_instaweb
<commit_msg>One more try at de-flaking QueuedWorkerPoolTest.<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Author: jmarantz@google.com (Joshua Marantz)

// Unit-test for QueuedWorkerPool

#include "net/instaweb/util/public/queued_worker_pool.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "net/instaweb/util/public/basictypes.h"
#include "net/instaweb/util/public/function.h"
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/worker_test_base.h"

namespace net_instaweb {
namespace {

class QueuedWorkerPoolTest: public WorkerTestBase {
 public:
  QueuedWorkerPoolTest()
      : worker_(new QueuedWorkerPool(2, thread_runtime_.get())) {}

 protected:
  scoped_ptr<QueuedWorkerPool> worker_;

  // Blocks mainline until a sequence completes all outstanding tasks.
  void WaitUntilSequenceCompletes(QueuedWorkerPool::Sequence* sequence) {
    SyncPoint done(thread_runtime_.get());
    sequence->Add(new NotifyRunFunction(&done));
    done.Wait();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(QueuedWorkerPoolTest);
};

// A function that, without protection of a mutex, increments a shared
// integer.  The intent is that the QueuedWorkerPool::Sequence is
// enforcing the sequentiality on our behalf so we don't have to worry
// about mutexing in here.
class Increment : public Function {
 public:
  Increment(int expected_value, int* count)
      : expected_value_(expected_value),
        count_(count) {
  }

 protected:
  virtual void Run() {
    ++*count_;
    EXPECT_EQ(expected_value_, *count_);
  }
  virtual void Cancel() {
    *count_ -= 100;
    EXPECT_EQ(expected_value_, *count_);
  }

 private:
  int expected_value_;
  int* count_;

  DISALLOW_COPY_AND_ASSIGN(Increment);
};

// Tests that all the jobs queued in one sequence should run sequentially.
TEST_F(QueuedWorkerPoolTest, BasicOperation) {
  const int kBound = 42;
  int count = 0;
  SyncPoint sync(thread_runtime_.get());

  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    sequence->Add(new Increment(i + 1, &count));
  }

  sequence->Add(new NotifyRunFunction(&sync));
  sync.Wait();
  EXPECT_EQ(kBound, count);
  worker_->FreeSequence(sequence);
}

// Test ordinary and cancelled AddFunction callback.
TEST_F(QueuedWorkerPoolTest, AddFunctionTest) {
  const int kBound = 5;
  int count1 = 0;
  int count2 = 0;
  SyncPoint sync(thread_runtime_.get());

  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    QueuedWorkerPool::Sequence::AddFunction
        add(sequence, new Increment(i + 1, &count1));
    add.set_delete_after_callback(false);
    add.CallRun();
    QueuedWorkerPool::Sequence::AddFunction
        cancel(sequence, new Increment(-100 * (i + 1), &count2));
    cancel.set_delete_after_callback(false);
    cancel.CallCancel();
  }

  sequence->Add(new NotifyRunFunction(&sync));
  sync.Wait();
  EXPECT_EQ(kBound, count1);
  EXPECT_EQ(-100 * kBound, count2);
  worker_->FreeSequence(sequence);
}

// Makes sure that even if one sequence is blocked, another can
// complete, because we have more than one thread at our disposal in
// this worker.
TEST_F(QueuedWorkerPoolTest, SlowAndFastSequences) {
  const int kBound = 42;
  int count = 0;
  SyncPoint sync(thread_runtime_.get());
  SyncPoint wait(thread_runtime_.get());

  QueuedWorkerPool::Sequence* slow_sequence = worker_->NewSequence();
  slow_sequence->Add(new WaitRunFunction(&wait));
  slow_sequence->Add(new NotifyRunFunction(&sync));

  QueuedWorkerPool::Sequence* fast_sequence = worker_->NewSequence();
  for (int i = 0; i < kBound; ++i) {
    fast_sequence->Add(new Increment(i + 1, &count));
  }

  // At this point the fast sequence is churning through its work, while the
  // slow sequence is blocked waiting for SyncPoint 'wait'.  Let the fast
  // sequence unblock it.
  fast_sequence->Add(new NotifyRunFunction(&wait));

  sync.Wait();
  EXPECT_EQ(kBound, count);
  worker_->FreeSequence(fast_sequence);
  worker_->FreeSequence(slow_sequence);
}

class MakeNewSequence : public Function {
 public:
  MakeNewSequence(WorkerTestBase::SyncPoint* sync,
                  QueuedWorkerPool* pool,
                  QueuedWorkerPool::Sequence* sequence)
      : sync_(sync),
        pool_(pool),
        sequence_(sequence) {
  }

  virtual void Run() {
    pool_->FreeSequence(sequence_);
    pool_->NewSequence()->Add(new WorkerTestBase::NotifyRunFunction(sync_));
  }

 private:
  WorkerTestBase::SyncPoint* sync_;
  QueuedWorkerPool* pool_;
  QueuedWorkerPool::Sequence* sequence_;

  DISALLOW_COPY_AND_ASSIGN(MakeNewSequence);
};

TEST_F(QueuedWorkerPoolTest, RestartSequenceFromFunction) {
  SyncPoint sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  sequence->Add(new MakeNewSequence(&sync, worker_.get(), sequence));
  sync.Wait();
}

// Keeps track of whether run or cancel were called.
class LogOpsFunction : public Function {
 public:
  LogOpsFunction() : run_called_(false), cancel_called_(false) {
    set_delete_after_callback(false);
  }
  virtual ~LogOpsFunction() {}

  bool run_called() const { return run_called_; }
  bool cancel_called() const { return cancel_called_; }

 protected:
  virtual void Run() { run_called_ = true; }
  virtual void Cancel() { cancel_called_ = true; }

 private:
  bool run_called_;
  bool cancel_called_;
};

// Make sure calling add after worker was shut down Cancel()s the function
// properly.
TEST_F(QueuedWorkerPoolTest, AddAfterShutDown) {
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  worker_->ShutDown();
  LogOpsFunction f;
  sequence->Add(&f);
  worker_.reset(NULL);
  EXPECT_TRUE(f.cancel_called());
  EXPECT_FALSE(f.run_called());
}

TEST_F(QueuedWorkerPoolTest, LoadShedding) {
  const int kThresh = 100;
  worker_->SetLoadSheddingThreshold(kThresh);
  // Tests that load shedding works, and does so in FIFO order.
  // We do it by first wedging the queues by 2 (as many as we have threads)
  // sequences that wait on SyncPoints followed by 2*kThresh
  // independent LogOpsFunction instances (each in a separate sequence),
  // then a notify. If everything works fine, we'll cancel the first
  // kThresh + 1 LogOps, run the kThresh - 1 last LogOps, and the notify.
  SyncPoint wedge1_sync(thread_runtime_.get());
  SyncPoint wedge2_sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* wedge1 = worker_->NewSequence();
  wedge1->Add(new WaitRunFunction(&wedge1_sync));
  QueuedWorkerPool::Sequence* wedge2 = worker_->NewSequence();
  wedge2->Add(new WaitRunFunction(&wedge2_sync));

  std::vector<QueuedWorkerPool::Sequence*> log_ops;
  std::vector<LogOpsFunction*> log_ops_functions;
  for (int i = 0; i < 2 * kThresh; ++i) {
    LogOpsFunction* fn = new LogOpsFunction;
    QueuedWorkerPool::Sequence* log_op = worker_->NewSequence();
    log_op->Add(fn);
    log_ops.push_back(log_op);
    log_ops_functions.push_back(fn);
  }

  SyncPoint done_sync(thread_runtime_.get());
  QueuedWorkerPool::Sequence* done = worker_->NewSequence();
  done->Add(new NotifyRunFunction(&done_sync));

  wedge1_sync.Notify();
  wedge2_sync.Notify();
  done_sync.Wait();

  // We want to shutdown here since even though done_sync signaled, there
  // may still be a log op running in the 2nd thread. This will wait for it.
  worker_->ShutDown();

  worker_->FreeSequence(wedge1);
  worker_->FreeSequence(wedge2);

  for (int i = 0; i <= kThresh; ++i) {
    EXPECT_TRUE(log_ops_functions[i]->cancel_called());
    EXPECT_FALSE(log_ops_functions[i]->run_called());
    delete log_ops_functions[i];
    worker_->FreeSequence(log_ops[i]);
  }

  for (int i = kThresh + 1; i < 2 * kThresh; ++i) {
    EXPECT_FALSE(log_ops_functions[i]->cancel_called());
    EXPECT_TRUE(log_ops_functions[i]->run_called());
    delete log_ops_functions[i];
    worker_->FreeSequence(log_ops[i]);
  }

  worker_->FreeSequence(done);
}

class NotifyAndWait : public Function {
 public:
  NotifyAndWait(WorkerTestBase::SyncPoint* notify,
                WorkerTestBase::SyncPoint* wait)
      : notify_(notify),
        wait_(wait) {
  }

  virtual void Run() {
    notify_->Notify();
    wait_->Wait();
  }

  virtual void Cancel() {
    CHECK(false);
  }

 private:
  WorkerTestBase::SyncPoint* notify_;
  WorkerTestBase::SyncPoint* wait_;
};

TEST_F(QueuedWorkerPoolTest, MaxQueueSize) {
  SyncPoint started(thread_runtime_.get());
  SyncPoint wait(thread_runtime_.get());
  SyncPoint done(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  sequence->set_max_queue_size(4);
  int count = 0;
  sequence->Add(new NotifyAndWait(&started, &wait));
  started.Wait();
  sequence->Add(new Increment(-100, &count));  // will be canceled: -100.
  sequence->Add(new Increment(-99, &count));   // will be run: +1 == -99.
  sequence->Add(new Increment(-98, &count));   // will be run: +1 == -98.
  sequence->Add(new NotifyRunFunction(&done));
  sequence->Add(new Increment(-97, &count));   // Cancels first increment.
  wait.Notify();
  done.Wait();
  WaitUntilSequenceCompletes(sequence);
  EXPECT_EQ(-97, count);
}

TEST_F(QueuedWorkerPoolTest, CancelPending) {
  SyncPoint wait(thread_runtime_.get());
  SyncPoint done(thread_runtime_.get());
  QueuedWorkerPool::Sequence* sequence = worker_->NewSequence();
  int count = 0;
  sequence->Add(new WaitRunFunction(&wait));
  sequence->Add(new Increment(-100, &count));
  sequence->Add(new Increment(-200, &count));
  sequence->Add(new Increment(-300, &count));
  sequence->CancelPendingFunctions();
  sequence->Add(new NotifyRunFunction(&done));
  wait.Notify();
  done.Wait();
  EXPECT_EQ(-300, count);
}

}  // namespace

}  // namespace net_instaweb
<|endoftext|>


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

#include <cmath>
#include <cassert>
#include "Vector2.h"
#include "MathUtils.h"

namespace ouzel
{
    Vector2::Vector2():
        x(0.0f), y(0.0f)
    {
    }

    Vector2::Vector2(float x, float y):
        x(x), y(y)
    {
    }

    Vector2::Vector2(const float* array)
    {
        set(array);
    }

    Vector2::Vector2(const Vector2& p1, const Vector2& p2)
    {
        set(p1, p2);
    }

    Vector2::Vector2(const Vector2& copy)
    {
        set(copy);
    }

    Vector2::~Vector2()
    {
    }

    const Vector2& Vector2::zero()
    {
        static Vector2 value(0.0f, 0.0f);
        return value;
    }

    const Vector2& Vector2::one()
    {
        static Vector2 value(1.0f, 1.0f);
        return value;
    }

    const Vector2& Vector2::unitX()
    {
        static Vector2 value(1.0f, 0.0f);
        return value;
    }

    const Vector2& Vector2::unitY()
    {
        static Vector2 value(0.0f, 1.0f);
        return value;
    }

    bool Vector2::isZero() const
    {
        return x == 0.0f && y == 0.0f;
    }

    bool Vector2::isOne() const
    {
        return x == 1.0f && y == 1.0f;
    }

    float Vector2::angle(const Vector2& v1, const Vector2& v2)
    {
        float dz = v1.x * v2.y - v1.y * v2.x;
        return atan2f(fabsf(dz) + MATH_FLOAT_SMALL, dot(v1, v2));
    }

    void Vector2::add(const Vector2& v)
    {
        x += v.x;
        y += v.y;
    }

    void Vector2::add(const Vector2& v1, const Vector2& v2, Vector2* dst)
    {
        assert(dst);

        dst->x = v1.x + v2.x;
        dst->y = v1.y + v2.y;
    }

    void Vector2::clamp(const Vector2& min, const Vector2& max)
    {
        assert(!(min.x > max.x || min.y > max.y ));

        // Clamp the x value.
        if (x < min.x)
            x = min.x;
        if (x > max.x)
            x = max.x;

        // Clamp the y value.
        if (y < min.y)
            y = min.y;
        if (y > max.y)
            y = max.y;
    }

    void Vector2::clamp(const Vector2& v, const Vector2& min, const Vector2& max, Vector2* dst)
    {
        assert(dst);
        assert(!(min.x > max.x || min.y > max.y ));

        // Clamp the x value.
        dst->x = v.x;
        if (dst->x < min.x)
            dst->x = min.x;
        if (dst->x > max.x)
            dst->x = max.x;

        // Clamp the y value.
        dst->y = v.y;
        if (dst->y < min.y)
            dst->y = min.y;
        if (dst->y > max.y)
            dst->y = max.y;
    }

    float Vector2::distance(const Vector2& v) const
    {
        float dx = v.x - x;
        float dy = v.y - y;

        return sqrt(dx * dx + dy * dy);
    }

    float Vector2::distanceSquared(const Vector2& v) const
    {
        float dx = v.x - x;
        float dy = v.y - y;
        return (dx * dx + dy * dy);
    }

    float Vector2::dot(const Vector2& v) const
    {
        return (x * v.x + y * v.y);
    }

    float Vector2::dot(const Vector2& v1, const Vector2& v2)
    {
        return (v1.x * v2.x + v1.y * v2.y);
    }

    float Vector2::length() const
    {
        return sqrt(x * x + y * y);
    }

    float Vector2::lengthSquared() const
    {
        return (x * x + y * y);
    }

    void Vector2::negate()
    {
        x = -x;
        y = -y;
    }

    Vector2& Vector2::normalize()
    {
        normalize(this);
        return *this;
    }

    void Vector2::normalize(Vector2* dst) const
    {
        assert(dst);

        if (dst != this)
        {
            dst->x = x;
            dst->y = y;
        }

        float n = x * x + y * y;
        // Already normalized.
        if (n == 1.0f)
            return;

        n = sqrt(n);
        // Too close to zero.
        if (n < MATH_TOLERANCE)
            return;

        n = 1.0f / n;
        dst->x *= n;
        dst->y *= n;
    }

    void Vector2::scale(float scalar)
    {
        x *= scalar;
        y *= scalar;
    }

    void Vector2::scale(const Vector2& scale)
    {
        x *= scale.x;
        y *= scale.y;
    }

    void Vector2::rotate(const Vector2& point, float angle)
    {
        double sinAngle = sin(angle);
        double cosAngle = cos(angle);

        if (point.isZero())
        {
            float tempX = x * cosAngle - y * sinAngle;
            y = y * cosAngle + x * sinAngle;
            x = tempX;
        }
        else
        {
            float tempX = x - point.x;
            float tempY = y - point.y;

            x = tempX * cosAngle - tempY * sinAngle + point.x;
            y = tempY * cosAngle + tempX * sinAngle + point.y;
        }
    }

    void Vector2::set(float x, float y)
    {
        this->x = x;
        this->y = y;
    }

    void Vector2::set(const float* array)
    {
        assert(array);

        x = array[0];
        y = array[1];
    }

    void Vector2::set(const Vector2& v)
    {
        this->x = v.x;
        this->y = v.y;
    }

    void Vector2::set(const Vector2& p1, const Vector2& p2)
    {
         x = p2.x - p1.x;
         y = p2.y - p1.y;
    }

    void Vector2::subtract(const Vector2& v)
    {
        x -= v.x;
        y -= v.y;
    }

    void Vector2::subtract(const Vector2& v1, const Vector2& v2, Vector2* dst)
    {
        assert(dst);

        dst->x = v1.x - v2.x;
        dst->y = v1.y - v2.y;
    }

    void Vector2::smooth(const Vector2& target, float elapsedTime, float responseTime)
    {
        if (elapsedTime > 0)
        {
            *this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
        }
    }
}
<commit_msg>Use float for sin and cos instead of double in Vector2<commit_after>// Copyright (C) 2015 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cmath>
#include <cassert>
#include "Vector2.h"
#include "MathUtils.h"

namespace ouzel
{
    Vector2::Vector2():
        x(0.0f), y(0.0f)
    {
    }

    Vector2::Vector2(float x, float y):
        x(x), y(y)
    {
    }

    Vector2::Vector2(const float* array)
    {
        set(array);
    }

    Vector2::Vector2(const Vector2& p1, const Vector2& p2)
    {
        set(p1, p2);
    }

    Vector2::Vector2(const Vector2& copy)
    {
        set(copy);
    }

    Vector2::~Vector2()
    {
    }

    const Vector2& Vector2::zero()
    {
        static Vector2 value(0.0f, 0.0f);
        return value;
    }

    const Vector2& Vector2::one()
    {
        static Vector2 value(1.0f, 1.0f);
        return value;
    }

    const Vector2& Vector2::unitX()
    {
        static Vector2 value(1.0f, 0.0f);
        return value;
    }

    const Vector2& Vector2::unitY()
    {
        static Vector2 value(0.0f, 1.0f);
        return value;
    }

    bool Vector2::isZero() const
    {
        return x == 0.0f && y == 0.0f;
    }

    bool Vector2::isOne() const
    {
        return x == 1.0f && y == 1.0f;
    }

    float Vector2::angle(const Vector2& v1, const Vector2& v2)
    {
        float dz = v1.x * v2.y - v1.y * v2.x;
        return atan2f(fabsf(dz) + MATH_FLOAT_SMALL, dot(v1, v2));
    }

    void Vector2::add(const Vector2& v)
    {
        x += v.x;
        y += v.y;
    }

    void Vector2::add(const Vector2& v1, const Vector2& v2, Vector2* dst)
    {
        assert(dst);

        dst->x = v1.x + v2.x;
        dst->y = v1.y + v2.y;
    }

    void Vector2::clamp(const Vector2& min, const Vector2& max)
    {
        assert(!(min.x > max.x || min.y > max.y ));

        // Clamp the x value.
        if (x < min.x)
            x = min.x;
        if (x > max.x)
            x = max.x;

        // Clamp the y value.
        if (y < min.y)
            y = min.y;
        if (y > max.y)
            y = max.y;
    }

    void Vector2::clamp(const Vector2& v, const Vector2& min, const Vector2& max, Vector2* dst)
    {
        assert(dst);
        assert(!(min.x > max.x || min.y > max.y ));

        // Clamp the x value.
        dst->x = v.x;
        if (dst->x < min.x)
            dst->x = min.x;
        if (dst->x > max.x)
            dst->x = max.x;

        // Clamp the y value.
        dst->y = v.y;
        if (dst->y < min.y)
            dst->y = min.y;
        if (dst->y > max.y)
            dst->y = max.y;
    }

    float Vector2::distance(const Vector2& v) const
    {
        float dx = v.x - x;
        float dy = v.y - y;

        return sqrt(dx * dx + dy * dy);
    }

    float Vector2::distanceSquared(const Vector2& v) const
    {
        float dx = v.x - x;
        float dy = v.y - y;
        return (dx * dx + dy * dy);
    }

    float Vector2::dot(const Vector2& v) const
    {
        return (x * v.x + y * v.y);
    }

    float Vector2::dot(const Vector2& v1, const Vector2& v2)
    {
        return (v1.x * v2.x + v1.y * v2.y);
    }

    float Vector2::length() const
    {
        return sqrt(x * x + y * y);
    }

    float Vector2::lengthSquared() const
    {
        return (x * x + y * y);
    }

    void Vector2::negate()
    {
        x = -x;
        y = -y;
    }

    Vector2& Vector2::normalize()
    {
        normalize(this);
        return *this;
    }

    void Vector2::normalize(Vector2* dst) const
    {
        assert(dst);

        if (dst != this)
        {
            dst->x = x;
            dst->y = y;
        }

        float n = x * x + y * y;
        // Already normalized.
        if (n == 1.0f)
            return;

        n = sqrt(n);
        // Too close to zero.
        if (n < MATH_TOLERANCE)
            return;

        n = 1.0f / n;
        dst->x *= n;
        dst->y *= n;
    }

    void Vector2::scale(float scalar)
    {
        x *= scalar;
        y *= scalar;
    }

    void Vector2::scale(const Vector2& scale)
    {
        x *= scale.x;
        y *= scale.y;
    }

    void Vector2::rotate(const Vector2& point, float angle)
    {
        float sinAngle = sinf(angle);
        float cosAngle = cosf(angle);

        if (point.isZero())
        {
            float tempX = x * cosAngle - y * sinAngle;
            y = y * cosAngle + x * sinAngle;
            x = tempX;
        }
        else
        {
            float tempX = x - point.x;
            float tempY = y - point.y;

            x = tempX * cosAngle - tempY * sinAngle + point.x;
            y = tempY * cosAngle + tempX * sinAngle + point.y;
        }
    }

    void Vector2::set(float x, float y)
    {
        this->x = x;
        this->y = y;
    }

    void Vector2::set(const float* array)
    {
        assert(array);

        x = array[0];
        y = array[1];
    }

    void Vector2::set(const Vector2& v)
    {
        this->x = v.x;
        this->y = v.y;
    }

    void Vector2::set(const Vector2& p1, const Vector2& p2)
    {
         x = p2.x - p1.x;
         y = p2.y - p1.y;
    }

    void Vector2::subtract(const Vector2& v)
    {
        x -= v.x;
        y -= v.y;
    }

    void Vector2::subtract(const Vector2& v1, const Vector2& v2, Vector2* dst)
    {
        assert(dst);

        dst->x = v1.x - v2.x;
        dst->y = v1.y - v2.y;
    }

    void Vector2::smooth(const Vector2& target, float elapsedTime, float responseTime)
    {
        if (elapsedTime > 0)
        {
            *this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014,2015,2016,2018 CNRS
// Authors: Florent Lamiraux, Joseph Mirabel, Diane Bury
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#define HPP_DEBUG 1

#include <hpp/core/continuous-validation/body-pair-collision.hh>

#include <limits>

#include <hpp/fcl/collision_data.h>
#include <hpp/fcl/collision.h>
#include <hpp/pinocchio/body.hh>
#include <hpp/pinocchio/collision-object.hh>

#include <hpp/core/path.hh>
#include <hpp/core/straight-path.hh> // To enable dynamic casting (needs inheritance).

namespace hpp {
  namespace core {
    namespace continuousValidation {

      bool BodyPairCollision::validateConfiguration (const value_type& t, interval_t& interval,
                ValidationReportPtr_t& report,
                const pinocchio::DeviceData& data)
      {
        namespace icl = boost::icl;
        using std::numeric_limits;

        if (valid_) {
          interval = path_->timeRange ();
          assert (interval.second > interval.first);
          return true;
        }
        continuous_interval iclInterval (interval.first, interval.second,
          icl::interval_bounds::closed());
        if (icl::contains (validInterval_, iclInterval))
        {
          // TODO interval could probably be enlarge using validInterval_
          // interval = validInterval_;
          assert (interval.second > interval.first);
          return true;
        }

        value_type distanceLowerBound;
        if (!computeDistanceLowerBound(distanceLowerBound, report, data))
        {
          return false;
        }

        value_type halfLengthDist, halfLengthTol;
        /// \todo A finer bound could be computed when path is an
        ///       InterpolatedPath using the maximal velocity on each
        ///       subinterval
        if (distanceLowerBound == numeric_limits <value_type>::infinity ()) {
          halfLengthDist = numeric_limits <value_type>::infinity ();
          halfLengthTol = 0;
        } else {
          value_type Vm;
          halfLengthDist = collisionFreeInterval(t, distanceLowerBound, Vm);
          if (Vm != 0) {
            halfLengthTol = 2*tolerance_/Vm;
          } else {
            halfLengthTol = numeric_limits <value_type>::infinity ();
          }
        }
        assert (!std::isnan (halfLengthDist));
        assert (!std::isnan (halfLengthTol));
        interval.first = t - (halfLengthDist + halfLengthTol);
        interval.second = t + (halfLengthDist + halfLengthTol);
        validInterval_.insert (continuous_interval(interval.first,
          interval.second, icl::interval_bounds::closed()));
        // Check if the whole path is valid.
        iclInterval = continuous_interval (path_->timeRange ().first,
          path_->timeRange ().second, icl::interval_bounds::closed());
        if (icl::contains (validInterval_, iclInterval))
          valid_ = true;
        assert (interval.second > interval.first);
        return true;
      }

      void BodyPairCollision::setupPath()
      {
        if (HPP_DYNAMIC_PTR_CAST(StraightPath, path_)) refine_ = false;
        Vb_ = vector_t (path_->outputDerivativeSize());
        value_type t0 = path_->timeRange ().first;
        value_type t1 = path_->timeRange ().second;
        assert (t1 >= t0);
        if (t1 - t0 == 0) {
          maximalVelocity_ = std::numeric_limits<value_type>::infinity();
          refine_ = false;
        } else {
          path_->velocityBound (Vb_, t0, t1);
          maximalVelocity_ = computeMaximalVelocity (Vb_);
        }
      }

      value_type BodyPairCollision::collisionFreeInterval(const value_type &t,
                                      const value_type &distanceLowerBound,
                                      value_type &maxVelocity) const
      {
        value_type T[3], Vm[2];
        value_type tm, tM;
        maxVelocity = maximalVelocity_;
        T[0] = distanceLowerBound / maxVelocity;
        if (!refine_)
          return T[0];
        else
        {
          tm = t - T[0];
          tM = t + T[0];
          bool  leftIsValid = (tm < path_->timeRange().first );
          bool rightIsValid = (tM > path_->timeRange().second);
          if (leftIsValid && rightIsValid)
            return T[0];

          for (int i = 0; i < 2; ++i)
          {
            tm = t - (leftIsValid ? 0 : T[i]);
            tM = t + (rightIsValid ? 0 : T[i]);
            path_->velocityBound(Vb_, tm, tM);
            Vm[i] = computeMaximalVelocity(Vb_);
            T[i + 1] = distanceLowerBound / Vm[i];
          }
          assert(maximalVelocity_ >= Vm[1] && Vm[1] >= Vm[0] && T[1] >= T[2] && T[2] >= T[0]);
          // hppDout (info, "Refine changed the interval length of " << T[0] / T[2] << ", from " << T[0] << " to " << T[2]);
          maxVelocity = Vm[1];
          return T[2];
        }
      }

      bool BodyPairCollision::computeDistanceLowerBound(value_type &distanceLowerBound,
        ValidationReportPtr_t& report,
        const pinocchio::DeviceData& data) const
      {
        using std::numeric_limits;
        distanceLowerBound = numeric_limits <value_type>::infinity ();
        assert (collisionRequest_.enable_distance_lower_bound == true);
        const CollisionPairs_t& prs (pairs());
        for (CollisionPairs_t::const_iterator _pair = prs.begin();
            _pair != prs.end(); ++_pair) {
          pinocchio::FclConstCollisionObjectPtr_t object_a = _pair->first ->fcl (data);
          pinocchio::FclConstCollisionObjectPtr_t object_b = _pair->second->fcl (data);
          fcl::CollisionResult result;
          fcl::collide (object_a, object_b, collisionRequest_, result);
          // Get result
          if (result.isCollision ()) {
            setReport(report, result, *_pair);
            return false;
          }
          if (result.distance_lower_bound < distanceLowerBound) {
            distanceLowerBound = result.distance_lower_bound;
            assert (distanceLowerBound > 0);
          }
        }
        return true;
      }
    } // namespace continuousValidation
  } // namespace core
} // namespace hpp
<commit_msg>[BodyPairCollision] relax assert.<commit_after>// Copyright (c) 2014,2015,2016,2018 CNRS
// Authors: Florent Lamiraux, Joseph Mirabel, Diane Bury
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#define HPP_DEBUG 1

#include <hpp/core/continuous-validation/body-pair-collision.hh>

#include <limits>

#include <hpp/fcl/collision_data.h>
#include <hpp/fcl/collision.h>
#include <hpp/pinocchio/body.hh>
#include <hpp/pinocchio/collision-object.hh>

#include <hpp/core/path.hh>
#include <hpp/core/straight-path.hh> // To enable dynamic casting (needs inheritance).

namespace hpp {
  namespace core {
    namespace continuousValidation {

      bool BodyPairCollision::validateConfiguration (const value_type& t, interval_t& interval,
                ValidationReportPtr_t& report,
                const pinocchio::DeviceData& data)
      {
        namespace icl = boost::icl;
        using std::numeric_limits;

        if (valid_) {
          interval = path_->timeRange ();
          assert (interval.second > interval.first);
          return true;
        }
        continuous_interval iclInterval (interval.first, interval.second,
          icl::interval_bounds::closed());
        if (icl::contains (validInterval_, iclInterval))
        {
          // TODO interval could probably be enlarge using validInterval_
          // interval = validInterval_;
          assert (interval.second > interval.first);
          return true;
        }

        value_type distanceLowerBound;
        if (!computeDistanceLowerBound(distanceLowerBound, report, data))
        {
          return false;
        }

        value_type halfLengthDist, halfLengthTol;
        /// \todo A finer bound could be computed when path is an
        ///       InterpolatedPath using the maximal velocity on each
        ///       subinterval
        if (distanceLowerBound == numeric_limits <value_type>::infinity ()) {
          halfLengthDist = numeric_limits <value_type>::infinity ();
          halfLengthTol = 0;
        } else {
          value_type Vm;
          halfLengthDist = collisionFreeInterval(t, distanceLowerBound, Vm);
          if (Vm != 0) {
            halfLengthTol = 2*tolerance_/Vm;
          } else {
            halfLengthTol = numeric_limits <value_type>::infinity ();
          }
        }
        assert (!std::isnan (halfLengthDist));
        assert (!std::isnan (halfLengthTol));
        interval.first = t - (halfLengthDist + halfLengthTol);
        interval.second = t + (halfLengthDist + halfLengthTol);
        validInterval_.insert (continuous_interval(interval.first,
          interval.second, icl::interval_bounds::closed()));
        // Check if the whole path is valid.
        iclInterval = continuous_interval (path_->timeRange ().first,
          path_->timeRange ().second, icl::interval_bounds::closed());
        if (icl::contains (validInterval_, iclInterval))
          valid_ = true;
        assert (interval.second > interval.first || path()->length() == 0);
        return true;
      }

      void BodyPairCollision::setupPath()
      {
        if (HPP_DYNAMIC_PTR_CAST(StraightPath, path_)) refine_ = false;
        Vb_ = vector_t (path_->outputDerivativeSize());
        value_type t0 = path_->timeRange ().first;
        value_type t1 = path_->timeRange ().second;
        assert (t1 >= t0);
        if (t1 - t0 == 0) {
          maximalVelocity_ = std::numeric_limits<value_type>::infinity();
          refine_ = false;
        } else {
          path_->velocityBound (Vb_, t0, t1);
          maximalVelocity_ = computeMaximalVelocity (Vb_);
        }
      }

      value_type BodyPairCollision::collisionFreeInterval(const value_type &t,
                                      const value_type &distanceLowerBound,
                                      value_type &maxVelocity) const
      {
        value_type T[3], Vm[2];
        value_type tm, tM;
        maxVelocity = maximalVelocity_;
        T[0] = distanceLowerBound / maxVelocity;
        if (!refine_)
          return T[0];
        else
        {
          tm = t - T[0];
          tM = t + T[0];
          bool  leftIsValid = (tm < path_->timeRange().first );
          bool rightIsValid = (tM > path_->timeRange().second);
          if (leftIsValid && rightIsValid)
            return T[0];

          for (int i = 0; i < 2; ++i)
          {
            tm = t - (leftIsValid ? 0 : T[i]);
            tM = t + (rightIsValid ? 0 : T[i]);
            path_->velocityBound(Vb_, tm, tM);
            Vm[i] = computeMaximalVelocity(Vb_);
            T[i + 1] = distanceLowerBound / Vm[i];
          }
          assert(maximalVelocity_ >= Vm[1] && Vm[1] >= Vm[0] && T[1] >= T[2] && T[2] >= T[0]);
          // hppDout (info, "Refine changed the interval length of " << T[0] / T[2] << ", from " << T[0] << " to " << T[2]);
          maxVelocity = Vm[1];
          return T[2];
        }
      }

      bool BodyPairCollision::computeDistanceLowerBound(value_type &distanceLowerBound,
        ValidationReportPtr_t& report,
        const pinocchio::DeviceData& data) const
      {
        using std::numeric_limits;
        distanceLowerBound = numeric_limits <value_type>::infinity ();
        assert (collisionRequest_.enable_distance_lower_bound == true);
        const CollisionPairs_t& prs (pairs());
        for (CollisionPairs_t::const_iterator _pair = prs.begin();
            _pair != prs.end(); ++_pair) {
          pinocchio::FclConstCollisionObjectPtr_t object_a = _pair->first ->fcl (data);
          pinocchio::FclConstCollisionObjectPtr_t object_b = _pair->second->fcl (data);
          fcl::CollisionResult result;
          fcl::collide (object_a, object_b, collisionRequest_, result);
          // Get result
          if (result.isCollision ()) {
            setReport(report, result, *_pair);
            return false;
          }
          if (result.distance_lower_bound < distanceLowerBound) {
            distanceLowerBound = result.distance_lower_bound;
            assert (distanceLowerBound > 0);
          }
        }
        return true;
      }
    } // namespace continuousValidation
  } // namespace core
} // namespace hpp
<|endoftext|>


<commit_before>#ifndef _CONVERSION_ALGORITHM_
#define _CONVERSION_ALGORITHM_

#include "ConversionAlgorithmInterface.hpp"
#include "../ConversionException.hpp"

#include <memory>
#include <string>
#include <map>

namespace protobuf_decoder
{
    namespace algorithm
    {
        class ConversionAlgorithm : public ConversionAlgorithmInterface
        {
        public:
            ConversionAlgorithm(const std::string& iKey);

            virtual ~ConversionAlgorithm() {}

            static std::shared_ptr<ConversionAlgorithmInterface> Create(const std::string& iKey);

            virtual std::shared_ptr<ConversionAlgorithmInterface> create() = 0;

            static std::map<std::string, std::string> GetAlgorithms();

        private:
            static std::map<std::string, ConversionAlgorithm*> &getExemplars();
        };
    }
}

#endif //_CONVERSION_ALGORITHM_
<commit_msg>Update ConversionAlgorithm.hpp<commit_after>#ifndef _CONVERSION_ALGORITHM_
#define _CONVERSION_ALGORITHM_

#include "ConversionAlgorithmInterface.hpp"
#include "../ConversionException.hpp"

#include <memory>
#include <string>
#include <map>

namespace protobuf_decoder
{
    namespace algorithm
    {
        /**
         * @brief Constructor base for algorithms.
         *
         * Base in virtual constructor pattern responsible for managing the
         * creation of algorithm objects from a string key.
         */
        class ConversionAlgorithm : public ConversionAlgorithmInterface
        {
        public:
            /**
             * @brief Constructor
             *
             * On first call, will register the algorithm and its
             * key in a static table.
             */
            ConversionAlgorithm(const std::string& iKey);

            /**
             * @brief Destructor
             */
            virtual ~ConversionAlgorithm() {}

            /**
             * @brief Create algorithm from key.
             *
             * @note If no algorithm has been registered for key in input
             * an empty shared_ptr will be returned.
             *
             * @param iKey Key for algorithm.
             *
             * @return shared_ptr<ConversionAlgorithmInterface> Algorithm.
             */
            static std::shared_ptr<ConversionAlgorithmInterface> Create(const std::string& iKey);

            /**
             * @brief Creation for algorithm.
             *
             * Should be implemented for each algorithm.
             *
             * @return std::shared_ptr<ConversionAlgorithmInterface> Algorithm.
             */
            virtual std::shared_ptr<ConversionAlgorithmInterface> create() = 0;

            /**
             * @brief Get all registered algorithms.
             *
             * @return map<string, string> Name, key pair for all algorithms.
             */
            static std::map<std::string, std::string> GetAlgorithms();

        private:
            /**
             * @brief Get static registration table.
             *
             * @return map<string, ConversionAlgorithm*> Key, exemplar pair.
             */
            static std::map<std::string, ConversionAlgorithm*> &getExemplars();
        };
    }
}

#endif //_CONVERSION_ALGORITHM_
<|endoftext|>


<commit_before>//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "mbedtls.h"

void SSL_GetCertDateTime_internal(DATE_TIME_INFO *dt, mbedtls_x509_time *mt)
{
    dt->year = mt->year;
    dt->month = mt->mon;
    dt->day = mt->day;
    dt->hour = mt->hour;
    dt->minute = mt->min;
    dt->second = mt->sec;

    dt->dlsTime = 0;
    dt->tzOffset = 0;
}

bool ssl_parse_certificate_internal(void *certificate, size_t size, void *pwd, void *x509CertData)
{
    (void)pwd;

    int ret;
    X509CertData *x509 = (X509CertData *)x509CertData;

    mbedtls_x509_crt cacert;
    mbedtls_x509_crt_init(&cacert);

    /////////////////////////////////////////////////////////////////////////////////////////////////
    // developer notes:                                                                            //
    // this call parses certificates in both string and binary formats                             //
    // when the formart is a string it has to include the terminator otherwise the parse will fail //
    /////////////////////////////////////////////////////////////////////////////////////////////////
    ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)certificate, size);
    if (ret < 0)
    {
        return false;
    }

    mbedtls_x509_dn_gets(x509->Issuer, sizeof(x509->Issuer) - 1, &cacert.issuer);

    mbedtls_x509_dn_gets(x509->Subject, sizeof(x509->Subject) - 1, &cacert.subject);

    SSL_GetCertDateTime_internal(&x509->EffectiveDate, &cacert.valid_from);

    SSL_GetCertDateTime_internal(&x509->ExpirationDate, &cacert.valid_to);

    return true;
}
<commit_msg>Fix memory leak when parsing X509 certs (#2010)<commit_after>//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "mbedtls.h"

void SSL_GetCertDateTime_internal(DATE_TIME_INFO *dt, mbedtls_x509_time *mt)
{
    dt->year = mt->year;
    dt->month = mt->mon;
    dt->day = mt->day;
    dt->hour = mt->hour;
    dt->minute = mt->min;
    dt->second = mt->sec;

    dt->dlsTime = 0;
    dt->tzOffset = 0;
}

bool ssl_parse_certificate_internal(void *certificate, size_t size, void *pwd, void *x509CertData)
{
    (void)pwd;

    int ret;
    X509CertData *x509 = (X509CertData *)x509CertData;

    mbedtls_x509_crt cacert;
    mbedtls_x509_crt_init(&cacert);

    /////////////////////////////////////////////////////////////////////////////////////////////////
    // developer notes:                                                                            //
    // this call parses certificates in both string and binary formats                             //
    // when the formart is a string it has to include the terminator otherwise the parse will fail //
    /////////////////////////////////////////////////////////////////////////////////////////////////
    ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)certificate, size);
    if (ret < 0)
    {
        mbedtls_x509_crt_free(&cacert);
        return false;
    }

    mbedtls_x509_dn_gets(x509->Issuer, sizeof(x509->Issuer) - 1, &cacert.issuer);

    mbedtls_x509_dn_gets(x509->Subject, sizeof(x509->Subject) - 1, &cacert.subject);

    SSL_GetCertDateTime_internal(&x509->EffectiveDate, &cacert.valid_from);

    SSL_GetCertDateTime_internal(&x509->ExpirationDate, &cacert.valid_to);

    mbedtls_x509_crt_free(&cacert);

    return true;
}
<|endoftext|>


<commit_before>#ifndef RADIUMENGINE_VERTEXPICKING_HPP
#define RADIUMENGINE_VERTEXPICKING_HPP

#include <GuiBase/RaGuiBase.hpp>

#include <Engine/RaEngine.hpp>
#include <Engine/RadiumEngine.hpp>
#include <Core/Mesh/MeshPrimitives.hpp>
#include <Engine/Component/Component.hpp>
#include <Engine/Renderer/Renderer.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderConfigFactory.hpp>
#include <Engine/Renderer/RenderObject/RenderObjectManager.hpp>

#include <QObject>

namespace Ra
{
    namespace Gui
    {
        /// Data representing a feature on a Render Object.
        /// If m_featureType==RO, this means that no feature is selected.
        /// Besides the Render Object index, the data are:
        ///  - for vertices: the index.
        ///  - for edges: the vertices indices.
        ///  - for triangles and faces: the triangle/face index and its vertices indices.
        struct FeatureData
        {
            FeatureData() : m_featureType(Engine::Renderer::RO), m_roIdx(-1)
            {}

            Engine::Renderer::PickingMode m_featureType;
            std::vector< int > m_data;
            uint m_roIdx;
        };

        class FeaturePickingManager
        {
        public:
            FeaturePickingManager();
            ~FeaturePickingManager();

            /// Registers the index of the first RenderObject from which feature picking is enabled.
            inline void setMinRenderObjectIndex(uint id)
            {
                m_firstRO = id;
            }

            /// Performs the picking of the feature on the given Render Object, according to the picking query and the cast ray.
            void doPicking( int roIndex, const Engine::Renderer::PickingQuery& query, const Core::Ray& ray );

            /// Const accessor to the selected feature data.
            inline const FeatureData& getFeatureData() const
            {
                return m_FeatureData;
            }

            /// Non-const accessor to the selected feature data.
            inline FeatureData& getFeatureData()
            {
                return m_FeatureData;
            }

            /// Clears the selection.
            void clearFeature();

            /// Sets the selection to the idx-th vertex.
            /// Note: Only if the selected feature is in VERTEX mode and id is a valid vertex id.
            void setVertexIndex(int id);

            /// Sets the selection to the idx-th triangle.
            /// Note: Only if the selected feature is in TRIANGLE mode and id is a valid triangle id.
            void setTriangleIndex(int id);

        private:
            /// The selected feature data.
            FeatureData m_FeatureData;
            /// The first Render Object on which Feature Picking is allowed.
            uint m_firstRO;
        };
    } // namespace Gui
} // namespace Ra

#endif // RADIUMENGINE_VERTEXPICKING_HPP
<commit_msg>Add missing dll export/import<commit_after>#ifndef RADIUMENGINE_VERTEXPICKING_HPP
#define RADIUMENGINE_VERTEXPICKING_HPP

#include <GuiBase/RaGuiBase.hpp>

#include <Engine/RaEngine.hpp>
#include <Engine/RadiumEngine.hpp>
#include <Core/Mesh/MeshPrimitives.hpp>
#include <Engine/Component/Component.hpp>
#include <Engine/Renderer/Renderer.hpp>
#include <Engine/Renderer/RenderTechnique/ShaderConfigFactory.hpp>
#include <Engine/Renderer/RenderObject/RenderObjectManager.hpp>

#include <QObject>

namespace Ra
{
    namespace Gui
    {
        /// Data representing a feature on a Render Object.
        /// If m_featureType==RO, this means that no feature is selected.
        /// Besides the Render Object index, the data are:
        ///  - for vertices: the index.
        ///  - for edges: the vertices indices.
        ///  - for triangles and faces: the triangle/face index and its vertices indices.
        struct RA_GUIBASE_API FeatureData
        {
            FeatureData() : m_featureType(Engine::Renderer::RO), m_roIdx(-1)
            {}

            Engine::Renderer::PickingMode m_featureType;
            std::vector< int > m_data;
            uint m_roIdx;
        };

        class RA_GUIBASE_API FeaturePickingManager
        {
        public:
            FeaturePickingManager();
            ~FeaturePickingManager();

            /// Registers the index of the first RenderObject from which feature picking is enabled.
            inline void setMinRenderObjectIndex(uint id)
            {
                m_firstRO = id;
            }

            /// Performs the picking of the feature on the given Render Object, according to the picking query and the cast ray.
            void doPicking( int roIndex, const Engine::Renderer::PickingQuery& query, const Core::Ray& ray );

            /// Const accessor to the selected feature data.
            inline const FeatureData& getFeatureData() const
            {
                return m_FeatureData;
            }

            /// Non-const accessor to the selected feature data.
            inline FeatureData& getFeatureData()
            {
                return m_FeatureData;
            }

            /// Clears the selection.
            void clearFeature();

            /// Sets the selection to the idx-th vertex.
            /// Note: Only if the selected feature is in VERTEX mode and id is a valid vertex id.
            void setVertexIndex(int id);

            /// Sets the selection to the idx-th triangle.
            /// Note: Only if the selected feature is in TRIANGLE mode and id is a valid triangle id.
            void setTriangleIndex(int id);

        private:
            /// The selected feature data.
            FeatureData m_FeatureData;
            /// The first Render Object on which Feature Picking is allowed.
            uint m_firstRO;
        };
    } // namespace Gui
} // namespace Ra

#endif // RADIUMENGINE_VERTEXPICKING_HPP
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "paramwindows.h"
#include "ui_mainwindow.h"

#include <QMessageBox>
#include <QDialog>
#include "windowstatistics.h"
#include "createpartymultigamer.h"
#include "launchsologame.h"
#include "widgetchat.h"
#include "joinparty.h"
#include "frmconnexion.h"
#include "help.h"
#include <QAction>
#include <currentProfile.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Maximize the window
    showMaximized();

    //Show welcome message
    ui->statusBar->showMessage("Non connecté - Bienvenue sur BOMBERMAN.", 15000);
    frmConnexion* frmConnect = new frmConnexion();
    frmConnect->show();

    // Linking buttons to action triggered
    connect(ui->actionDemarrerPartieSolo,SIGNAL(triggered()),this,SLOT(BeginPartySolo()));
    connect(ui->actionDemarrerPartieMulti,SIGNAL(triggered()),this,SLOT(BeginPartyMulti()));
    connect(ui->actionChargerPartieSolo,SIGNAL(triggered()),this,SLOT(LoadPartySolo()));
    connect(ui->actionChargerPartieMulti,SIGNAL(triggered()),this,SLOT(LoadPartyMulti()));
    connect(ui->actionSauvegarderPartieSolo,SIGNAL(triggered()),this,SLOT(SavePartySolo()));
    connect(ui->actionQuitter,SIGNAL(triggered()),this,SLOT(Quit()));
    connect(ui->actionCommandes_de_jeu,SIGNAL(triggered()),this,SLOT(GameControls()));
    connect(ui->actionAffichage,SIGNAL(triggered()),this,SLOT(DisplaySetting()));
    connect(ui->actionAudio,SIGNAL(triggered()),this,SLOT(AudioSetting()));
    connect(ui->actionAide,SIGNAL(triggered()),this,SLOT(Help()));
    connect(ui->actionA_propos,SIGNAL(triggered()),this,SLOT(Credits()));
    connect(ui->actionAffichageStatistics,SIGNAL(triggered()),this,SLOT(Statistics()));
    connect(frmConnect,SIGNAL(connexionOk()),this,SLOT(UtilisateurConnecte()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::BeginPartySolo()
{
    /*QMessageBox msg;
    msg.setText("Vous venez de lancer une partie solo.");
    msg.exec();*/

    LaunchSoloGame* formsologame = new LaunchSoloGame(this);
    formsologame->show();
    ui->statusBar->showMessage("Lancez une nouvelle partie solo.", 15000);
}

void MainWindow::UtilisateurConnecte()
{
    currentProfile* user  = currentProfile::getInstance();
    ui->statusBar->showMessage("Connecté - Bienvenue sur BOMBERMAN " + user->getPseudo() + ".", 15000);
}

void MainWindow::BeginPartyMulti()
{

    createpartymultigamer* CreatePartyMultiGamer;
    CreatePartyMultiGamer = new createpartymultigamer(this);
    CreatePartyMultiGamer->exec();

    //Test du module chat
    //Ajout du widgetChat

    QList<QString> *listJoueur = new QList<QString>();
    listJoueur->insert(0,"toto");
    widgetChat *Chat = new widgetChat(this,listJoueur);
    Chat->setGeometry(10,40,590,500);
    Chat->show();

    ui->statusBar->showMessage("Vous avez lancé la partie multijoueur.", 15000);
}

void MainWindow::LoadPartySolo()
{
    // Ouverture du dossier parent de la solution et filtre sur les fichiers de type texte pour sélection fichier à ouvrir
    QString fichier = QFileDialog::getOpenFileName(this, "Ouvrir un fichier", QString(), "Fichiers texte (*.txt)");

    // Message d'information provisoire indiquant le chemin d'accès au fichier à ouvrir
    // QMessageBox::information(this, "Fichier", "Vous avez ouvert le fichier :\n" + fichier);

    // on déclare la variable de type fichier, puis on l'ouvre en mode "lecture seule"
    QFile fichierACharger(fichier);

    if (fichierACharger.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream flux (&fichierACharger);

        QString ligne;

        // On parcours ensuite le fichier ligne par ligne en y appliquant un traitement : ici affichage d'une messageBox
        while(! flux.atEnd())
        {
            ligne = flux.readLine();

            QMessageBox msg;
            msg.setText(ligne);
            msg.exec();
        }
    }
}

void MainWindow::LoadPartyMulti()
{
    /*QMessageBox msg;
    msg.setText("Vous venez de charger une partie multi.");
    msg.exec();
    ui->statusBar->showMessage("Vous avez chargé une partie multijoueur.", 15000);*/

    JoinParty* JoinPartyMulti;
    JoinPartyMulti = new JoinParty(this);
//JoinPartyMulti->setGeometry(50,100,200,190);
    JoinPartyMulti->show();
}

void MainWindow::SavePartySolo()
{
    // On ouvre une boite de dialogue permettant la sauvegarde d'un fichier
    QString path = QFileDialog::getSaveFileName(this, "Enregistrer un fichier", QString("*.txt"), "Fichiers texte (*.txt);; Tous les fichiers (*.*)");

    // On crée le fichier ou écrase un existant
    QFile file(path);

    if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);
        out << "J'ai sauvegardé le fichier " + path;

        file.close();

        ui->statusBar->showMessage("Partie sauvegardée : " + path, 15000);
    }
}

void MainWindow::Quit()
{
    if (QMessageBox::Yes == QMessageBox(QMessageBox::Warning, "Confirmation de sortie.", "Êtes-vous sûr de vouloir quitter BomberMan ?", QMessageBox::Yes|QMessageBox::No).exec())
    {
        exit(true);
    }
}

void MainWindow::GameControls()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 2);
    paramForm->show();
}

void MainWindow::DisplaySetting()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 1);
    paramForm->show();
}

void MainWindow::AudioSetting()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 0);
    paramForm->show();
}

void MainWindow::Help()
{

    help* helpWindow = new help(this);

    // helpWindow->show(); // Roman : 30/05/2014 : Mis en commentaire car s'ouvre déjà deans la classe help

    ui->statusBar->showMessage("Vous venez de fermer la fenêtre d'Aide.", 15000);

 }

void MainWindow::Credits()
{
    /*QMessageBox msg;
    msg.setText("Vous venez d'ouvrir les configurations audio.");
    msg.exec();*/

    QMessageBox::about(this, tr("BomberMAN"),
                 tr("The BomberMAN  is a strategic, maze-based video game franchise originally developed by Hudson Soft. The original game was published in 1983 and new games have been published at irregular intervals ever since.                Several titles in the 2000s were published by fellow Japanese game company Konami, who gained full control of the franchise when they purchased and absorbed Hudson in 2012. Today, Bomberman has featured in over 70 different games on numerous platforms (including all Nintendo platforms save for the 3DS and Wii U), as well as several anime and manga.His franchise is one of the most commercially successful of all time.
Realised by the Dream-Team :

Petra Kratochvilova

Thibaud Cutullic

Yoann Solacroup

Yann Damon

Gregoire Quincy

Roman Logvinov

Damien Moro
"));
}

void MainWindow::Statistics()
{
    windowstatistics* Stats;
    Stats = new windowstatistics(this);
    Stats->setGeometry(50,100,490,190);
    Stats->exec();
    ui->statusBar->showMessage("Vous avez consulté les statistics.", 15000);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event && event->key() == Qt::Key_F1) {
        Help();// Ouvre la fenêtre d'aide
 }
}

//Cela fonction mais lance la fenetre 3 fois
/*bool MainWindow::event(QEvent *event)//Test lancement fenetre Aide en appuant la touche "F1"
{
    QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
    if(kevent && kevent ->key() == Qt::Key_F1)
        Help();
    return true;

}
*/

<commit_msg>Update mainwindow.cpp<commit_after>#include "mainwindow.h"
#include "paramwindows.h"
#include "ui_mainwindow.h"

#include <QMessageBox>
#include <QDialog>
#include "windowstatistics.h"
#include "createpartymultigamer.h"
#include "launchsologame.h"
#include "widgetchat.h"
#include "joinparty.h"
#include "frmconnexion.h"
#include "help.h"
#include <QAction>
#include "currentProfile.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Maximize the window
    showMaximized();

    //Show welcome message
    ui->statusBar->showMessage("Non connecté - Bienvenue sur BOMBERMAN.", 15000);
    frmConnexion* frmConnect = new frmConnexion();
    frmConnect->show();

    // Linking buttons to action triggered
    connect(ui->actionDemarrerPartieSolo,SIGNAL(triggered()),this,SLOT(BeginPartySolo()));
    connect(ui->actionDemarrerPartieMulti,SIGNAL(triggered()),this,SLOT(BeginPartyMulti()));
    connect(ui->actionChargerPartieSolo,SIGNAL(triggered()),this,SLOT(LoadPartySolo()));
    connect(ui->actionChargerPartieMulti,SIGNAL(triggered()),this,SLOT(LoadPartyMulti()));
    connect(ui->actionSauvegarderPartieSolo,SIGNAL(triggered()),this,SLOT(SavePartySolo()));
    connect(ui->actionQuitter,SIGNAL(triggered()),this,SLOT(Quit()));
    connect(ui->actionCommandes_de_jeu,SIGNAL(triggered()),this,SLOT(GameControls()));
    connect(ui->actionAffichage,SIGNAL(triggered()),this,SLOT(DisplaySetting()));
    connect(ui->actionAudio,SIGNAL(triggered()),this,SLOT(AudioSetting()));
    connect(ui->actionAide,SIGNAL(triggered()),this,SLOT(Help()));
    connect(ui->actionA_propos,SIGNAL(triggered()),this,SLOT(Credits()));
    connect(ui->actionAffichageStatistics,SIGNAL(triggered()),this,SLOT(Statistics()));
    connect(frmConnect,SIGNAL(connexionOk()),this,SLOT(UtilisateurConnecte()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::BeginPartySolo()
{
    /*QMessageBox msg;
    msg.setText("Vous venez de lancer une partie solo.");
    msg.exec();*/

    LaunchSoloGame* formsologame = new LaunchSoloGame(this);
    formsologame->show();
    ui->statusBar->showMessage("Lancez une nouvelle partie solo.", 15000);
}

void MainWindow::UtilisateurConnecte()
{
    currentProfile* user  = currentProfile::getInstance();
    ui->statusBar->showMessage("Connecté - Bienvenue sur BOMBERMAN " + user->getPseudo() + ".", 15000);
}

void MainWindow::BeginPartyMulti()
{

    createpartymultigamer* CreatePartyMultiGamer;
    CreatePartyMultiGamer = new createpartymultigamer(this);
    CreatePartyMultiGamer->exec();

    //Test du module chat
    //Ajout du widgetChat

    QList<QString> *listJoueur = new QList<QString>();
    listJoueur->insert(0,"toto");
    widgetChat *Chat = new widgetChat(this,listJoueur);
    Chat->setGeometry(10,40,590,500);
    Chat->show();

    ui->statusBar->showMessage("Vous avez lancé la partie multijoueur.", 15000);
}

void MainWindow::LoadPartySolo()
{
    // Ouverture du dossier parent de la solution et filtre sur les fichiers de type texte pour sélection fichier à ouvrir
    QString fichier = QFileDialog::getOpenFileName(this, "Ouvrir un fichier", QString(), "Fichiers texte (*.txt)");

    // Message d'information provisoire indiquant le chemin d'accès au fichier à ouvrir
    // QMessageBox::information(this, "Fichier", "Vous avez ouvert le fichier :\n" + fichier);

    // on déclare la variable de type fichier, puis on l'ouvre en mode "lecture seule"
    QFile fichierACharger(fichier);

    if (fichierACharger.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream flux (&fichierACharger);

        QString ligne;

        // On parcours ensuite le fichier ligne par ligne en y appliquant un traitement : ici affichage d'une messageBox
        while(! flux.atEnd())
        {
            ligne = flux.readLine();

            QMessageBox msg;
            msg.setText(ligne);
            msg.exec();
        }
    }
}

void MainWindow::LoadPartyMulti()
{
    /*QMessageBox msg;
    msg.setText("Vous venez de charger une partie multi.");
    msg.exec();
    ui->statusBar->showMessage("Vous avez chargé une partie multijoueur.", 15000);*/

    JoinParty* JoinPartyMulti;
    JoinPartyMulti = new JoinParty(this);
//JoinPartyMulti->setGeometry(50,100,200,190);
    JoinPartyMulti->show();
}

void MainWindow::SavePartySolo()
{
    // On ouvre une boite de dialogue permettant la sauvegarde d'un fichier
    QString path = QFileDialog::getSaveFileName(this, "Enregistrer un fichier", QString("*.txt"), "Fichiers texte (*.txt);; Tous les fichiers (*.*)");

    // On crée le fichier ou écrase un existant
    QFile file(path);

    if (file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QTextStream out(&file);
        out << "J'ai sauvegardé le fichier " + path;

        file.close();

        ui->statusBar->showMessage("Partie sauvegardée : " + path, 15000);
    }
}

void MainWindow::Quit()
{
    if (QMessageBox::Yes == QMessageBox(QMessageBox::Warning, "Confirmation de sortie.", "Êtes-vous sûr de vouloir quitter BomberMan ?", QMessageBox::Yes|QMessageBox::No).exec())
    {
        exit(true);
    }
}

void MainWindow::GameControls()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 2);
    paramForm->show();
}

void MainWindow::DisplaySetting()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 1);
    paramForm->show();
}

void MainWindow::AudioSetting()
{
    ParamWindows* paramForm;
    paramForm = new ParamWindows(this, 0);
    paramForm->show();
}

void MainWindow::Help()
{

    help* helpWindow = new help(this);

    // helpWindow->show(); // Roman : 30/05/2014 : Mis en commentaire car s'ouvre déjà deans la classe help

    ui->statusBar->showMessage("Vous venez de fermer la fenêtre d'Aide.", 15000);

 }

void MainWindow::Credits()
{
    /*QMessageBox msg;
    msg.setText("Vous venez d'ouvrir les configurations audio.");
    msg.exec();*/

    QMessageBox::about(this, tr("BomberMAN"),
                 tr("The BomberMAN  is a strategic, maze-based video game franchise originally developed by Hudson Soft. The original game was published in 1983 and new games have been published at irregular intervals ever since.                Several titles in the 2000s were published by fellow Japanese game company Konami, who gained full control of the franchise when they purchased and absorbed Hudson in 2012. Today, Bomberman has featured in over 70 different games on numerous platforms (including all Nintendo platforms save for the 3DS and Wii U), as well as several anime and manga.His franchise is one of the most commercially successful of all time.
Realised by the Dream-Team :

Petra Kratochvilova

Thibaud Cutullic

Yoann Solacroup

Yann Damon

Gregoire Quincy

Roman Logvinov

Damien Moro
"));
}

void MainWindow::Statistics()
{
    windowstatistics* Stats;
    Stats = new windowstatistics(this);
    Stats->setGeometry(50,100,490,190);
    Stats->exec();
    ui->statusBar->showMessage("Vous avez consulté les statistics.", 15000);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event && event->key() == Qt::Key_F1) {
        Help();// Ouvre la fenêtre d'aide
 }
}

//Cela fonction mais lance la fenetre 3 fois
/*bool MainWindow::event(QEvent *event)//Test lancement fenetre Aide en appuant la touche "F1"
{
    QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
    if(kevent && kevent ->key() == Qt::Key_F1)
        Help();
    return true;

}
*/

<|endoftext|>


<commit_before>// Time:  O(|V|+|E|) = O(26 + 26^2) = O(1)
// Space: O(|E|) = O(26^2) = O(1)

class Solution {
public:
    string alienOrder(vector<string>& words) {
        // Find ancestors of each node by DFS.
        unordered_set<char> nodes;
        unordered_map<char, vector<char>> ancestors;
        for (int i = 0; i < words.size(); ++i) {
            for (char c : words[i]) {
                nodes.emplace(c);
            }
            if (i > 0) {
                findEdges(words[i - 1], words[i], &ancestors);
            }
        }

        // Output topological order by DFS.
        string result;
        unordered_map<char, char> visited;
        for (auto& node : nodes) {
            if (topSortDFS(node, node, &ancestors, &visited, &result)) {
                return "";
            }
        }

        return result;
    }

private:
    // Construct the graph.
    void findEdges(const string &word1, const string &word2,
                   unordered_map<char, vector<char>> *ancestors) {
        int len = min(word1.length(), word2.length());
        for (int i = 0; i < len; ++i) {
            if (word1[i] != word2[i]) {
                (*ancestors)[word2[i]].emplace_back(word1[i]);
                break;
            }
        }
    }

    // Topological sort, return whether there is a cycle.
    bool topSortDFS(const char& root,
                    const char& node,
                    unordered_map<char, vector<char>> *ancestors,
                    unordered_map<char, char> *visited,
                    string *result) {
        if (visited->emplace(make_pair(node, root)).second) {
            for (auto& ancestor: (*ancestors)[node]) {
                if (topSortDFS(root, ancestor, ancestors, visited, result)) {
                    return true;
                }
            }
            result->push_back(node);
        } else if ((*visited)[node] == root) {
            // Visited from the same root in the DFS path.
            // So it is cyclic.
            return true;
        }
        return false;
    }
};

// Adjacency matrix method.
class Solution2 {
public:
    string alienOrder(vector<string>& words) {
        string result;
        vector<vector<bool>> graph(26, vector<bool>(26));
        findDependency(words, &graph);
        findOrder(&graph, &result);
        return result;
    }

private:
    void findEdges(const string &word1, const string &word2, vector<vector<bool>> *graph) {
        int len = min(word1.length(), word2.length());
        for (int i = 0; i < len; ++i) {
            if (word1[i] != word2[i]) {
                (*graph)[word1[i] - 'a'][word2[i] - 'a'] = true;
                break;
            }
        }
    }

    // Construct the graph.
    void findDependency(const vector<string>& words, vector<vector<bool>> *graph) {
        for (const auto& c : words[0]) {
            (*graph)[c - 'a'][c - 'a'] = true;
        }
        for (int i = 1; i < words.size(); ++i) {
            for (const auto& c : words[i]) {
                (*graph)[c - 'a'] [c - 'a'] = true;
            }
            findEdges(words[i - 1], words[i], graph);
        }
    }

    // Topological sort, return whether there is a cycle.
    bool topSortDFS(string *result, vector<bool> *visited,
                    vector<vector<bool>> *graph, const int root) {
        if ((*visited)[root]) {
            result->clear();
            return true;
        }
        (*visited)[root] = true;
        for (int i = 0; i < 26; ++i) {
            if (i != root && (*graph)[root][i]) {
                if (topSortDFS(result, visited, graph, i)) {
                    return true;
                }
            }
        }
        (*graph)[root][root] = false;
        result->push_back(root + 'a');
        return false;
    }

    void findOrder(vector<vector<bool>> *graph, string *result) {
        for (int i = 0; i < 26; ++i) {
            // Find a root node.
            bool root_node = (*graph)[i][i];
            if ((*graph)[i][i]) {
                for (int j = 0; j < 26; ++j) {
                    if (j != i && (*graph)[j][i]) {
                        root_node = false;
                        break;
                    }
                }
            }
            if (root_node) {
                string reversed_order = "";
                vector<bool> visited(26, false);
                if (topSortDFS(&reversed_order, &visited, graph, i)) {
                    result->clear();
                    return;
                } else {
                    result->append(reversed_order);
                }
            }
        }

        // If there is any unvisited node, return "".
        for (int i = 0; i < 26; ++i) {
            if ((*graph)[i][i]) {
                result->clear();
                return;
            }
        }
        // The order should be reversed.
        reverse(result->begin(), result->end());
    }
};
<commit_msg>Update alien-dictionary.cpp<commit_after>// Time:  O(|V|+|E|) = O(26 + 26^2) = O(1)
// Space: O(|E|) = O(26^2) = O(1)

class Solution {
public:
    string alienOrder(vector<string>& words) {
        // Find ancestors of each node by DFS.
        unordered_set<char> nodes;
        unordered_map<char, vector<char>> ancestors;
        for (int i = 0; i < words.size(); ++i) {
            for (char c : words[i]) {
                nodes.emplace(c);
            }
            if (i > 0) {
                findEdges(words[i - 1], words[i], &ancestors);
            }
        }

        // Output topological order by DFS.
        string result;
        unordered_map<char, char> visited;
        for (const auto& node : nodes) {
            if (topSortDFS(node, node, &ancestors, &visited, &result)) {
                return "";
            }
        }

        return result;
    }

private:
    // Construct the graph.
    void findEdges(const string &word1, const string &word2,
                   unordered_map<char, vector<char>> *ancestors) {
        int len = min(word1.length(), word2.length());
        for (int i = 0; i < len; ++i) {
            if (word1[i] != word2[i]) {
                (*ancestors)[word2[i]].emplace_back(word1[i]);
                break;
            }
        }
    }

    // Topological sort, return whether there is a cycle.
    bool topSortDFS(const char& root,
                    const char& node,
                    unordered_map<char, vector<char>> *ancestors,
                    unordered_map<char, char> *visited,
                    string *result) {
        if (visited->emplace(make_pair(node, root)).second) {
            for (auto& ancestor: (*ancestors)[node]) {
                if (topSortDFS(root, ancestor, ancestors, visited, result)) {
                    return true;
                }
            }
            result->push_back(node);
        } else if ((*visited)[node] == root) {
            // Visited from the same root in the DFS path.
            // So it is cyclic.
            return true;
        }
        return false;
    }
};

// Adjacency matrix method.
class Solution2 {
public:
    string alienOrder(vector<string>& words) {
        string result;
        vector<vector<bool>> graph(26, vector<bool>(26));
        findDependency(words, &graph);
        findOrder(&graph, &result);
        return result;
    }

private:
    void findEdges(const string &word1, const string &word2, vector<vector<bool>> *graph) {
        int len = min(word1.length(), word2.length());
        for (int i = 0; i < len; ++i) {
            if (word1[i] != word2[i]) {
                (*graph)[word1[i] - 'a'][word2[i] - 'a'] = true;
                break;
            }
        }
    }

    // Construct the graph.
    void findDependency(const vector<string>& words, vector<vector<bool>> *graph) {
        for (const auto& c : words[0]) {
            (*graph)[c - 'a'][c - 'a'] = true;
        }
        for (int i = 1; i < words.size(); ++i) {
            for (const auto& c : words[i]) {
                (*graph)[c - 'a'] [c - 'a'] = true;
            }
            findEdges(words[i - 1], words[i], graph);
        }
    }

    // Topological sort, return whether there is a cycle.
    bool topSortDFS(string *result, vector<bool> *visited,
                    vector<vector<bool>> *graph, const int root) {
        if ((*visited)[root]) {
            result->clear();
            return true;
        }
        (*visited)[root] = true;
        for (int i = 0; i < 26; ++i) {
            if (i != root && (*graph)[root][i]) {
                if (topSortDFS(result, visited, graph, i)) {
                    return true;
                }
            }
        }
        (*graph)[root][root] = false;
        result->push_back(root + 'a');
        return false;
    }

    void findOrder(vector<vector<bool>> *graph, string *result) {
        for (int i = 0; i < 26; ++i) {
            // Find a root node.
            bool root_node = (*graph)[i][i];
            if ((*graph)[i][i]) {
                for (int j = 0; j < 26; ++j) {
                    if (j != i && (*graph)[j][i]) {
                        root_node = false;
                        break;
                    }
                }
            }
            if (root_node) {
                string reversed_order = "";
                vector<bool> visited(26, false);
                if (topSortDFS(&reversed_order, &visited, graph, i)) {
                    result->clear();
                    return;
                } else {
                    result->append(reversed_order);
                }
            }
        }

        // If there is any unvisited node, return "".
        for (int i = 0; i < 26; ++i) {
            if ((*graph)[i][i]) {
                result->clear();
                return;
            }
        }
        // The order should be reversed.
        reverse(result->begin(), result->end());
    }
};
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int calculate(string s) {
        stack<int> operands;
        stack<char> operators;
        string operand;
        for (int i = s.length() - 1; i >= 0; --i) {
            if (isdigit(s[i])) {
                operand.push_back(s[i]);
                if (i == 0 || !isdigit(s[i - 1])) {
                    reverse(operand.begin(), operand.end());
                    operands.emplace(stoi(operand));
                    operand.clear();
                }
            } else if (s[i] == ')' || s[i] == '+' || s[i] == '-') {
                operators.emplace(s[i]);
            } else if (s[i] == '(') {
                while (operators.top() != ')') {
                    compute(operands, operators);
                }
                operators.pop();
            }
        }
        while (!operators.empty()) {
            compute(operands, operators);
        }
        return operands.top();
    }

    void compute(stack<int>& operands, stack<char>& operators) {
        const int left = operands.top();
        operands.pop();
        const int right = operands.top();
        operands.pop();
        const char op = operators.top();
        operators.pop();
        if (op == '+') {
            operands.push(left + right);
        } else if (op == '-') {
            operands.push(left - right);
        }
    }
};
<commit_msg>Update basic-calculator.cpp<commit_after>// Time:  O(n)
// Space: O(n)

class Solution {
public:
    int calculate(string s) {
        stack<int> operands;
        stack<char> operators;
        string operand;
        for (int i = s.length() - 1; i >= 0; --i) {
            if (isdigit(s[i])) {
                operand.push_back(s[i]);
                if (i == 0 || !isdigit(s[i - 1])) {
                    reverse(operand.begin(), operand.end());
                    operands.emplace(stoi(operand));
                    operand.clear();
                }
            } else if (s[i] == ')' || s[i] == '*' ||
                       s[i] == '/') {
                operators.emplace(s[i]);
            } else if (s[i] == '+' || s[i] == '-') {
                while (!operators.empty() && (operators.top() == '*' ||
                       operators.top() == '/')) {
                     compute(operands, operators);
                }
                operators.emplace(s[i]);
            } else if (s[i] == '(') {
                // operators at least one element, i.e. ')'.
                while (operators.top() != ')') {
                    compute(operands, operators);
                }
                operators.pop();
            }
        }
        while (!operators.empty()) {
            compute(operands, operators);
        }
        return operands.top();
    }

    void compute(stack<int>& operands, stack<char>& operators) {
        const int left = operands.top();
        operands.pop();
        const int right = operands.top();
        operands.pop();
        const char op = operators.top();
        operators.pop();

        if (op == '+') {
            operands.push(left + right);
        } else if (op == '-') {
            operands.push(left - right);
        } else if (op == '*') {
            operands.push(left * right);
        } else if (op == '/') {
            operands.push(left / right);
        }
    }
};

// Time:  O(n)
// Space: O(n)
class Solution2 {
public:
    int calculate(string s) {
        stack<int> operands;
        stack<char> operators;
        string operand;
        for (int i = s.length() - 1; i >= 0; --i) {
            if (isdigit(s[i])) {
                operand.push_back(s[i]);
                if (i == 0 || !isdigit(s[i - 1])) {
                    reverse(operand.begin(), operand.end());
                    operands.emplace(stoi(operand));
                    operand.clear();
                }
            } else if (s[i] == ')' || s[i] == '+' || s[i] == '-') {
                operators.emplace(s[i]);
            } else if (s[i] == '(') {
                while (operators.top() != ')') {
                    compute(operands, operators);
                }
                operators.pop();
            }
        }
        while (!operators.empty()) {
            compute(operands, operators);
        }
        return operands.top();
    }

    void compute(stack<int>& operands, stack<char>& operators) {
        const int left = operands.top();
        operands.pop();
        const int right = operands.top();
        operands.pop();
        const char op = operators.top();
        operators.pop();
        if (op == '+') {
            operands.push(left + right);
        } else if (op == '-') {
            operands.push(left - right);
        }
    }
};
<|endoftext|>