<commit_before>//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// This test is intended to create a situation in which multiple events
// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen
// from multiple threads. The test expects the debugger to set a breakpoint on
// the main thread (before any worker threads are spawned) and modify variables
// which control the number of therads that are spawned for each action.

#include <atomic>
#include <vector>
using namespace std;

#include <pthread.h>

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

// Note that although hogging the CPU while waiting for a variable to change
// would be terrible in production code, it's great for testing since it
// avoids a lot of messy context switching to get multiple threads synchronized.
#define do_nothing()

#define pseudo_barrier_wait(bar) \
    --bar;                       \
    while (bar > 0)              \
        do_nothing();

#define pseudo_barrier_init(bar, count) (bar = count)

typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
typedef std::vector<pthread_t> thread_vector;

std::atomic_int g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
std::atomic_int g_watchme;

struct action_args {
  int delay;
};

// Perform any extra actions required by thread 'input' arg
void do_action_args(void *input) {
    if (input) {
      action_args *args = static_cast<action_args*>(input);
      sleep(args->delay);
    }
}

void *
breakpoint_func (void *input)
{
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Do something
    g_breakpoint++;       // Set breakpoint here
    return 0;
}

void *
signal_func (void *input) {
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Send a user-defined signal to the current process
    //kill(getpid(), SIGUSR1);
    // Send a user-defined signal to the current thread
    pthread_kill(pthread_self(), SIGUSR1);

    return 0;
}

void *
watchpoint_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    g_watchme += 1;     // watchpoint triggers here
    return 0;
}

void *
crash_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    int *a = 0;
    *a = 5; // crash happens here
    return 0;
}

void sigusr1_handler(int sig) {
    if (sig == SIGUSR1)
        g_sigusr1_count += 1; // Break here in signal handler
}

/// Register a simple function for to handle signal
void register_signal_handler(int signal, void (*handler)(int))
{
    sigset_t empty_sigset;
    sigemptyset(&empty_sigset);

    struct sigaction action;
    action.sa_sigaction = 0;
    action.sa_mask = empty_sigset;
    action.sa_flags = 0;
    action.sa_handler = handler;
    sigaction(SIGUSR1, &action, 0);
}

void start_threads(thread_vector& threads,
                   action_counts& actions,
                   void* args = 0) {
    action_counts::iterator b = actions.begin(), e = actions.end();
    for(action_counts::iterator i = b; i != e; ++i) {
        for(unsigned count = 0; count < i->first; ++count) {
            pthread_t t;
            pthread_create(&t, 0, i->second, args);
            threads.push_back(t);
        }
    }
}

int main ()
{
    g_watchme = 0;

    // Actions are triggered immediately after the thread is spawned
    unsigned num_breakpoint_threads = 1;
    unsigned num_watchpoint_threads = 0;
    unsigned num_signal_threads = 1;
    unsigned num_crash_threads = 0;

    // Actions below are triggered after a 1-second delay
    unsigned num_delay_breakpoint_threads = 0;
    unsigned num_delay_watchpoint_threads = 0;
    unsigned num_delay_signal_threads = 0;
    unsigned num_delay_crash_threads = 0;

    register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads

    unsigned total_threads = num_breakpoint_threads \
                             + num_watchpoint_threads \
                             + num_signal_threads \
                             + num_crash_threads \
                             + num_delay_breakpoint_threads \
                             + num_delay_watchpoint_threads \
                             + num_delay_signal_threads \
                             + num_delay_crash_threads;

    // Don't let either thread do anything until they're both ready.
    pseudo_barrier_init(g_barrier, total_threads);

    action_counts actions;
    actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
    actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
    actions.push_back(std::make_pair(num_signal_threads, signal_func));
    actions.push_back(std::make_pair(num_crash_threads, crash_func));

    action_counts delay_actions;
    actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
    actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
    actions.push_back(std::make_pair(num_delay_signal_threads, signal_func));
    actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));

    // Create threads that handle instant actions
    thread_vector threads;
    start_threads(threads, actions);

    // Create threads that handle delayed actions
    action_args delay_arg;
    delay_arg.delay = 1;
    start_threads(threads, delay_actions, &delay_arg);

    // Join all threads
    typedef std::vector<pthread_t>::iterator thread_iterator;
    for(thread_iterator t = threads.begin(); t != threads.end(); ++t)
        pthread_join(*t, 0);

    return 0; // Break here and verify one thread is active.
}
<commit_msg>Fix TestConcurrentEvents to behave nicely with GCC 4.8 - newer gcc generates additional debuginfo for function exit (stack object desctruction) which was causing tests to fail - work-around consists of not declaring any stack objects in main()<commit_after>//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// This test is intended to create a situation in which multiple events
// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen
// from multiple threads. The test expects the debugger to set a breakpoint on
// the main thread (before any worker threads are spawned) and modify variables
// which control the number of therads that are spawned for each action.

#include <atomic>
#include <vector>
using namespace std;

#include <pthread.h>

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

// Note that although hogging the CPU while waiting for a variable to change
// would be terrible in production code, it's great for testing since it
// avoids a lot of messy context switching to get multiple threads synchronized.
#define do_nothing()

#define pseudo_barrier_wait(bar) \
    --bar;                       \
    while (bar > 0)              \
        do_nothing();

#define pseudo_barrier_init(bar, count) (bar = count)

typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
typedef std::vector<pthread_t> thread_vector;

std::atomic_int g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
std::atomic_int g_watchme;

struct action_args {
  int delay;
};

// Perform any extra actions required by thread 'input' arg
void do_action_args(void *input) {
    if (input) {
      action_args *args = static_cast<action_args*>(input);
      sleep(args->delay);
    }
}

void *
breakpoint_func (void *input)
{
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Do something
    g_breakpoint++;       // Set breakpoint here
    return 0;
}

void *
signal_func (void *input) {
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Send a user-defined signal to the current process
    //kill(getpid(), SIGUSR1);
    // Send a user-defined signal to the current thread
    pthread_kill(pthread_self(), SIGUSR1);

    return 0;
}

void *
watchpoint_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    g_watchme += 1;     // watchpoint triggers here
    return 0;
}

void *
crash_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    int *a = 0;
    *a = 5; // crash happens here
    return 0;
}

void sigusr1_handler(int sig) {
    if (sig == SIGUSR1)
        g_sigusr1_count += 1; // Break here in signal handler
}

/// Register a simple function for to handle signal
void register_signal_handler(int signal, void (*handler)(int))
{
    sigset_t empty_sigset;
    sigemptyset(&empty_sigset);

    struct sigaction action;
    action.sa_sigaction = 0;
    action.sa_mask = empty_sigset;
    action.sa_flags = 0;
    action.sa_handler = handler;
    sigaction(SIGUSR1, &action, 0);
}

void start_threads(thread_vector& threads,
                   action_counts& actions,
                   void* args = 0) {
    action_counts::iterator b = actions.begin(), e = actions.end();
    for(action_counts::iterator i = b; i != e; ++i) {
        for(unsigned count = 0; count < i->first; ++count) {
            pthread_t t;
            pthread_create(&t, 0, i->second, args);
            threads.push_back(t);
        }
    }
}

int dotest()
{
    g_watchme = 0;

    // Actions are triggered immediately after the thread is spawned
    unsigned num_breakpoint_threads = 1;
    unsigned num_watchpoint_threads = 0;
    unsigned num_signal_threads = 1;
    unsigned num_crash_threads = 0;

    // Actions below are triggered after a 1-second delay
    unsigned num_delay_breakpoint_threads = 0;
    unsigned num_delay_watchpoint_threads = 0;
    unsigned num_delay_signal_threads = 0;
    unsigned num_delay_crash_threads = 0;

    register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads

    unsigned total_threads = num_breakpoint_threads \
                             + num_watchpoint_threads \
                             + num_signal_threads \
                             + num_crash_threads \
                             + num_delay_breakpoint_threads \
                             + num_delay_watchpoint_threads \
                             + num_delay_signal_threads \
                             + num_delay_crash_threads;

    // Don't let either thread do anything until they're both ready.
    pseudo_barrier_init(g_barrier, total_threads);

    action_counts actions;
    actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
    actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
    actions.push_back(std::make_pair(num_signal_threads, signal_func));
    actions.push_back(std::make_pair(num_crash_threads, crash_func));

    action_counts delay_actions;
    actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
    actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
    actions.push_back(std::make_pair(num_delay_signal_threads, signal_func));
    actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));

    // Create threads that handle instant actions
    thread_vector threads;
    start_threads(threads, actions);

    // Create threads that handle delayed actions
    action_args delay_arg;
    delay_arg.delay = 1;
    start_threads(threads, delay_actions, &delay_arg);

    // Join all threads
    typedef std::vector<pthread_t>::iterator thread_iterator;
    for(thread_iterator t = threads.begin(); t != threads.end(); ++t)
        pthread_join(*t, 0);

    return 0;
}

int main ()
{
    dotest();
    return 0; // Break here and verify one thread is active.
}

<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include <Corrade/TestSuite/Tester.h>

#include "Magnum/Math/Algorithms/Svd.h"

namespace Magnum { namespace Math { namespace Algorithms { namespace Test {

struct SvdTest: Corrade::TestSuite::Tester {
    explicit SvdTest();

    void testDouble();
    void testFloat();
};

typedef RectangularMatrix<5, 8, Double> Matrix5x8d;
typedef Matrix<8, Double> Matrix8d;
typedef Matrix<5, Double> Matrix5d;
typedef Vector<8, Double> Vector8d;
typedef Vector<5, Double> Vector5d;

typedef RectangularMatrix<5, 8, Float> Matrix5x8f;
typedef Matrix<8, Float> Matrix8f;
typedef Matrix<5, Float> Matrix5f;
typedef Vector<8, Float> Vector8f;
typedef Vector<5, Float> Vector5f;

constexpr static Matrix5x8d ad(
    Vector8d(22.0, 14.0,  -1.0, -3.0,  9.0,  9.0,  2.0,  4.0),
    Vector8d(10.0,  7.0,  13.0, -2.0,  8.0,  1.0, -6.0,  5.0),
    Vector8d( 2.0, 10.0,  -1.0, 13.0,  1.0, -7.0,  6.0,  0.0),
    Vector8d( 3.0,  0.0, -11.0, -2.0, -2.0,  5.0,  5.0, -2.0),
    Vector8d( 7.0,  8.0,   3.0,  4.0,  4.0, -1.0,  1.0,  2.0)
);
static const Vector5d expectedd(std::sqrt(1248.0), 0.0, 20.0, std::sqrt(384.0), 0.0);

constexpr static Matrix5x8f af(
    Vector8f(22.0f, 14.0f,  -1.0f, -3.0f,  9.0f,  9.0f,  2.0f,  4.0f),
    Vector8f(10.0f,  7.0f,  13.0f, -2.0f,  8.0f,  1.0f, -6.0f,  5.0f),
    Vector8f( 2.0f, 10.0f,  -1.0f, 13.0f,  1.0f, -7.0f,  6.0f,  0.0f),
    Vector8f( 3.0f,  0.0f, -11.0f, -2.0f, -2.0f,  5.0f,  5.0f, -2.0f),
    Vector8f( 7.0f,  8.0f,   3.0f,  4.0f,  4.0f, -1.0f,  1.0f,  2.0f)
);
static const Vector5f expectedf(std::sqrt(1248.0f), 0.0f, 20.0f, std::sqrt(384.0f), 0.0f);

SvdTest::SvdTest() {
    addTests({&SvdTest::testDouble,
              &SvdTest::testFloat});
}

void SvdTest::testDouble() {
    Matrix5x8d u;
    Vector5d w;
    Matrix5d v;
    std::tie(u, w, v) = Algorithms::svd(ad);

    /* Test composition */
    Matrix8d u2(u[0], u[1], u[2], u[3], u[4], Vector8d(), Vector8d(), Vector8d());
    Matrix5x8d w2 = Matrix5x8d::fromDiagonal(w);
    CORRADE_COMPARE(u2*w2*v.transposed(), ad);

    /* Test that V is unitary */
    CORRADE_COMPARE(v*v.transposed(), Matrix5d{IdentityInit});
    CORRADE_COMPARE(v.transposed()*v, Matrix5d{IdentityInit});

    /* Test W */
    CORRADE_COMPARE(w, expectedd);
}

void SvdTest::testFloat() {
    Matrix5x8f u;
    Vector5f w;
    Matrix5f v;
    std::tie(u, w, v) = Algorithms::svd(af);

    /* Test composition (single precision is not enough, test for similarity) */
    Matrix8f u2(u[0], u[1], u[2], u[3], u[4], Vector8f(), Vector8f(), Vector8f());
    Matrix5x8f w2 = Matrix5x8f::fromDiagonal(w);
    CORRADE_VERIFY(Math::abs((u2*w2*v.transposed()-af).toVector()).max() < 1.0e-5f);

    /* Test that V is unitary */
    CORRADE_COMPARE(v*v.transposed(), Matrix5f{IdentityInit});
    CORRADE_COMPARE(v.transposed()*v, Matrix5f{IdentityInit});

    /* Test W (single precision is not enough, test for similarity) */
    CORRADE_VERIFY(Math::abs(w-expectedf).max() < 1.0e-5f);
}

}}}}

CORRADE_TEST_MAIN(Magnum::Math::Algorithms::Test::SvdTest)
<commit_msg>Math: simplify the SVD test code by making it templated.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include <Corrade/TestSuite/Tester.h>

#include "Magnum/Math/Algorithms/Svd.h"

namespace Magnum { namespace Math { namespace Algorithms { namespace Test {

struct SvdTest: Corrade::TestSuite::Tester {
    explicit SvdTest();

    template<class T> void test();
};

template<class T> using Matrix5x8 = RectangularMatrix<5, 8, T>;
template<class T> using Matrix8 = Matrix<8, T>;
template<class T> using Matrix5 = Matrix<5, T>;
template<class T> using Vector8 = Vector<8, T>;
template<class T> using Vector5 = Vector<5, T>;

SvdTest::SvdTest() {
    addTests<SvdTest>({&SvdTest::test<Float>,
                       &SvdTest::test<Double>});
}

template<class T> void SvdTest::test() {
    setTestCaseName(std::is_same<T, Double>::value ? "test<Double>" : "test<Float>");

    constexpr const Matrix5x8<T> a{
        Vector8<T>{T{22}, T{14}, T{ -1}, T{-3}, T{ 9}, T{ 9}, T{ 2}, T{ 4}},
        Vector8<T>{T{10}, T{ 7}, T{ 13}, T{-2}, T{ 8}, T{ 1}, T{-6}, T{ 5}},
        Vector8<T>{T{ 2}, T{10}, T{ -1}, T{13}, T{ 1}, T{-7}, T{ 6}, T{ 0}},
        Vector8<T>{T{ 3}, T{ 0}, T{-11}, T{-2}, T{-2}, T{ 5}, T{ 5}, T{-2}},
        Vector8<T>{T{ 7}, T{ 8}, T{  3}, T{ 4}, T{ 4}, T{-1}, T{ 1}, T{ 2}}};
    const Vector5<T> expected(std::sqrt(T{1248}), T{0}, T{20}, std::sqrt(T{384}), T{0});

    Matrix5x8<T> u{NoInit};
    Vector5<T> w{NoInit};
    Matrix5<T> v{NoInit};
    std::tie(u, w, v) = Algorithms::svd(a);

    /* Test composition */
    Matrix8<T> u2{u[0], u[1], u[2], u[3], u[4], Vector8<T>{}, Vector8<T>{}, Vector8<T>{}};
    Matrix5x8<T> w2 = Matrix5x8<T>::fromDiagonal(w);
    CORRADE_COMPARE(u2*w2*v.transposed(), a);

    /* Test that V is unitary */
    CORRADE_COMPARE(v*v.transposed(), Matrix5<T>{IdentityInit});
    CORRADE_COMPARE(v.transposed()*v, Matrix5<T>{IdentityInit});

    /* Test W */
    CORRADE_COMPARE(w, expected);
}

}}}}

CORRADE_TEST_MAIN(Magnum::Math::Algorithms::Test::SvdTest)
<|endoftext|>


<commit_before>#ifndef __MODULE__MESH_HPP__
#define __MODULE__MESH_HPP__

#include "Book.hpp"
#include "Vector3.hpp"
#include <string>
#include <cstdlib>
#include <vector>

namespace Module {

class Vector3;
class GraphicsInterface;
class GameObject;

// Currently, Module does not allow for vertex indexing. This is because
// vertex indexing means each vertex can only have one normal for all uses of that vertex (e.g. smooth faces).
// You can have vertex normals with indexing, but that involves unpacking the vertices and
// essentially not using indexing, meaning that the index system's overhead still exists
// without its functionality being used.
class Mesh {
private:
	std::vector<GameObject*> instances; // a vector of pointers to GameObjects that use this mesh
	Book<Mesh>::size_type selfIndex;	// this mesh's index in the book of all meshes

	Book<float>* vertexBook; // the book containing the vertices of this mesh
	Book<float>* normalBook; // the book containing the normals of this mesh
	Book<float>::size_type  vertexIndex; // the index of this mesh's first vertex in the vertexBook
	Book<float>::size_type  normalIndex; // the index of this mesh's first normal in the normalBook
	Book<float>::size_type  numVertices; // the number of vertices/normals that this mesh has
	float scale; // scalar to multiply all vertices by for rendering, etc.
	std::string name;
	Mesh() :
		selfIndex(0), vertexBook(0), normalBook(0), vertexIndex(0), normalIndex(0), numVertices(0), scale(1.0f), name("") {}
	Mesh(Book<Mesh>::size_type index, Book<float>* vb, Book<float>* nb,
		 Book<int>::size_type vi, Book<int>::size_type ni,
		 unsigned int num, std::string meshName) :
			selfIndex(index), vertexBook(vb), normalBook(nb), vertexIndex(vi), normalIndex(ni),
			numVertices(num), scale(1.0f), name(meshName) {}
public:
	Book<Mesh>::size_type getIndex() const;
	Book<float>::size_type getNumVertices() const;
	Vector3 getVertex(unsigned int i) const;
	Vector3 getNormal(unsigned int i) const;
	float getScale() const;
	void setScale(float newScale);

	friend class GraphicsInterface;
	friend class Book<Mesh>;
};

inline Book<Mesh>::size_type Mesh::getIndex() const
{
	return selfIndex;
}

inline Book<int>::size_type Mesh::getNumVertices() const
{
	return numVertices;
}

inline float Mesh::getScale() const
{
	return scale;
}

inline void Mesh::setScale(float newScale)
{
	scale = newScale;
}

Vector3 Mesh::getVertex(unsigned int i) const
{
	return Vector3(	(*vertexBook)[vertexIndex + 3 * i],
					(*vertexBook)[vertexIndex + 3 * i + 1],
					(*vertexBook)[vertexIndex + 3 * i + 2]);
}

Vector3 Mesh::getNormal(unsigned int i) const
{
	return Vector3(	(*normalBook)[normalIndex + 3 * i],
					(*normalBook)[normalIndex + 3 * i + 1],
					(*normalBook)[normalIndex + 3 * i + 2]);
}

}

#endif<commit_msg>Fixed compilation issue (multiple definitions, added 'inline' specifier)<commit_after>#ifndef __MODULE__MESH_HPP__
#define __MODULE__MESH_HPP__

#include "Book.hpp"
#include "Vector3.hpp"
#include <string>
#include <cstdlib>
#include <vector>

namespace Module {

class Vector3;
class GraphicsInterface;
class GameObject;

// Currently, Module does not allow for vertex indexing. This is because
// vertex indexing means each vertex can only have one normal for all uses of that vertex (e.g. smooth faces).
// You can have vertex normals with indexing, but that involves unpacking the vertices and
// essentially not using indexing, meaning that the index system's overhead still exists
// without its functionality being used.
class Mesh {
private:
	std::vector<GameObject*> instances; // a vector of pointers to GameObjects that use this mesh
	Book<Mesh>::size_type selfIndex;	// this mesh's index in the book of all meshes

	Book<float>* vertexBook; // the book containing the vertices of this mesh
	Book<float>* normalBook; // the book containing the normals of this mesh
	Book<float>::size_type  vertexIndex; // the index of this mesh's first vertex in the vertexBook
	Book<float>::size_type  normalIndex; // the index of this mesh's first normal in the normalBook
	Book<float>::size_type  numVertices; // the number of vertices/normals that this mesh has
	float scale; // scalar to multiply all vertices by for rendering, etc.
	std::string name;
	Mesh() :
		selfIndex(0), vertexBook(0), normalBook(0), vertexIndex(0), normalIndex(0), numVertices(0), scale(1.0f), name("") {}
	Mesh(Book<Mesh>::size_type index, Book<float>* vb, Book<float>* nb,
		 Book<int>::size_type vi, Book<int>::size_type ni,
		 unsigned int num, std::string meshName) :
			selfIndex(index), vertexBook(vb), normalBook(nb), vertexIndex(vi), normalIndex(ni),
			numVertices(num), scale(1.0f), name(meshName) {}
public:
	Book<Mesh>::size_type getIndex() const;
	Book<float>::size_type getNumVertices() const;
	Vector3 getVertex(unsigned int i) const;
	Vector3 getNormal(unsigned int i) const;
	float getScale() const;
	void setScale(float newScale);

	friend class GraphicsInterface;
	friend class Book<Mesh>;
};

inline Book<Mesh>::size_type Mesh::getIndex() const
{
	return selfIndex;
}

inline Book<int>::size_type Mesh::getNumVertices() const
{
	return numVertices;
}

inline float Mesh::getScale() const
{
	return scale;
}

inline void Mesh::setScale(float newScale)
{
	scale = newScale;
}

inline Vector3 Mesh::getVertex(unsigned int i) const
{
	return Vector3(	(*vertexBook)[vertexIndex + 3 * i],
					(*vertexBook)[vertexIndex + 3 * i + 1],
					(*vertexBook)[vertexIndex + 3 * i + 2]);
}

inline Vector3 Mesh::getNormal(unsigned int i) const
{
	return Vector3(	(*normalBook)[normalIndex + 3 * i],
					(*normalBook)[normalIndex + 3 * i + 1],
					(*normalBook)[normalIndex + 3 * i + 2]);
}

}

#endif<|endoftext|>


<commit_before>#include <omp.h>
#include <unistd.h>
#include <cstdlib>
#include <iostream>

#include "bdmAdaptor.h"
#include "cell.h"

using bdm::Cell;
using bdm::Soa;
using bdm::Scalar;

void PrintUsage() {
  std::cout
      << "USAGE\n"
      << "  ./persistent_sim #cells_per_dim #distance |\n"
      << "\nDESCRIPTION\n"
      << "  Creates a three dimensional grid of cells of size "
         "(#cells_per_dim)^3,\n"
      << "  and moves them unidirectional for the purpose of demonstrating "
         "data persistency\n"
      << "  Feel free to crash the simulation and restart it to experience "
         "some fault tolerance\n"
      << "\nOPTIONS\n"
      << "  --help\n"
      << "    Explains usage of this binary and its command line options\n"
      << std::endl;
}

Cell<Soa> InitializeCells(size_t cells_per_dim) {
  const double space = 20;

  auto cells = Cell<>::NewEmptySoa();
  cells.reserve(cells_per_dim * cells_per_dim * cells_per_dim);
  for (size_t i = 0; i < cells_per_dim; i++) {
    for (size_t j = 0; j < cells_per_dim; j++) {
      for (size_t k = 0; k < cells_per_dim; k++) {
        Cell<Scalar> cell({i * space, j * space, k * space});
        cell.SetDiameter(30);
        cell.SetAdherence(0.4);
        cell.SetMass(1.0);
        cell.UpdateVolume();
        cells.push_back(cell);
      }
    }
  }
  return cells;
}

void Simulate(Cell<Soa>* cells, size_t number_of_time_steps) {
  srand(42);
  for (size_t time_step = 0; time_step < number_of_time_steps; time_step++) {
#pragma omp parallel for
    for (size_t i = 0; i < cells->size(); i++) {
      // The simulation operation is just a simple cell displacement and growth
      auto current_pos = (*cells)[i].GetPosition();
      double r =
          -1.0 +
          static_cast<double>(rand()) / (static_cast<double>(RAND_MAX / (2)));
      std::array<double, 3> new_pos{(current_pos[0] + r), current_pos[1] + r,
                                    current_pos[2] + r};

      (*cells)[i].SetPosition(new_pos);
    }
    // timestep of 0.1
    double time = 0.1 * time_step;

#ifdef USE_CATALYST
    bdm_adaptor::CoProcess(cells, time, time_step,
                           time_step == number_of_time_steps - 1);
#endif

    // Simulate the simulation overhead
    std::cout << "Simulating..." << std::endl;
    usleep(500000);
  }
}

int main(int args, char** argv) {
  if (args == 4) {
    size_t threads = 2;
    size_t cells_per_dim;
    size_t duration;

    std::istringstream(std::string(argv[1])) >> cells_per_dim;
    std::istringstream(std::string(argv[2])) >> duration;

#ifdef USE_CATALYST
    // initialize with a single script (for this demo)
    bdm_adaptor::Initialize(argv[3]);
#endif

    auto new_cells = InitializeCells(cells_per_dim);
    Cell<Soa>* cells = &new_cells;

    omp_set_num_threads(threads);
    Simulate(cells, duration);

#ifdef USE_CATALYST
    bdm_adaptor::Finalize();
#endif
  } else {
    PrintUsage();
  }
  return 0;
}
<commit_msg>Remove cell_displacement example<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include "kangaru.hpp"

using namespace std;
using namespace kgr;

struct MyContainer;

///////////////////////////////
//      Service Classes      //
///////////////////////////////
struct A {
	A(int n = 0) : n{n} {};

	// A needs nothing
	int n = 0;
};

struct B {
	// B needs A
	B(shared_ptr<A> a) : a{a} {}

	shared_ptr<A> a;
};

struct AC {
	virtual int getN() const = 0;
};

struct C : AC {
	// C needs A and B
	C(shared_ptr<A> a, shared_ptr<B> b) : a{a}, b{b} {}

	int getN() const override;

	shared_ptr<A> a;
	shared_ptr<B> b;
};

int C::getN() const
{
	return 21;
}

struct D {
	// D needs B and AC
	D(shared_ptr<B> b, shared_ptr<AC> c) : b{b}, c{c} {}

	shared_ptr<B> b;
	shared_ptr<AC> c;
};

struct E : C {
	// E needs MyContainer, A and B
	// We needs A and B because C needs them
	E(shared_ptr<MyContainer> container, shared_ptr<A> a, shared_ptr<B> b) :
		C {a, b}, container{container} {}

	int getN() const override;

	// weak_ptr because we don't want the MyContainer to hold a shared_ptr to himself
	weak_ptr<MyContainer> container;
};

int E::getN() const
{
	return 66;
}

struct MyContainer : Container {
	void init() override;
};

void MyContainer::init()
{
	instance(make_shared<A>(8));
	instance<C>();
	instance<E>();
}

///////////////////////////////
//     Service Meta Data     //
///////////////////////////////
namespace kgr {

template<> struct Service<A> : NoDependencies, Single {};

// B depends on A
template<> struct Service<B> : Dependency<A>, Single {};

// C depends on A and B
template<> struct Service<AC> : NoDependencies, Single {};

// C depends on A and B
template<> struct Service<C> : Dependency<A, B>, Overrides<AC> {};

// D depends on B and AC
// The AC class will be a C (see init for details)
template<> struct Service<D> : Dependency<B, AC> {};

// E depends on MyContainer, A and B
template<> struct Service<E> : Dependency<MyContainer, A, B>, Overrides<C> {};

}

///////////////////////////////
//        Usage Example      //
///////////////////////////////
int main(int argc, char** argv)
{
	auto container = make_container<MyContainer>();

	container->callback<D>([](std::shared_ptr<B> b, std::shared_ptr<AC> ac) {
		cout << "a D is built" << endl;
		return make_shared<D>(b, ac);
	});

	// let's get some services
	auto a = container->service<A>();
	auto b = container->service<B>();
	auto c = container->service<C>(); // I'm a E!
	auto ac = container->service<AC>(); // I'm a C!
	auto d1 = container->service<D>();
	auto d2 = container->service<D>();
	auto e = container->service<E>();

	cout << "a default value: " << a->n << endl;

	a->n = 9;
	b->a->n = 8;
	// 5 will be the last value.
	// Since A is single, we will see the value 5 across all classes
	e->a->n = 5;

	cout << "is same container: " << (e->container.lock() == container ? "true" : "false") << endl;
	cout << "is same D: " << (d1 == d2 ? "true" : "false") << endl;
	cout << "is same A: " << ((a == b->a) && (a == e->a) ? "true" : "false") << endl;
	cout << "a: " << a->n << endl;
	cout << "b: " << b->a->n << endl;
	cout << "c (it's a E): " << c->getN() << endl;
	cout << "ac (it's a C): " << ac->getN() << endl;
	cout << "d1 n: " << d1->b->a->n << endl;
	cout << "d2 c getN(): " << d2->c->getN() << endl;

	return 0;
}
<commit_msg>Remove 'shadow' warnings<commit_after>#include <iostream>
#include "kangaru.hpp"

using namespace std;
using namespace kgr;

struct MyContainer;

///////////////////////////////
//      Service Classes      //
///////////////////////////////
struct A {
	A() = default;
	A(int val) : n{val} {}

	// A needs nothing
	int n = 0;
};

struct B {
	// B needs A
	B(shared_ptr<A> a_ptr) : a{std::move(a_ptr)} {}

	shared_ptr<A> a;
};

struct AC {
	virtual int getN() const = 0;
};

struct C : AC {
	// C needs A and B
	C(shared_ptr<A> a_ptr, shared_ptr<B> b_ptr) : a{std::move(a_ptr)}, b{std::move(b_ptr)} {}

	int getN() const override;

	shared_ptr<A> a;
	shared_ptr<B> b;
};

int C::getN() const
{
	return 21;
}

struct D {
	// D needs B and AC
	D(shared_ptr<B> b_ptr, shared_ptr<AC> c_ptr) : b{std::move(b_ptr)}, c{std::move(c_ptr)} {}

	shared_ptr<B> b;
	shared_ptr<AC> c;
};

struct E : C {
	// E needs MyContainer, A and B
	// We needs A and B because C needs them
	E(shared_ptr<MyContainer> cont_ptr, shared_ptr<A> a_ptr, shared_ptr<B> b_ptr) :
		C {std::move(a_ptr), std::move(b_ptr)}, container{std::move(cont_ptr)} {}

	int getN() const override;

	// weak_ptr because we don't want the MyContainer to hold a shared_ptr to himself
	weak_ptr<MyContainer> container;
};

int E::getN() const
{
	return 66;
}

struct MyContainer : Container {
	void init() override;
};

void MyContainer::init()
{
	instance(make_shared<A>(8));
	instance<C>();
	instance<E>();
}

///////////////////////////////
//     Service Meta Data     //
///////////////////////////////
namespace kgr {

template<> struct Service<A> : NoDependencies, Single {};

// B depends on A
template<> struct Service<B> : Dependency<A>, Single {};

// C depends on A and B
template<> struct Service<AC> : NoDependencies, Single {};

// C depends on A and B
template<> struct Service<C> : Dependency<A, B>, Overrides<AC> {};

// D depends on B and AC
// The AC class will be a C (see init for details)
template<> struct Service<D> : Dependency<B, AC> {};

// E depends on MyContainer, A and B
template<> struct Service<E> : Dependency<MyContainer, A, B>, Overrides<C> {};

}

///////////////////////////////
//        Usage Example      //
///////////////////////////////
int main(int argc, char** argv)
{
	auto container = make_container<MyContainer>();

	container->callback<D>([](std::shared_ptr<B> b, std::shared_ptr<AC> ac) {
		cout << "a D is built" << endl;
		return make_shared<D>(b, ac);
	});

	// let's get some services
	auto a = container->service<A>();
	auto b = container->service<B>();
	auto c = container->service<C>(); // I'm a E!
	auto ac = container->service<AC>(); // I'm a C!
	auto d1 = container->service<D>();
	auto d2 = container->service<D>();
	auto e = container->service<E>();

	cout << "a default value: " << a->n << endl;

	a->n = 9;
	b->a->n = 8;
	// 5 will be the last value.
	// Since A is single, we will see the value 5 across all classes
	e->a->n = 5;

	cout << "is same container: " << (e->container.lock() == container ? "true" : "false") << endl;
	cout << "is same D: " << (d1 == d2 ? "true" : "false") << endl;
	cout << "is same A: " << ((a == b->a) && (a == e->a) ? "true" : "false") << endl;
	cout << "a: " << a->n << endl;
	cout << "b: " << b->a->n << endl;
	cout << "c (it's a E): " << c->getN() << endl;
	cout << "ac (it's a C): " << ac->getN() << endl;
	cout << "d1 n: " << d1->b->a->n << endl;
	cout << "d2 c getN(): " << d2->c->getN() << endl;

	return 0;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2012 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreViewport.h"

#include "OgreLogManager.h"
#include "OgreRenderTarget.h"
#include "OgreCamera.h"
#include "OgreMath.h"
#include "OgreRoot.h"
#include "OgreMaterialManager.h"
#include "OgreRenderSystem.h"
#include "OgreRenderWindow.h"

namespace Ogre {
    OrientationMode Viewport::mDefaultOrientationMode = OR_DEGREE_0;
    //---------------------------------------------------------------------
    Viewport::Viewport(Camera* cam, RenderTarget* target, Real left, Real top, Real width, Real height, int ZOrder)
        : mCamera(cam)
        , mTarget(target)
        , mRelLeft(left)
        , mRelTop(top)
        , mRelWidth(width)
        , mRelHeight(height)
        // Actual dimensions will update later
        , mZOrder(ZOrder)
        , mBackColour(ColourValue::Black)
		, mDepthClearValue(1)
        , mClearEveryFrame(true)
		, mClearBuffers(FBT_COLOUR | FBT_DEPTH)
        , mUpdated(false)
        , mShowOverlays(true)
        , mShowSkies(true)
		, mShowShadows(true)
		, mVisibilityMask(0xFFFFFFFF)
		, mRQSequence(0)
		, mMaterialSchemeName(MaterialManager::DEFAULT_SCHEME_NAME)
		, mIsAutoUpdated(true)
    {
#if OGRE_COMPILER != OGRE_COMPILER_GCCE && OGRE_PLATFORM != OGRE_PLATFORM_ANDROID
		LogManager::getSingleton().stream(LML_TRIVIAL)
			<< "Creating viewport on target '" << target->getName() << "'"
			<< ", rendering from camera '" << (cam != 0 ? cam->getName() : "NULL") << "'"
			<< ", relative dimensions "	<< std::ios::fixed << std::setprecision(2)
			<< "L: " << left << " T: " << top << " W: " << width << " H: " << height
			<< " ZOrder: " << ZOrder;
#endif

        // Set the default orientation mode
        mOrientationMode = mDefaultOrientationMode;

        // Set the default material scheme
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        mMaterialSchemeName = rs->_getDefaultViewportMaterialScheme();

        // Calculate actual dimensions
        _updateDimensions();

        // notify camera
        if(cam) cam->_notifyViewport(this);
    }
    //---------------------------------------------------------------------
    Viewport::~Viewport()
    {
		RenderSystem* rs = Root::getSingleton().getRenderSystem();
		if ((rs) && (rs->_getViewport() == this))
		{
			rs->_setViewport(NULL);
		}
    }
    //---------------------------------------------------------------------
    bool Viewport::_isUpdated(void) const
    {
        return mUpdated;
    }
    //---------------------------------------------------------------------
    void Viewport::_clearUpdatedFlag(void)
    {
        mUpdated = false;
    }
    //---------------------------------------------------------------------
    void Viewport::_updateDimensions(void)
    {
        Real height = (Real) mTarget->getHeight();
        Real width = (Real) mTarget->getWidth();

        mActLeft = (int) (mRelLeft * width);
        mActTop = (int) (mRelTop * height);
        mActWidth = (int) (mRelWidth * width);
        mActHeight = (int) (mRelHeight * height);

        // This will check if the cameras getAutoAspectRatio() property is set.
        // If it's true its aspect ratio is fit to the current viewport
        // If it's false the camera remains unchanged.
        // This allows cameras to be used to render to many viewports,
        // which can have their own dimensions and aspect ratios.

        if (mCamera)
        {
            if (mCamera->getAutoAspectRatio())
                mCamera->setAspectRatio((Real) mActWidth / (Real) mActHeight);

#if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
            mCamera->setOrientationMode(mOrientationMode);
#endif
        }

#if OGRE_COMPILER != OGRE_COMPILER_GCCE
		LogManager::getSingleton().stream(LML_TRIVIAL)
			<< "Viewport for camera '" << (mCamera != 0 ? mCamera->getName() : "NULL") << "'"
			<< ", actual dimensions "	<< std::ios::fixed << std::setprecision(2)
			<< "L: " << mActLeft << " T: " << mActTop << " W: " << mActWidth << " H: " << mActHeight;
#endif

		 mUpdated = true;

		for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
		{
			(*i)->viewportDimensionsChanged(this);
		}
	}
	//---------------------------------------------------------------------
	int Viewport::getZOrder(void) const
	{
		return mZOrder;
	}
	//---------------------------------------------------------------------
    RenderTarget* Viewport::getTarget(void) const
    {
        return mTarget;
    }
    //---------------------------------------------------------------------
    Camera* Viewport::getCamera(void) const
    {
        return mCamera;
    }
    //---------------------------------------------------------------------
    Real Viewport::getLeft(void) const
    {
        return mRelLeft;
    }
    //---------------------------------------------------------------------
    Real Viewport::getTop(void) const
    {
        return mRelTop;
    }
    //---------------------------------------------------------------------
    Real Viewport::getWidth(void) const
    {
        return mRelWidth;
    }
    //---------------------------------------------------------------------
    Real Viewport::getHeight(void) const
    {
        return mRelHeight;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualLeft(void) const
    {
        return mActLeft;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualTop(void) const
    {
        return mActTop;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualWidth(void) const
    {
        return mActWidth;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualHeight(void) const
    {
        return mActHeight;
    }
    //---------------------------------------------------------------------
    void Viewport::setDimensions(Real left, Real top, Real width, Real height)
    {
        mRelLeft = left;
        mRelTop = top;
        mRelWidth = width;
        mRelHeight = height;
        _updateDimensions();
    }
    //---------------------------------------------------------------------
    void Viewport::update(void)
    {
        if (mCamera)
        {
            // Tell Camera to render into me
            mCamera->_renderScene(this, mShowOverlays);
        }
    }
    //---------------------------------------------------------------------
    void Viewport::setOrientationMode(OrientationMode orientationMode, bool setDefault)
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Setting Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        mOrientationMode = orientationMode;

        if (setDefault)
        {
            setDefaultOrientationMode(orientationMode);
        }

        if (mCamera)
        {
            mCamera->setOrientationMode(mOrientationMode);
        }

	// Update the render system config
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        if(mOrientationMode == OR_LANDSCAPELEFT)
            rs->setConfigOption("Orientation", "Landscape Left");
        else if(mOrientationMode == OR_LANDSCAPERIGHT)
            rs->setConfigOption("Orientation", "Landscape Right");
        else if(mOrientationMode == OR_PORTRAIT)
            rs->setConfigOption("Orientation", "Portrait");
#endif
    }
    //---------------------------------------------------------------------
    OrientationMode Viewport::getOrientationMode() const
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Getting Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        return mOrientationMode;
    }
    //---------------------------------------------------------------------
    void Viewport::setDefaultOrientationMode(OrientationMode orientationMode)
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Setting default Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        mDefaultOrientationMode = orientationMode;
    }
    //---------------------------------------------------------------------
    OrientationMode Viewport::getDefaultOrientationMode()
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Getting default Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        return mDefaultOrientationMode;
    }
    //---------------------------------------------------------------------
    void Viewport::setBackgroundColour(const ColourValue& colour)
    {
        mBackColour = colour;
    }
    //---------------------------------------------------------------------
    const ColourValue& Viewport::getBackgroundColour(void) const
    {
        return mBackColour;
    }
    //---------------------------------------------------------------------
	void Viewport::setDepthClear( Real depth )
    {
        mDepthClearValue = depth;
    }
    //---------------------------------------------------------------------
    Real Viewport::getDepthClear(void) const
    {
        return mDepthClearValue;
    }
	//---------------------------------------------------------------------
    void Viewport::setClearEveryFrame(bool inClear, unsigned int inBuffers)
    {
        mClearEveryFrame = inClear;
		mClearBuffers = inBuffers;
    }
    //---------------------------------------------------------------------
    bool Viewport::getClearEveryFrame(void) const
    {
        return mClearEveryFrame;
    }
    //---------------------------------------------------------------------
    unsigned int Viewport::getClearBuffers(void) const
    {
        return mClearBuffers;
    }
    //---------------------------------------------------------------------
	void Viewport::clear(unsigned int buffers, const ColourValue& col,
						 Real depth, unsigned short stencil)
	{
		RenderSystem* rs = Root::getSingleton().getRenderSystem();
		if (rs)
		{
			Viewport* currentvp = rs->_getViewport();
			if (currentvp && currentvp == this)
				rs->clearFrameBuffer(buffers, col, depth, stencil);
			else if (currentvp)
			{
				rs->_setViewport(this);
				rs->clearFrameBuffer(buffers, col, depth, stencil);
				rs->_setViewport(currentvp);
			}
		}
	}
    //---------------------------------------------------------------------
    void Viewport::getActualDimensions(int &left, int&top, int &width, int &height) const
    {
        left = mActLeft;
        top = mActTop;
        width = mActWidth;
        height = mActHeight;

    }
    //---------------------------------------------------------------------
    unsigned int Viewport::_getNumRenderedFaces(void) const
    {
		return mCamera ? mCamera->_getNumRenderedFaces() : 0;
    }
    //---------------------------------------------------------------------
    unsigned int Viewport::_getNumRenderedBatches(void) const
    {
		return mCamera ? mCamera->_getNumRenderedBatches() : 0;
    }
	//---------------------------------------------------------------------
	void Viewport::setCamera(Camera* cam)
	{
		if(mCamera)
		{
			if(mCamera->getViewport() == this)
			{
				mCamera->_notifyViewport(0);
			}
		}

		mCamera = cam;
		if (cam)
		{
			// update aspect ratio of new camera if needed.
			if (cam->getAutoAspectRatio())
			{
				cam->setAspectRatio((Real) mActWidth / (Real) mActHeight);
			}
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
			cam->setOrientationMode(mOrientationMode);
#endif
			cam->_notifyViewport(this);
		}

		for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
		{
			(*i)->viewportCameraChanged(this);
		}
    }
    //---------------------------------------------------------------------
	void Viewport::setAutoUpdated(bool inAutoUpdated)
	{
		mIsAutoUpdated = inAutoUpdated;
	}
	//---------------------------------------------------------------------
	bool Viewport::isAutoUpdated() const
	{
		return mIsAutoUpdated;
	}
	//---------------------------------------------------------------------
    void Viewport::setOverlaysEnabled(bool enabled)
    {
        mShowOverlays = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getOverlaysEnabled(void) const
    {
        return mShowOverlays;
    }
    //---------------------------------------------------------------------
    void Viewport::setSkiesEnabled(bool enabled)
    {
        mShowSkies = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getSkiesEnabled(void) const
    {
        return mShowSkies;
    }
    //---------------------------------------------------------------------
    void Viewport::setShadowsEnabled(bool enabled)
    {
        mShowShadows = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getShadowsEnabled(void) const
    {
        return mShowShadows;
    }
	//-----------------------------------------------------------------------
	void Viewport::setRenderQueueInvocationSequenceName(const String& sequenceName)
	{
		mRQSequenceName = sequenceName;
		if (mRQSequenceName.empty())
		{
			mRQSequence = 0;
		}
		else
		{
			mRQSequence =
				Root::getSingleton().getRenderQueueInvocationSequence(mRQSequenceName);
		}
	}
	//-----------------------------------------------------------------------
	const String& Viewport::getRenderQueueInvocationSequenceName(void) const
	{
		return mRQSequenceName;
	}
	//-----------------------------------------------------------------------
	RenderQueueInvocationSequence* Viewport::_getRenderQueueInvocationSequence(void)
	{
		return mRQSequence;
	}
	//-----------------------------------------------------------------------
    void Viewport::pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv)
    {
        pointOrientedToScreen(v.x, v.y, orientationMode, outv.x, outv.y);
    }
	//-----------------------------------------------------------------------
    void Viewport::pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode,
                                         Real &screenX, Real &screenY)
    {
        Real orX = orientedX;
        Real orY = orientedY;
        switch (orientationMode)
        {
        case 1:
            screenX = orY;
            screenY = Real(1.0) - orX;
            break;
        case 2:
            screenX = Real(1.0) - orX;
            screenY = Real(1.0) - orY;
            break;
        case 3:
            screenX = Real(1.0) - orY;
            screenY = orX;
            break;
        default:
            screenX = orX;
            screenY = orY;
            break;
        }
    }
	//-----------------------------------------------------------------------
	void Viewport::addListener(Listener* l)
	{
		if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end())
			mListeners.push_back(l);
	}
	//-----------------------------------------------------------------------
	void Viewport::removeListener(Listener* l)
	{
		ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l);
		if (i != mListeners.end())
			mListeners.erase(i);
	}

}
<commit_msg>Fix [541]: viewportDestroyed were never called<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2012 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreViewport.h"

#include "OgreLogManager.h"
#include "OgreRenderTarget.h"
#include "OgreCamera.h"
#include "OgreMath.h"
#include "OgreRoot.h"
#include "OgreMaterialManager.h"
#include "OgreRenderSystem.h"
#include "OgreRenderWindow.h"

namespace Ogre {
    OrientationMode Viewport::mDefaultOrientationMode = OR_DEGREE_0;
    //---------------------------------------------------------------------
    Viewport::Viewport(Camera* cam, RenderTarget* target, Real left, Real top, Real width, Real height, int ZOrder)
        : mCamera(cam)
        , mTarget(target)
        , mRelLeft(left)
        , mRelTop(top)
        , mRelWidth(width)
        , mRelHeight(height)
        // Actual dimensions will update later
        , mZOrder(ZOrder)
        , mBackColour(ColourValue::Black)
		, mDepthClearValue(1)
        , mClearEveryFrame(true)
		, mClearBuffers(FBT_COLOUR | FBT_DEPTH)
        , mUpdated(false)
        , mShowOverlays(true)
        , mShowSkies(true)
		, mShowShadows(true)
		, mVisibilityMask(0xFFFFFFFF)
		, mRQSequence(0)
		, mMaterialSchemeName(MaterialManager::DEFAULT_SCHEME_NAME)
		, mIsAutoUpdated(true)
    {
#if OGRE_COMPILER != OGRE_COMPILER_GCCE && OGRE_PLATFORM != OGRE_PLATFORM_ANDROID
		LogManager::getSingleton().stream(LML_TRIVIAL)
			<< "Creating viewport on target '" << target->getName() << "'"
			<< ", rendering from camera '" << (cam != 0 ? cam->getName() : "NULL") << "'"
			<< ", relative dimensions "	<< std::ios::fixed << std::setprecision(2)
			<< "L: " << left << " T: " << top << " W: " << width << " H: " << height
			<< " ZOrder: " << ZOrder;
#endif

        // Set the default orientation mode
        mOrientationMode = mDefaultOrientationMode;

        // Set the default material scheme
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        mMaterialSchemeName = rs->_getDefaultViewportMaterialScheme();

        // Calculate actual dimensions
        _updateDimensions();

        // notify camera
        if(cam) cam->_notifyViewport(this);
    }
    //---------------------------------------------------------------------
    Viewport::~Viewport()
    {
		for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
		{
			(*i)->viewportDestroyed(this);
		}

		RenderSystem* rs = Root::getSingleton().getRenderSystem();
		if ((rs) && (rs->_getViewport() == this))
		{
			rs->_setViewport(NULL);
		}
    }
    //---------------------------------------------------------------------
    bool Viewport::_isUpdated(void) const
    {
        return mUpdated;
    }
    //---------------------------------------------------------------------
    void Viewport::_clearUpdatedFlag(void)
    {
        mUpdated = false;
    }
    //---------------------------------------------------------------------
    void Viewport::_updateDimensions(void)
    {
        Real height = (Real) mTarget->getHeight();
        Real width = (Real) mTarget->getWidth();

        mActLeft = (int) (mRelLeft * width);
        mActTop = (int) (mRelTop * height);
        mActWidth = (int) (mRelWidth * width);
        mActHeight = (int) (mRelHeight * height);

        // This will check if the cameras getAutoAspectRatio() property is set.
        // If it's true its aspect ratio is fit to the current viewport
        // If it's false the camera remains unchanged.
        // This allows cameras to be used to render to many viewports,
        // which can have their own dimensions and aspect ratios.

        if (mCamera)
        {
            if (mCamera->getAutoAspectRatio())
                mCamera->setAspectRatio((Real) mActWidth / (Real) mActHeight);

#if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
            mCamera->setOrientationMode(mOrientationMode);
#endif
        }

#if OGRE_COMPILER != OGRE_COMPILER_GCCE
		LogManager::getSingleton().stream(LML_TRIVIAL)
			<< "Viewport for camera '" << (mCamera != 0 ? mCamera->getName() : "NULL") << "'"
			<< ", actual dimensions "	<< std::ios::fixed << std::setprecision(2)
			<< "L: " << mActLeft << " T: " << mActTop << " W: " << mActWidth << " H: " << mActHeight;
#endif

		 mUpdated = true;

		for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
		{
			(*i)->viewportDimensionsChanged(this);
		}
	}
	//---------------------------------------------------------------------
	int Viewport::getZOrder(void) const
	{
		return mZOrder;
	}
	//---------------------------------------------------------------------
    RenderTarget* Viewport::getTarget(void) const
    {
        return mTarget;
    }
    //---------------------------------------------------------------------
    Camera* Viewport::getCamera(void) const
    {
        return mCamera;
    }
    //---------------------------------------------------------------------
    Real Viewport::getLeft(void) const
    {
        return mRelLeft;
    }
    //---------------------------------------------------------------------
    Real Viewport::getTop(void) const
    {
        return mRelTop;
    }
    //---------------------------------------------------------------------
    Real Viewport::getWidth(void) const
    {
        return mRelWidth;
    }
    //---------------------------------------------------------------------
    Real Viewport::getHeight(void) const
    {
        return mRelHeight;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualLeft(void) const
    {
        return mActLeft;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualTop(void) const
    {
        return mActTop;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualWidth(void) const
    {
        return mActWidth;
    }
    //---------------------------------------------------------------------
    int Viewport::getActualHeight(void) const
    {
        return mActHeight;
    }
    //---------------------------------------------------------------------
    void Viewport::setDimensions(Real left, Real top, Real width, Real height)
    {
        mRelLeft = left;
        mRelTop = top;
        mRelWidth = width;
        mRelHeight = height;
        _updateDimensions();
    }
    //---------------------------------------------------------------------
    void Viewport::update(void)
    {
        if (mCamera)
        {
            // Tell Camera to render into me
            mCamera->_renderScene(this, mShowOverlays);
        }
    }
    //---------------------------------------------------------------------
    void Viewport::setOrientationMode(OrientationMode orientationMode, bool setDefault)
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Setting Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        mOrientationMode = orientationMode;

        if (setDefault)
        {
            setDefaultOrientationMode(orientationMode);
        }

        if (mCamera)
        {
            mCamera->setOrientationMode(mOrientationMode);
        }

	// Update the render system config
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        if(mOrientationMode == OR_LANDSCAPELEFT)
            rs->setConfigOption("Orientation", "Landscape Left");
        else if(mOrientationMode == OR_LANDSCAPERIGHT)
            rs->setConfigOption("Orientation", "Landscape Right");
        else if(mOrientationMode == OR_PORTRAIT)
            rs->setConfigOption("Orientation", "Portrait");
#endif
    }
    //---------------------------------------------------------------------
    OrientationMode Viewport::getOrientationMode() const
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Getting Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        return mOrientationMode;
    }
    //---------------------------------------------------------------------
    void Viewport::setDefaultOrientationMode(OrientationMode orientationMode)
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Setting default Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        mDefaultOrientationMode = orientationMode;
    }
    //---------------------------------------------------------------------
    OrientationMode Viewport::getDefaultOrientationMode()
    {
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "Getting default Viewport orientation mode is not supported",
                    __FUNCTION__);
#endif
        return mDefaultOrientationMode;
    }
    //---------------------------------------------------------------------
    void Viewport::setBackgroundColour(const ColourValue& colour)
    {
        mBackColour = colour;
    }
    //---------------------------------------------------------------------
    const ColourValue& Viewport::getBackgroundColour(void) const
    {
        return mBackColour;
    }
    //---------------------------------------------------------------------
	void Viewport::setDepthClear( Real depth )
    {
        mDepthClearValue = depth;
    }
    //---------------------------------------------------------------------
    Real Viewport::getDepthClear(void) const
    {
        return mDepthClearValue;
    }
	//---------------------------------------------------------------------
    void Viewport::setClearEveryFrame(bool inClear, unsigned int inBuffers)
    {
        mClearEveryFrame = inClear;
		mClearBuffers = inBuffers;
    }
    //---------------------------------------------------------------------
    bool Viewport::getClearEveryFrame(void) const
    {
        return mClearEveryFrame;
    }
    //---------------------------------------------------------------------
    unsigned int Viewport::getClearBuffers(void) const
    {
        return mClearBuffers;
    }
    //---------------------------------------------------------------------
	void Viewport::clear(unsigned int buffers, const ColourValue& col,
						 Real depth, unsigned short stencil)
	{
		RenderSystem* rs = Root::getSingleton().getRenderSystem();
		if (rs)
		{
			Viewport* currentvp = rs->_getViewport();
			if (currentvp && currentvp == this)
				rs->clearFrameBuffer(buffers, col, depth, stencil);
			else if (currentvp)
			{
				rs->_setViewport(this);
				rs->clearFrameBuffer(buffers, col, depth, stencil);
				rs->_setViewport(currentvp);
			}
		}
	}
    //---------------------------------------------------------------------
    void Viewport::getActualDimensions(int &left, int&top, int &width, int &height) const
    {
        left = mActLeft;
        top = mActTop;
        width = mActWidth;
        height = mActHeight;

    }
    //---------------------------------------------------------------------
    unsigned int Viewport::_getNumRenderedFaces(void) const
    {
		return mCamera ? mCamera->_getNumRenderedFaces() : 0;
    }
    //---------------------------------------------------------------------
    unsigned int Viewport::_getNumRenderedBatches(void) const
    {
		return mCamera ? mCamera->_getNumRenderedBatches() : 0;
    }
	//---------------------------------------------------------------------
	void Viewport::setCamera(Camera* cam)
	{
		if(mCamera)
		{
			if(mCamera->getViewport() == this)
			{
				mCamera->_notifyViewport(0);
			}
		}

		mCamera = cam;
		if (cam)
		{
			// update aspect ratio of new camera if needed.
			if (cam->getAutoAspectRatio())
			{
				cam->setAspectRatio((Real) mActWidth / (Real) mActHeight);
			}
#if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
			cam->setOrientationMode(mOrientationMode);
#endif
			cam->_notifyViewport(this);
		}

		for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
		{
			(*i)->viewportCameraChanged(this);
		}
    }
    //---------------------------------------------------------------------
	void Viewport::setAutoUpdated(bool inAutoUpdated)
	{
		mIsAutoUpdated = inAutoUpdated;
	}
	//---------------------------------------------------------------------
	bool Viewport::isAutoUpdated() const
	{
		return mIsAutoUpdated;
	}
	//---------------------------------------------------------------------
    void Viewport::setOverlaysEnabled(bool enabled)
    {
        mShowOverlays = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getOverlaysEnabled(void) const
    {
        return mShowOverlays;
    }
    //---------------------------------------------------------------------
    void Viewport::setSkiesEnabled(bool enabled)
    {
        mShowSkies = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getSkiesEnabled(void) const
    {
        return mShowSkies;
    }
    //---------------------------------------------------------------------
    void Viewport::setShadowsEnabled(bool enabled)
    {
        mShowShadows = enabled;
    }
    //---------------------------------------------------------------------
    bool Viewport::getShadowsEnabled(void) const
    {
        return mShowShadows;
    }
	//-----------------------------------------------------------------------
	void Viewport::setRenderQueueInvocationSequenceName(const String& sequenceName)
	{
		mRQSequenceName = sequenceName;
		if (mRQSequenceName.empty())
		{
			mRQSequence = 0;
		}
		else
		{
			mRQSequence =
				Root::getSingleton().getRenderQueueInvocationSequence(mRQSequenceName);
		}
	}
	//-----------------------------------------------------------------------
	const String& Viewport::getRenderQueueInvocationSequenceName(void) const
	{
		return mRQSequenceName;
	}
	//-----------------------------------------------------------------------
	RenderQueueInvocationSequence* Viewport::_getRenderQueueInvocationSequence(void)
	{
		return mRQSequence;
	}
	//-----------------------------------------------------------------------
    void Viewport::pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv)
    {
        pointOrientedToScreen(v.x, v.y, orientationMode, outv.x, outv.y);
    }
	//-----------------------------------------------------------------------
    void Viewport::pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode,
                                         Real &screenX, Real &screenY)
    {
        Real orX = orientedX;
        Real orY = orientedY;
        switch (orientationMode)
        {
        case 1:
            screenX = orY;
            screenY = Real(1.0) - orX;
            break;
        case 2:
            screenX = Real(1.0) - orX;
            screenY = Real(1.0) - orY;
            break;
        case 3:
            screenX = Real(1.0) - orY;
            screenY = orX;
            break;
        default:
            screenX = orX;
            screenY = orY;
            break;
        }
    }
	//-----------------------------------------------------------------------
	void Viewport::addListener(Listener* l)
	{
		if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end())
			mListeners.push_back(l);
	}
	//-----------------------------------------------------------------------
	void Viewport::removeListener(Listener* l)
	{
		ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l);
		if (i != mListeners.end())
			mListeners.erase(i);
	}

}
<|endoftext|>


<commit_before>//
//   Copyright 2015 Pixar
//
//   Licensed under the Apache License, Version 2.0 (the "Apache License")
//   with the following modification; you may not use this file except in
//   compliance with the Apache License and the following modification to it:
//   Section 6. Trademarks. is deleted and replaced with:
//
//   6. Trademarks. This License does not grant permission to use the trade
//      names, trademarks, service marks, or product names of the Licensor
//      and its affiliates, except as required to comply with Section 4(c) of
//      the License and to reproduce the content of the NOTICE file.
//
//   You may obtain a copy of the Apache License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the Apache License with the above modification is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//   KIND, either express or implied. See the Apache License for the specific
//   language governing permissions and limitations under the Apache License.
//

#include <sstream>
#include <string>
#include "glUtils.h"

namespace GLUtils {

void
CheckGLErrors(std::string const & where) {
    GLuint err;
    while ((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "GL error: "
                  << (where.empty() ? "" : where + " ")
                  << err << "\n";
    }
}

GLuint
CompileShader(GLenum shaderType, const char *source) {
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);

    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
        GLchar emsg[40960];
        glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
        fprintf(stderr, "Error compiling GLSL shader: %s\n", emsg);
        return 0;
    }

    return shader;
}

bool
SupportsAdaptiveTessellation() {
#ifdef OSD_USES_GLEW
    return glewGetExtension("GL_ARB_tessellation_shader") == GL_TRUE;
#else
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
    return true;
#else
    return false;
#endif
#endif
}

///Helper function that parses the open gl version string, retrieving the major
///and minor version from it.
void GetMajorMinorVersion(int *major, int *minor){
	static bool initialized = false;
	int _major = -1, _minor = -1;
	if (!initialized || _major == -1 || _minor == -1){
		const GLubyte *ver = glGetString(GL_SHADING_LANGUAGE_VERSION);
		if (!ver){
			_major = -1;
			_minor = -1;
		}
		else{
			std::string major_str(ver, ver + 1);
			std::string minor_str(ver + 2, ver + 3);
			std::stringstream ss;
			ss << major_str << " " << minor_str;
			ss >> _major;
			ss >> _minor;
		}
		initialized = true;
	}
	*major = _major;
	*minor = _minor;

}

/** Gets the shader version based on the current opengl version and returns
 * it in a string form */

const std::string &GetShaderVersion(){
	static bool initialized = false;
	static std::string shader_version;
	if (!initialized){

		int major, minor;
		GetMajorMinorVersion(&major, &minor);
		int version_number = major * 10 + minor;
		switch (version_number){
		case 20:
			shader_version = "110";
			break;
		case 21:
			shader_version = "120";
			break;
		case 30:
			shader_version = "130";
			break;
		case 31:
			shader_version = "140";
			break;
		case 32:
			shader_version = "150";
			break;
		default:
			std::stringstream ss;
			ss << version_number;
			shader_version = ss.str() + "0";
			break;
		}
		initialized = true;
	}
	return shader_version;
}

/* Generates the version defintion needed by the glsl shaders based on the
 * opengl string
*/
const std::string &GetShaderVersionInclude(){
	static bool initialized = false;
	static std::string include;
	if (!initialized){
		include = "#version " + GetShaderVersion() + "\n";
		initialized = true;
	}
	return include;
}

bool GL_ARBSeparateShaderObjectsOrGL_VERSION_4_1(){
#if defined(OSD_USES_GLEW)
	bool initialized = false, uses = false;
	if (!initialized){
		uses = glewGetExtension("GL_ARB_separate_shader_objects") ||
			(GLEW_VERSION_4_1
			&& glewGetExtension("GL_ARB_tessellation_shader"));
		initialized = true;
	}
	return uses;
#else
#if defined(GL_ARB_separate_shader_objects) || defined(GL_VERSION_4_1)
	return true;
#else
	return false;
#endif
#endif
}

}   // namesapce GLUtils
<commit_msg>reverting glewGetExtension with glewIsSupported until we find a better workaround.<commit_after>//
//   Copyright 2015 Pixar
//
//   Licensed under the Apache License, Version 2.0 (the "Apache License")
//   with the following modification; you may not use this file except in
//   compliance with the Apache License and the following modification to it:
//   Section 6. Trademarks. is deleted and replaced with:
//
//   6. Trademarks. This License does not grant permission to use the trade
//      names, trademarks, service marks, or product names of the Licensor
//      and its affiliates, except as required to comply with Section 4(c) of
//      the License and to reproduce the content of the NOTICE file.
//
//   You may obtain a copy of the Apache License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the Apache License with the above modification is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//   KIND, either express or implied. See the Apache License for the specific
//   language governing permissions and limitations under the Apache License.
//

#include <sstream>
#include <string>
#include "glUtils.h"

namespace GLUtils {

void
CheckGLErrors(std::string const & where) {
    GLuint err;
    while ((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "GL error: "
                  << (where.empty() ? "" : where + " ")
                  << err << "\n";
    }
}

GLuint
CompileShader(GLenum shaderType, const char *source) {
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);

    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
        GLchar emsg[40960];
        glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
        fprintf(stderr, "Error compiling GLSL shader: %s\n", emsg);
        return 0;
    }

    return shader;
}

bool
SupportsAdaptiveTessellation() {
#ifdef OSD_USES_GLEW
    // XXXtakahito:
    //    glewGetExtension doesn't work if the context is initialized
    //    with core profile, since glGetStrings(GL_EXTENSIONS) return
    //    NULL.
    //
    //return glewGetExtension("GL_ARB_tessellation_shader") != NULL;
    return glewIsSupported("GL_ARB_tessellation_shader");
#else
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
    return true;
#else
    return false;
#endif
#endif
}

///Helper function that parses the open gl version string, retrieving the major
///and minor version from it.
void GetMajorMinorVersion(int *major, int *minor){
	static bool initialized = false;
	int _major = -1, _minor = -1;
	if (!initialized || _major == -1 || _minor == -1){
		const GLubyte *ver = glGetString(GL_SHADING_LANGUAGE_VERSION);
		if (!ver){
			_major = -1;
			_minor = -1;
		}
		else{
			std::string major_str(ver, ver + 1);
			std::string minor_str(ver + 2, ver + 3);
			std::stringstream ss;
			ss << major_str << " " << minor_str;
			ss >> _major;
			ss >> _minor;
		}
		initialized = true;
	}
	*major = _major;
	*minor = _minor;

}

/** Gets the shader version based on the current opengl version and returns
 * it in a string form */

const std::string &GetShaderVersion(){
	static bool initialized = false;
	static std::string shader_version;
	if (!initialized){

		int major, minor;
		GetMajorMinorVersion(&major, &minor);
		int version_number = major * 10 + minor;
		switch (version_number){
		case 20:
			shader_version = "110";
			break;
		case 21:
			shader_version = "120";
			break;
		case 30:
			shader_version = "130";
			break;
		case 31:
			shader_version = "140";
			break;
		case 32:
			shader_version = "150";
			break;
		default:
			std::stringstream ss;
			ss << version_number;
			shader_version = ss.str() + "0";
			break;
		}
		initialized = true;
	}
	return shader_version;
}

/* Generates the version defintion needed by the glsl shaders based on the
 * opengl string
*/
const std::string &GetShaderVersionInclude(){
	static bool initialized = false;
	static std::string include;
	if (!initialized){
		include = "#version " + GetShaderVersion() + "\n";
		initialized = true;
	}
	return include;
}

bool GL_ARBSeparateShaderObjectsOrGL_VERSION_4_1(){
#if defined(OSD_USES_GLEW)
	bool initialized = false, uses = false;
	if (!initialized){
		uses = glewGetExtension("GL_ARB_separate_shader_objects") ||
			(GLEW_VERSION_4_1
			&& glewGetExtension("GL_ARB_tessellation_shader"));
		initialized = true;
	}
	return uses;
#else
#if defined(GL_ARB_separate_shader_objects) || defined(GL_VERSION_4_1)
	return true;
#else
	return false;
#endif
#endif
}

}   // namesapce GLUtils
<|endoftext|>


<commit_before>//
//  LevelManager.cpp
//  Created by Matt Kaufmann on 01/10/14.
//

#include "ExampleGame/Components/ComponentTypes/ComponentTypeIds.h"
#include "ExampleGame/Components/LevelManager/LevelLoader.h"
#include "ExampleGame/Components/LevelManager/LevelManager.h"
#include "ExampleGame/Components/Triggers/TriggerLevelDefeat.h"
#include "ExampleGame/Components/Triggers/TriggerLevelVictory.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"

#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Framework/SavedDataManager/SavedDataManager.h"

#include <fstream>

ComponentIdType LevelManager::componentTypeId = COMPONENT_TYPE_ID_LEVEL_MANAGER;

LevelManager::LevelManager() : Component() {
	this->init();
}

LevelManager::LevelManager(Object* object_) : Component(object_) {
	this->init();
}

LevelManager::~LevelManager() {
	this->destroy();
}

void LevelManager::HandleMessage(MessageChunk messageChunk) {
	Component::HandleMessage(messageChunk);
	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_FRAME_EVENT:
			this->update();
			break;
		case MESSAGE_TYPE_ON_END_CONDITIONS_MET:
			break;
		case MESSAGE_TYPE_LEVEL_UNLOADED:
			if(this->levelToLoad != -1) {
				MessageChunk mc = ENGINE->GetMessageHub()->GetOneFreeMessage();
				mc->SetMessageType(MESSAGE_TYPE_LOAD_LEVEL);
				// TODO [HACK We need this delay when loading a new level
				mc->messageData.iv1.x = 3;
				ENGINE->GetMessageHub()->SendPointcastMessage(mc, this->GetObject()->GetId(), this->GetObject()->GetId());
			}
			break;
		case MESSAGE_TYPE_LOAD_LEVEL:
				if(messageChunk->messageData.iv1.x == 0) {
					this->loadLevel_internal();
				} else {
					MessageChunk mc = ENGINE->GetMessageHub()->GetOneFreeMessage();
					mc->SetMessageType(MESSAGE_TYPE_LOAD_LEVEL);
					mc->messageData.iv1.x = messageChunk->messageData.iv1.x - 1;
					ENGINE->GetMessageHub()->SendPointcastMessage(mc, this->GetObject()->GetId(), this->GetObject()->GetId());
				}
			break;
		default:
			break;
	}
}

void LevelManager::LoadLevel(int levelNumber) {
	this->levelToLoad = levelNumber;
	this->UnloadLevel();
}

void LevelManager::UnloadLevel() {
	// Unload the previous scene and all other items in the SceneGraph3D
	this->clearEndConditions();
	ENGINE->GetSceneGraph3D()->UnloadCurrentScene();
	ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_LEVEL_UNLOADED);
}

void LevelManager::ReloadCurrentLevel() {
	this->LoadLevel(this->currentLevelIndex);
}

bool LevelManager::TryLoadNextLevel() {
	if(this->currentLevelIndex + 1 < this->GetNumLevelsInCurrentMission()) {
		this->LoadLevel(this->currentLevelIndex + 1);
		return true;
	}
	return false;
}

void LevelManager::StartLevel() {
	ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_SCENE_START);
}

void LevelManager::loadLevel_internal() {
	ASSERT(this->levelToLoad < this->GetNumLevelsInCurrentMission(), "level number is less than the number of levels");
	if(this->levelToLoad < this->GetNumLevelsInCurrentMission()) {
		this->currentLevelIndex = this->levelToLoad;
		this->LoadLevelFromData(this->GetLevelData(this->currentMission, this->levelToLoad));
		ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_LEVEL_LOADED);
	}
	this->levelToLoad = -1;
}

void LevelManager::LoadLevelFromData(LevelData* levelData) {
	LevelLoader::LoadLevelFromFile(levelData->path);
	if(levelData->hasTutorial) {
		LevelLoader::LoadTutorialData(levelData->name);
	}
	// Set up the bonus
	SINGLETONS->GetMasteryManager()->SetCurrentBonuse(levelData->bonus, levelData->bonusValue);
}

LevelData* LevelManager::GetLevelData(int missionIndex, int levelIndex)
{
	return this->GetLevelData(this->currentContract, missionIndex, levelIndex);
}

LevelData* LevelManager::GetLevelData(int contractIndex, int missionIndex, int levelIndex)
{
	std::vector<LevelData*> lData = this->GetMissionData(contractIndex, missionIndex)->levels;
	if(levelIndex < (int)lData.size()) {
		return lData[levelIndex];
	}
	ASSERT(false, "index passed into GetLevelData is valid");
	return lData[0];
}

MissionData* LevelManager::GetMissionData(int contractIndex, int missionIndex)
{
	std::vector<MissionData*> mData = this->GetContractData(contractIndex)->missions;
	if(missionIndex < (int)mData.size()) {
		return mData[missionIndex];
	}
	ASSERT(false, "missionIndex passed into GetMissionData is valid");
	return mData[0];
}
ContractData* LevelManager::GetContractData(int index)
{
	if(index < (int)this->contractData.size()) {
		return this->contractData[index];
	}
	ASSERT(false, "index passed into GetContractData is valid");
	return this->contractData[0];
}

int LevelManager::GetNumLevelsInMission(int mission) {
	MissionData* mData = GetMissionData(this->currentContract, mission);
	return mData->levels.size();
}

void LevelManager::OnCurrentLevelWon(LevelCompletion completion) {
	LevelData* lData = this->GetLevelData(this->currentMission, this->currentLevelIndex);
	if(completion > lData->completion) {
		Bundle* bundle = FRAMEWORK->GetSavedDataManager()->GetSavedBundle(PLAYER_BUNDLE_NAME);

		lData->completion = completion;

		if(lData->completion == LevelCompletion::Completed) {
			this->levelCompletionData[lData->levelNum] = 'C';
		} else if (lData->completion == LevelCompletion::Completed_Bonus) {
			this->levelCompletionData[lData->levelNum] = 'B';

		}

		LevelData* nextLevel = this->getNextLevel();
		if(nextLevel->completion == LevelCompletion::Locked) {
			nextLevel->completion = LevelCompletion::Unlocked;
			this->levelCompletionData[nextLevel->levelNum] = 'U';
		}

		bundle->PutString(LEVEL_COMPLETION, this->levelCompletionData);
		bundle->Save();
	}
}

LevelData* LevelManager::getNextLevel() {
	int lIndex = this->currentLevelIndex + 1;
	int mIndex = this->currentMission;
	int cIndex = this->currentContract;
	if(lIndex < this->GetNumLevelsInCurrentMission()) {
		return this->GetLevelData(mIndex, lIndex);
	}
	mIndex++;
	if(mIndex < GetNumMissionsInCurrentContract()) {
		return this->GetLevelData(mIndex, 0);
	}
	cIndex++;
	if(cIndex < this->NumContracts()) {
		return this->GetLevelData(cIndex, mIndex, lIndex);
	}
	// this is the last level
	return nullptr;
}

void LevelManager::AddWinCondition(ObjectIdType switchId) {
	Triggerable* victoryTrigger = this->winner->GetComponent<Triggerable>();
	victoryTrigger->SubscribeToSwitchObject(switchId);
}

void LevelManager::AddLoseCondition(ObjectIdType switchId) {
	Triggerable* defeatTrigger = this->loser->GetComponent<Triggerable>();
	defeatTrigger->SubscribeToSwitchObject(switchId);
}

void LevelManager::init() {
	this->addSubscriptionToMessageType(MESSAGE_TYPE_FRAME_EVENT, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_LEVEL_UNLOADED, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_LOAD_LEVEL, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_ON_END_CONDITIONS_MET, this->GetTypeId(), false);

	// Generate required end condition objects
	this->winner = new Object();
	winner->AddComponent<TriggerLevelVictory>();

	this->loser = new Object();
	loser->AddComponent<TriggerLevelDefeat>();

	// load player data
	Bundle* bundle = nullptr;
	if (!FRAMEWORK->GetSavedDataManager()->HasBundle(PLAYER_BUNDLE_NAME)) {
		this->initBundleForFirstTime();
	}

	bundle = FRAMEWORK->GetSavedDataManager()->GetSavedBundle(PLAYER_BUNDLE_NAME);
	this->levelCompletionData = bundle->GetString(LEVEL_COMPLETION);

	this->levelToLoad = -1;
	currentLevelIndex = 0;
	currentMission = 0;
	currentContract = 0;
	// load the list of levels with a tutorial
	LevelLoader::LoadLevelData(&this->contractData);
}

void LevelManager::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());

	if (this->winner != nullptr) {
		delete this->winner;
		this->winner = nullptr;
	}

	if (this->loser != nullptr) {
		delete this->loser;
		this->loser = nullptr;
	}
}

void LevelManager::update() {
}

void LevelManager::endLevel(bool /*success*/) {
	//LevelEnd.EndLevel(success);
}

void LevelManager::clearEndConditions() {
	Triggerable* victoryTrigger = winner->GetComponent<TriggerLevelVictory>();
	if (victoryTrigger != nullptr) {
		victoryTrigger->UnsubscribeToAllSwitches();
	}

	Triggerable* defeatTrigger = loser->GetComponent<TriggerLevelDefeat>();
	if (defeatTrigger != nullptr) {
		defeatTrigger->UnsubscribeToAllSwitches();
	}
}

void LevelManager::initBundleForFirstTime() {
	Bundle* bundle = FRAMEWORK->GetSavedDataManager()->CreateNewBundle(PLAYER_BUNDLE_NAME);

	// create level completion data
	char levelCompletion[MAX_LEVELS_POSSIBLE];
	levelCompletion[0] = 'U'; // U = unlocked
	for(int i = 1; i < MAX_LEVELS_POSSIBLE; ++i) {
		levelCompletion[i] = 'L'; // L = locked
	}

	std::string levelData = levelCompletion;
	bundle->PutString(LEVEL_COMPLETION, levelData);

	bundle->Save();
}
<commit_msg>Debug override that unlocks all levels<commit_after>//
//  LevelManager.cpp
//  Created by Matt Kaufmann on 01/10/14.
//

#include "ExampleGame/Components/ComponentTypes/ComponentTypeIds.h"
#include "ExampleGame/Components/LevelManager/LevelLoader.h"
#include "ExampleGame/Components/LevelManager/LevelManager.h"
#include "ExampleGame/Components/Triggers/TriggerLevelDefeat.h"
#include "ExampleGame/Components/Triggers/TriggerLevelVictory.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"

#include "Vajra/Engine/MessageHub/MessageHub.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Framework/SavedDataManager/SavedDataManager.h"

#include <fstream>

ComponentIdType LevelManager::componentTypeId = COMPONENT_TYPE_ID_LEVEL_MANAGER;

LevelManager::LevelManager() : Component() {
	this->init();
}

LevelManager::LevelManager(Object* object_) : Component(object_) {
	this->init();
}

LevelManager::~LevelManager() {
	this->destroy();
}

void LevelManager::HandleMessage(MessageChunk messageChunk) {
	Component::HandleMessage(messageChunk);
	switch (messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_FRAME_EVENT:
			this->update();
			break;
		case MESSAGE_TYPE_ON_END_CONDITIONS_MET:
			break;
		case MESSAGE_TYPE_LEVEL_UNLOADED:
			if(this->levelToLoad != -1) {
				MessageChunk mc = ENGINE->GetMessageHub()->GetOneFreeMessage();
				mc->SetMessageType(MESSAGE_TYPE_LOAD_LEVEL);
				// TODO [HACK We need this delay when loading a new level
				mc->messageData.iv1.x = 3;
				ENGINE->GetMessageHub()->SendPointcastMessage(mc, this->GetObject()->GetId(), this->GetObject()->GetId());
			}
			break;
		case MESSAGE_TYPE_LOAD_LEVEL:
				if(messageChunk->messageData.iv1.x == 0) {
					this->loadLevel_internal();
				} else {
					MessageChunk mc = ENGINE->GetMessageHub()->GetOneFreeMessage();
					mc->SetMessageType(MESSAGE_TYPE_LOAD_LEVEL);
					mc->messageData.iv1.x = messageChunk->messageData.iv1.x - 1;
					ENGINE->GetMessageHub()->SendPointcastMessage(mc, this->GetObject()->GetId(), this->GetObject()->GetId());
				}
			break;
		default:
			break;
	}
}

void LevelManager::LoadLevel(int levelNumber) {
	this->levelToLoad = levelNumber;
	this->UnloadLevel();
}

void LevelManager::UnloadLevel() {
	// Unload the previous scene and all other items in the SceneGraph3D
	this->clearEndConditions();
	ENGINE->GetSceneGraph3D()->UnloadCurrentScene();
	ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_LEVEL_UNLOADED);
}

void LevelManager::ReloadCurrentLevel() {
	this->LoadLevel(this->currentLevelIndex);
}

bool LevelManager::TryLoadNextLevel() {
	if(this->currentLevelIndex + 1 < this->GetNumLevelsInCurrentMission()) {
		this->LoadLevel(this->currentLevelIndex + 1);
		return true;
	}
	return false;
}

void LevelManager::StartLevel() {
	ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_SCENE_START);
}

void LevelManager::loadLevel_internal() {
	ASSERT(this->levelToLoad < this->GetNumLevelsInCurrentMission(), "level number is less than the number of levels");
	if(this->levelToLoad < this->GetNumLevelsInCurrentMission()) {
		this->currentLevelIndex = this->levelToLoad;
		this->LoadLevelFromData(this->GetLevelData(this->currentMission, this->levelToLoad));
		ENGINE->GetMessageHub()->SendMulticastMessage(MESSAGE_TYPE_LEVEL_LOADED);
	}
	this->levelToLoad = -1;
}

void LevelManager::LoadLevelFromData(LevelData* levelData) {
	LevelLoader::LoadLevelFromFile(levelData->path);
	if(levelData->hasTutorial) {
		LevelLoader::LoadTutorialData(levelData->name);
	}
	// Set up the bonus
	SINGLETONS->GetMasteryManager()->SetCurrentBonuse(levelData->bonus, levelData->bonusValue);
}

LevelData* LevelManager::GetLevelData(int missionIndex, int levelIndex)
{
	return this->GetLevelData(this->currentContract, missionIndex, levelIndex);
}

LevelData* LevelManager::GetLevelData(int contractIndex, int missionIndex, int levelIndex)
{
	std::vector<LevelData*> lData = this->GetMissionData(contractIndex, missionIndex)->levels;
	if(levelIndex < (int)lData.size()) {
		return lData[levelIndex];
	}
	ASSERT(false, "index passed into GetLevelData is valid");
	return lData[0];
}

MissionData* LevelManager::GetMissionData(int contractIndex, int missionIndex)
{
	std::vector<MissionData*> mData = this->GetContractData(contractIndex)->missions;
	if(missionIndex < (int)mData.size()) {
		return mData[missionIndex];
	}
	ASSERT(false, "missionIndex passed into GetMissionData is valid");
	return mData[0];
}
ContractData* LevelManager::GetContractData(int index)
{
	if(index < (int)this->contractData.size()) {
		return this->contractData[index];
	}
	ASSERT(false, "index passed into GetContractData is valid");
	return this->contractData[0];
}

int LevelManager::GetNumLevelsInMission(int mission) {
	MissionData* mData = GetMissionData(this->currentContract, mission);
	return mData->levels.size();
}

void LevelManager::OnCurrentLevelWon(LevelCompletion completion) {
	LevelData* lData = this->GetLevelData(this->currentMission, this->currentLevelIndex);
	if(completion > lData->completion) {
		Bundle* bundle = FRAMEWORK->GetSavedDataManager()->GetSavedBundle(PLAYER_BUNDLE_NAME);

		lData->completion = completion;

		if(lData->completion == LevelCompletion::Completed) {
			this->levelCompletionData[lData->levelNum] = 'C';
		} else if (lData->completion == LevelCompletion::Completed_Bonus) {
			this->levelCompletionData[lData->levelNum] = 'B';

		}

		LevelData* nextLevel = this->getNextLevel();
		if(nextLevel->completion == LevelCompletion::Locked) {
			nextLevel->completion = LevelCompletion::Unlocked;
			this->levelCompletionData[nextLevel->levelNum] = 'U';
		}

		bundle->PutString(LEVEL_COMPLETION, this->levelCompletionData);
		bundle->Save();
	}
}

LevelData* LevelManager::getNextLevel() {
	int lIndex = this->currentLevelIndex + 1;
	int mIndex = this->currentMission;
	int cIndex = this->currentContract;
	if(lIndex < this->GetNumLevelsInCurrentMission()) {
		return this->GetLevelData(mIndex, lIndex);
	}
	mIndex++;
	if(mIndex < GetNumMissionsInCurrentContract()) {
		return this->GetLevelData(mIndex, 0);
	}
	cIndex++;
	if(cIndex < this->NumContracts()) {
		return this->GetLevelData(cIndex, mIndex, lIndex);
	}
	// this is the last level
	return nullptr;
}

void LevelManager::AddWinCondition(ObjectIdType switchId) {
	Triggerable* victoryTrigger = this->winner->GetComponent<Triggerable>();
	victoryTrigger->SubscribeToSwitchObject(switchId);
}

void LevelManager::AddLoseCondition(ObjectIdType switchId) {
	Triggerable* defeatTrigger = this->loser->GetComponent<Triggerable>();
	defeatTrigger->SubscribeToSwitchObject(switchId);
}

void LevelManager::init() {
	this->addSubscriptionToMessageType(MESSAGE_TYPE_FRAME_EVENT, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_LEVEL_UNLOADED, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_LOAD_LEVEL, this->GetTypeId(), false);
	this->addSubscriptionToMessageType(MESSAGE_TYPE_ON_END_CONDITIONS_MET, this->GetTypeId(), false);

	// Generate required end condition objects
	this->winner = new Object();
	winner->AddComponent<TriggerLevelVictory>();

	this->loser = new Object();
	loser->AddComponent<TriggerLevelDefeat>();

	// load player data
	Bundle* bundle = nullptr;
	if (!FRAMEWORK->GetSavedDataManager()->HasBundle(PLAYER_BUNDLE_NAME)) {
		this->initBundleForFirstTime();
	}

	bundle = FRAMEWORK->GetSavedDataManager()->GetSavedBundle(PLAYER_BUNDLE_NAME);
	this->levelCompletionData = bundle->GetString(LEVEL_COMPLETION);

	this->levelToLoad = -1;
	currentLevelIndex = 0;
	currentMission = 0;
	currentContract = 0;
	// load the list of levels with a tutorial
	LevelLoader::LoadLevelData(&this->contractData);
}

void LevelManager::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());

	if (this->winner != nullptr) {
		delete this->winner;
		this->winner = nullptr;
	}

	if (this->loser != nullptr) {
		delete this->loser;
		this->loser = nullptr;
	}
}

void LevelManager::update() {
}

void LevelManager::endLevel(bool /*success*/) {
	//LevelEnd.EndLevel(success);
}

void LevelManager::clearEndConditions() {
	Triggerable* victoryTrigger = winner->GetComponent<TriggerLevelVictory>();
	if (victoryTrigger != nullptr) {
		victoryTrigger->UnsubscribeToAllSwitches();
	}

	Triggerable* defeatTrigger = loser->GetComponent<TriggerLevelDefeat>();
	if (defeatTrigger != nullptr) {
		defeatTrigger->UnsubscribeToAllSwitches();
	}
}

void LevelManager::initBundleForFirstTime() {
	Bundle* bundle = FRAMEWORK->GetSavedDataManager()->CreateNewBundle(PLAYER_BUNDLE_NAME);

	// create level completion data
	char levelCompletion[MAX_LEVELS_POSSIBLE];
	levelCompletion[0] = 'U'; // U = unlocked
	for(int i = 1; i < MAX_LEVELS_POSSIBLE; ++i) {
#ifdef DEBUG
		levelCompletion[i] = 'U';
#else
		levelCompletion[i] = 'L'; // L = locked
#endif
	}

	std::string levelData = levelCompletion;
	bundle->PutString(LEVEL_COMPLETION, levelData);

	bundle->Save();
}
<|endoftext|>


<commit_before>
#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		friend class B_tree;

		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { }
		~Node() {}
		void show(ostream &out, const int level = 0) const;
	};

	Node *tree, *null_tr;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left =nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right =nullptr;
		}
		delete tr_;
	}

public:
	Tree()
	{
		tree = NULL;
		null_tr = nullptr;
	};
	Node* tree_one() { return tree };
	void file_tree(char* name);
	void add(const T value);
	bool find(const T value);
	bool isEmpty() const { return tree== NULL; }
	void print(ostream &out) const;
	~Tree()
	{
		null_tree(tree);
		null_tree(null_tr);
	};
};
<commit_msg>Update tree.hpp<commit_after>
#include <fstream>
#include <iostream>

using namespace std;

template <class T>
class Tree
{
private:
	struct Node

	{
		friend class B_tree;

		T value_;
		Node *left;
		Node *right;
		Node() {};
		Node(const T value) : value_(value) { }
		~Node() {}
		void show(ostream &out, const int level) const;
	};

	Node *tree, *null_tr;
	void null_tree(Node *tr_)
	{
		if (!tr_) return;
		if (tr_->left)
		{
			null_tree(tr_->left);
			tr_->left =nullptr;
		}
		if (tr_->right)
		{
			null_tree(tr_->right);
			tr_->right =nullptr;
		}
		delete tr_;
	}

public:
	Tree()
	{
		tree = NULL;
		null_tr = nullptr;
	};
	Node* tree_one() { return tree };
	void file_tree(char* name);
	void add(const T value);
	bool find(const T value);
	bool isEmpty() const { return tree== NULL; }
	void print(ostream &out) const;
	~Tree()
	{
		null_tree(tree);
		null_tree(null_tr);
	};
};
<|endoftext|>