<commit_before>/*
 * Copyright (c) 2015, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <signal.h>

#ifdef BUILD_TESTS
// Temporary fix for UnitTest until APPLINK-9987 is resolved
#include <unistd.h>
#endif

#include "utils/threads/thread.h"
#include "pthread.h"
#include "utils/atomic.h"
#include "utils/threads/thread_delegate.h"
#include "utils/logger.h"

#ifndef __QNXNTO__
const int EOK = 0;
#endif

#if defined(OS_POSIX)
const size_t THREAD_NAME_SIZE = 15;
#endif

namespace threads {

CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")

size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */

void Thread::cleanup(void* arg) {
  LOG4CXX_AUTO_TRACE(logger_);
  Thread* thread = reinterpret_cast<Thread*>(arg);
  sync_primitives::AutoLock auto_lock(thread->state_lock_);
  thread->isThreadRunning_ = false;
  thread->state_cond_.Broadcast();
}

void* Thread::threadFunc(void* arg) {
  // 0 - state_lock unlocked
  //     stopped   = 0
  //     running   = 0
  //     finalized = 0
  // 4 - state_lock unlocked
  //     stopped = 1
  //     running = 1
  //     finalized = 0
  // 5 - state_lock unlocked
  //     stopped = 1
  //     running = 1
  //     finalized = 1
  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  LOG4CXX_DEBUG(logger_,
                "Thread #" << pthread_self() << " started successfully");

  threads::Thread* thread = reinterpret_cast<Thread*>(arg);
  DCHECK(thread);

  pthread_cleanup_push(&cleanup, thread);

    thread->state_lock_.Acquire();
    thread->state_cond_.Broadcast();

    while (!thread->finalized_) {
      LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration");
      thread->run_cond_.Wait(thread->state_lock_);
      LOG4CXX_DEBUG(
          logger_,
          "Thread #" << pthread_self() << " execute. " << "stopped_ = " << thread->stopped_ << "; finalized_ = " << thread->finalized_);
      if (!thread->stopped_ && !thread->finalized_) {
        thread->isThreadRunning_ = true;
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_testcancel();

        thread->state_lock_.Release();
        thread->delegate_->threadMain();
        thread->state_lock_.Acquire();

        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        thread->isThreadRunning_ = false;
      }
      thread->state_cond_.Broadcast();
      LOG4CXX_DEBUG(logger_,
                    "Thread #" << pthread_self() << " finished iteration");
    }

    thread->state_lock_.Release();
    pthread_cleanup_pop(1);

  LOG4CXX_DEBUG(logger_,
                "Thread #" << pthread_self() << " exited successfully");
  return NULL;
}

void Thread::SetNameForId(const PlatformThreadHandle& thread_id,
                          std::string name) {
  if (name.size() > THREAD_NAME_SIZE)
    name.erase(THREAD_NAME_SIZE);
  const int rc = pthread_setname_np(thread_id, name.c_str());
  if (rc != EOK) {
    LOG4CXX_WARN(
        logger_,
        "Couldn't set pthread name \"" << name << "\", error code " << rc << " (" << strerror(rc) << ")");
  }
}

Thread::Thread(const char* name, ThreadDelegate* delegate)
    : name_(name ? name : "undefined"),
      delegate_(delegate),
      handle_(0),
      thread_options_(),
      isThreadRunning_(0),
      stopped_(false),
      finalized_(false),
      thread_created_(false) {
}

bool Thread::start() {
  return start(thread_options_);
}

PlatformThreadHandle Thread::CurrentId() {
  return pthread_self();
}

bool Thread::start(const ThreadOptions& options) {
  LOG4CXX_AUTO_TRACE(logger_);

  sync_primitives::AutoLock auto_lock(state_lock_);
  // 1 - state_lock locked
  //     stopped = 0
  //     running = 0

  if (!delegate_) {
    LOG4CXX_ERROR(logger_,
                  "Cannot start thread " << name_ << ": delegate is NULL");
    // 0 - state_lock unlocked
    return false;
  }

  if (isThreadRunning_) {
    LOG4CXX_TRACE(
        logger_,
        "EXIT thread "<< name_ << " #" << handle_ << " is already running");
    return true;
  }

  thread_options_ = options;

  pthread_attr_t attributes;
  int pthread_result = pthread_attr_init(&attributes);
  if (pthread_result != EOK) {
    LOG4CXX_WARN(
        logger_,
        "Couldn't init pthread attributes. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
  }

  if (!thread_options_.is_joinable()) {
    pthread_result = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
    if (pthread_result != EOK) {
      LOG4CXX_WARN(
          logger_,
          "Couldn't set detach state attribute. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
      thread_options_.is_joinable(false);
    }
  }

  const size_t stack_size = thread_options_.stack_size();
  if (stack_size >= Thread::kMinStackSize) {
    pthread_result = pthread_attr_setstacksize(&attributes, stack_size);
    if (pthread_result != EOK) {
      LOG4CXX_WARN(
          logger_,
          "Couldn't set stacksize = " << stack_size << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
    }
  }
  else {
    ThreadOptions thread_options_temp(Thread::kMinStackSize, thread_options_.is_joinable());
    thread_options_ = thread_options_temp;
  }

  if (!thread_created_) {
    // state_lock 1
    pthread_result = pthread_create(&handle_, &attributes, threadFunc, this);
    if (pthread_result == EOK) {
      LOG4CXX_DEBUG(logger_, "Created thread: " << name_);
      SetNameForId(handle_, name_);
      // state_lock 0
      // possible concurrencies: stop and threadFunc
      state_cond_.Wait(auto_lock);
      thread_created_ = true;
    } else {
      LOG4CXX_ERROR(
          logger_,
          "Couldn't create thread " << name_ << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
    }
  }
  stopped_ = false;
  run_cond_.NotifyOne();
  LOG4CXX_DEBUG(
      logger_,
      "Thread " << name_ << " #" << handle_ << " started. pthread_result = " << pthread_result);
  pthread_attr_destroy(&attributes);
  return pthread_result == EOK;
}

void Thread::stop() {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoLock auto_lock(state_lock_);

  stopped_ = true;

  LOG4CXX_DEBUG(logger_, "Stopping thread #" << handle_
                << " \"" << name_ << " \"");

  if (delegate_ && isThreadRunning_) {
    delegate_->exitThreadMain();
  }

  LOG4CXX_DEBUG(logger_,
                "Stopped thread #" << handle_ << " \"" << name_ << " \"");
}

void Thread::join() {
  LOG4CXX_AUTO_TRACE(logger_);
  DCHECK(!pthread_equal(pthread_self(), handle_));

  stop();

  sync_primitives::AutoLock auto_lock(state_lock_);
  run_cond_.NotifyOne();
  if (isThreadRunning_) {
    if (!pthread_equal(pthread_self(), handle_)) {
      state_cond_.Wait(auto_lock);
    }
  }
}

Thread::~Thread() {
  finalized_ = true;
  stopped_ = true;
  join();
  pthread_join(handle_, NULL);
}

Thread* CreateThread(const char* name, ThreadDelegate* delegate) {
  Thread* thread = new Thread(name, delegate);
  delegate->set_thread(thread);
  return thread;
}

void DeleteThread(Thread* thread) {
  delete thread;
}

}  // namespace threads
<commit_msg>fix for pthread_join() crash in some platforms<commit_after>/*
 * Copyright (c) 2015, Ford Motor Company
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of the Ford Motor Company nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <signal.h>

#ifdef BUILD_TESTS
// Temporary fix for UnitTest until APPLINK-9987 is resolved
#include <unistd.h>
#endif

#include "utils/threads/thread.h"
#include "pthread.h"
#include "utils/atomic.h"
#include "utils/threads/thread_delegate.h"
#include "utils/logger.h"

#ifndef __QNXNTO__
const int EOK = 0;
#endif

#if defined(OS_POSIX)
const size_t THREAD_NAME_SIZE = 15;
#endif

namespace threads {

CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")

size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */

void Thread::cleanup(void* arg) {
  LOG4CXX_AUTO_TRACE(logger_);
  Thread* thread = reinterpret_cast<Thread*>(arg);
  sync_primitives::AutoLock auto_lock(thread->state_lock_);
  thread->isThreadRunning_ = false;
  thread->state_cond_.Broadcast();
}

void* Thread::threadFunc(void* arg) {
  // 0 - state_lock unlocked
  //     stopped   = 0
  //     running   = 0
  //     finalized = 0
  // 4 - state_lock unlocked
  //     stopped = 1
  //     running = 1
  //     finalized = 0
  // 5 - state_lock unlocked
  //     stopped = 1
  //     running = 1
  //     finalized = 1
  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  LOG4CXX_DEBUG(logger_,
                "Thread #" << pthread_self() << " started successfully");

  threads::Thread* thread = reinterpret_cast<Thread*>(arg);
  DCHECK(thread);

  pthread_cleanup_push(&cleanup, thread);

    thread->state_lock_.Acquire();
    thread->state_cond_.Broadcast();

    while (!thread->finalized_) {
      LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration");
      thread->run_cond_.Wait(thread->state_lock_);
      LOG4CXX_DEBUG(
          logger_,
          "Thread #" << pthread_self() << " execute. " << "stopped_ = " << thread->stopped_ << "; finalized_ = " << thread->finalized_);
      if (!thread->stopped_ && !thread->finalized_) {
        thread->isThreadRunning_ = true;
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_testcancel();

        thread->state_lock_.Release();
        thread->delegate_->threadMain();
        thread->state_lock_.Acquire();

        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        thread->isThreadRunning_ = false;
      }
      thread->state_cond_.Broadcast();
      LOG4CXX_DEBUG(logger_,
                    "Thread #" << pthread_self() << " finished iteration");
    }

    thread->state_lock_.Release();
    pthread_cleanup_pop(1);

  LOG4CXX_DEBUG(logger_,
                "Thread #" << pthread_self() << " exited successfully");
  return NULL;
}

void Thread::SetNameForId(const PlatformThreadHandle& thread_id,
                          std::string name) {
  if (name.size() > THREAD_NAME_SIZE)
    name.erase(THREAD_NAME_SIZE);
  const int rc = pthread_setname_np(thread_id, name.c_str());
  if (rc != EOK) {
    LOG4CXX_WARN(
        logger_,
        "Couldn't set pthread name \"" << name << "\", error code " << rc << " (" << strerror(rc) << ")");
  }
}

Thread::Thread(const char* name, ThreadDelegate* delegate)
    : name_(name ? name : "undefined"),
      delegate_(delegate),
      handle_(0),
      thread_options_(),
      isThreadRunning_(0),
      stopped_(false),
      finalized_(false),
      thread_created_(false) {
}

bool Thread::start() {
  return start(thread_options_);
}

PlatformThreadHandle Thread::CurrentId() {
  return pthread_self();
}

bool Thread::start(const ThreadOptions& options) {
  LOG4CXX_AUTO_TRACE(logger_);

  sync_primitives::AutoLock auto_lock(state_lock_);
  // 1 - state_lock locked
  //     stopped = 0
  //     running = 0

  if (!delegate_) {
    LOG4CXX_ERROR(logger_,
                  "Cannot start thread " << name_ << ": delegate is NULL");
    // 0 - state_lock unlocked
    return false;
  }

  if (isThreadRunning_) {
    LOG4CXX_TRACE(
        logger_,
        "EXIT thread "<< name_ << " #" << handle_ << " is already running");
    return true;
  }

  thread_options_ = options;

  pthread_attr_t attributes;
  int pthread_result = pthread_attr_init(&attributes);
  if (pthread_result != EOK) {
    LOG4CXX_WARN(
        logger_,
        "Couldn't init pthread attributes. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
  }

  if (!thread_options_.is_joinable()) {
    pthread_result = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
    if (pthread_result != EOK) {
      LOG4CXX_WARN(
          logger_,
          "Couldn't set detach state attribute. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
      thread_options_.is_joinable(false);
    }
  }

  const size_t stack_size = thread_options_.stack_size();
  if (stack_size >= Thread::kMinStackSize) {
    pthread_result = pthread_attr_setstacksize(&attributes, stack_size);
    if (pthread_result != EOK) {
      LOG4CXX_WARN(
          logger_,
          "Couldn't set stacksize = " << stack_size << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
    }
  }
  else {
    ThreadOptions thread_options_temp(Thread::kMinStackSize, thread_options_.is_joinable());
    thread_options_ = thread_options_temp;
  }

  if (!thread_created_) {
    // state_lock 1
    pthread_result = pthread_create(&handle_, &attributes, threadFunc, this);
    if (pthread_result == EOK) {
      LOG4CXX_DEBUG(logger_, "Created thread: " << name_);
      SetNameForId(handle_, name_);
      // state_lock 0
      // possible concurrencies: stop and threadFunc
      state_cond_.Wait(auto_lock);
      thread_created_ = true;
    } else {
      LOG4CXX_ERROR(
          logger_,
          "Couldn't create thread " << name_ << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")");
    }
  }
  stopped_ = false;
  run_cond_.NotifyOne();
  LOG4CXX_DEBUG(
      logger_,
      "Thread " << name_ << " #" << handle_ << " started. pthread_result = " << pthread_result);
  pthread_attr_destroy(&attributes);
  return pthread_result == EOK;
}

void Thread::stop() {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoLock auto_lock(state_lock_);

  stopped_ = true;

  LOG4CXX_DEBUG(logger_, "Stopping thread #" << handle_
                << " \"" << name_ << " \"");

  if (delegate_ && isThreadRunning_) {
    delegate_->exitThreadMain();
  }

  LOG4CXX_DEBUG(logger_,
                "Stopped thread #" << handle_ << " \"" << name_ << " \"");
}

void Thread::join() {
  LOG4CXX_AUTO_TRACE(logger_);
  DCHECK(!pthread_equal(pthread_self(), handle_));

  stop();

  sync_primitives::AutoLock auto_lock(state_lock_);
  run_cond_.NotifyOne();
  if (isThreadRunning_) {
    if (!pthread_equal(pthread_self(), handle_)) {
      state_cond_.Wait(auto_lock);
    }
  }
}

Thread::~Thread() {
  finalized_ = true;
  stopped_ = true;
  join();
  //in some platforms pthread_join behaviour is undefined when thread is not created(pthread_create) and call pthread_join.
  if(handle_) {
    pthread_join(handle_, NULL);
    handle_ = 0;
  }
}

Thread* CreateThread(const char* name, ThreadDelegate* delegate) {
  Thread* thread = new Thread(name, delegate);
  delegate->set_thread(thread);
  return thread;
}

void DeleteThread(Thread* thread) {
  delete thread;
}

}  // namespace threads
<|endoftext|>


<commit_before>#include "WorldEditorScene.hpp"
#include <imgui\imgui.h>
#include <Systems/EntityManager.hpp>
#include <Systems/AssetsAndComponentRelationsSystem.hpp>
#include <Systems/PhysicsSystem.hpp>
#include <AssetManagement/AssetManager.hh>

#include <Components/CameraComponent.hpp>

#include <Threads/ThreadManager.hpp>
#include <Threads/RenderThread.hpp>
#include <Threads/Commands/MainToPrepareCommands.hpp>
#include <Threads/Commands/ToRenderCommands.hpp>
#include <Threads/Tasks/BasicTasks.hpp>
#include <Threads/Tasks/ToRenderTasks.hpp>
#include <Components/FreeFlyComponent.hh>
#include <Systems/FreeFlyCamera.hh>
#include <Components/EntityRepresentation.hpp>
#include <Managers/ArchetypesEditorManager.hpp>
#include <EditorConfiguration.hpp>

#include "Systems/RenderCameraSystem.hpp"

namespace AGE
{
	const std::string WorldEditorScene::Name = "World Editor";

	WorldEditorScene::WorldEditorScene(AGE::Engine *engine)
		: AScene(engine)
	{
	}

	WorldEditorScene::~WorldEditorScene(void)
	{
	}

	bool WorldEditorScene::_userStart()
	{
		WE::EditorConfiguration::RefreshScenesDirectoryListing();
		getInstance<AGE::AssetsManager>()->setAssetsDirectory(WE::EditorConfiguration::GetCookedDirectory());

		addSystem<WE::AssetsAndComponentRelationsSystem>(0);
		addSystem<WE::EntityManager>(1);
		addSystem<FreeFlyCamera>(2);
		addSystem<PhysicsSystem>(3, Physics::EngineType::Bullet, getInstance<AGE::AssetsManager>());
		getInstance<Physics::PhysicsInterface>()->getWorld()->setGravity(0, 0, 0);
		addSystem<RenderCameraSystem>(1000);
		return true;
	}

	bool WorldEditorScene::_userUpdateBegin(float time)
	{
		return true;
	}

	bool WorldEditorScene::_userUpdateEnd(float time)
	{
		if (_displayWindow)
		{
			getInstance<AGE::WE::ArchetypeEditorManager>()->update(this);
		}
		// TODO
		//AGE::GetPrepareThread()->getQueue()->emplaceCommand<AGE::Commands::ToRender::RenderDrawLists>();
		return true;
	}

	void WorldEditorScene::updateMenu()
	{
		if (ImGui::BeginMenu("Scene"))
		{
			getSystem<WE::EntityManager>()->updateMenu();
			ImGui::EndMenu();
		}
		if (ImGui::BeginMenu("Archetypes"))
		{
			getInstance<AGE::WE::ArchetypeEditorManager>()->updateMenu();
			ImGui::EndMenu();
		}
	}
}<commit_msg>PhysX on AssetEditor<commit_after>#include "WorldEditorScene.hpp"
#include <imgui\imgui.h>
#include <Systems/EntityManager.hpp>
#include <Systems/AssetsAndComponentRelationsSystem.hpp>
#include <Systems/PhysicsSystem.hpp>
#include <AssetManagement/AssetManager.hh>

#include <Components/CameraComponent.hpp>

#include <Threads/ThreadManager.hpp>
#include <Threads/RenderThread.hpp>
#include <Threads/Commands/MainToPrepareCommands.hpp>
#include <Threads/Commands/ToRenderCommands.hpp>
#include <Threads/Tasks/BasicTasks.hpp>
#include <Threads/Tasks/ToRenderTasks.hpp>
#include <Components/FreeFlyComponent.hh>
#include <Systems/FreeFlyCamera.hh>
#include <Components/EntityRepresentation.hpp>
#include <Managers/ArchetypesEditorManager.hpp>
#include <EditorConfiguration.hpp>

#include "Systems/RenderCameraSystem.hpp"

namespace AGE
{
	const std::string WorldEditorScene::Name = "World Editor";

	WorldEditorScene::WorldEditorScene(AGE::Engine *engine)
		: AScene(engine)
	{
	}

	WorldEditorScene::~WorldEditorScene(void)
	{
	}

	bool WorldEditorScene::_userStart()
	{
		WE::EditorConfiguration::RefreshScenesDirectoryListing();
		getInstance<AGE::AssetsManager>()->setAssetsDirectory(WE::EditorConfiguration::GetCookedDirectory());

		addSystem<WE::AssetsAndComponentRelationsSystem>(0);
		addSystem<WE::EntityManager>(1);
		addSystem<FreeFlyCamera>(2);
		addSystem<PhysicsSystem>(3, Physics::EngineType::PhysX, getInstance<AGE::AssetsManager>());
		getInstance<Physics::PhysicsInterface>()->getWorld()->setGravity(0, 0, 0);
		addSystem<RenderCameraSystem>(1000);
		return true;
	}

	bool WorldEditorScene::_userUpdateBegin(float time)
	{
		return true;
	}

	bool WorldEditorScene::_userUpdateEnd(float time)
	{
		if (_displayWindow)
		{
			getInstance<AGE::WE::ArchetypeEditorManager>()->update(this);
		}
		// TODO
		//AGE::GetPrepareThread()->getQueue()->emplaceCommand<AGE::Commands::ToRender::RenderDrawLists>();
		return true;
	}

	void WorldEditorScene::updateMenu()
	{
		if (ImGui::BeginMenu("Scene"))
		{
			getSystem<WE::EntityManager>()->updateMenu();
			ImGui::EndMenu();
		}
		if (ImGui::BeginMenu("Archetypes"))
		{
			getInstance<AGE::WE::ArchetypeEditorManager>()->updateMenu();
			ImGui::EndMenu();
		}
	}
}<|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#include "arch/runtime/message_hub.hpp"

#include <math.h>
#include <unistd.h>

#include "config/args.hpp"
#include "arch/runtime/event_queue.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "logger.hpp"

// Set this to 1 if you would like some "unordered" messages to be unordered.
#ifndef NDEBUG
#define RDB_RELOOP_MESSAGES 0
#endif

linux_message_hub_t::linux_message_hub_t(linux_event_queue_t *queue, linux_thread_pool_t *thread_pool, int current_thread)
    : queue_(queue), thread_pool_(thread_pool), current_thread_(current_thread) {

    // We have to do this through dynamically, otherwise we might
    // allocate far too many file descriptors since this is what the
    // constructor of the system_event_t object (which is a member of
    // notify_t) does.
    notify_ = new notify_t[thread_pool_->n_threads];

    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Create notify fd for other cores that send work to us
        notify_[i].notifier_thread = i;
        notify_[i].parent = this;

        queue_->watch_resource(notify_[i].event.get_notify_fd(), poll_event_in, &notify_[i]);
    }
}

linux_message_hub_t::~linux_message_hub_t() {
    int res;

    for (int i = 0; i < thread_pool_->n_threads; i++) {
        guarantee(queues_[i].msg_local_list.empty());
    }

    guarantee(incoming_messages_.empty());

    delete[] notify_;
}

void linux_message_hub_t::do_store_message(unsigned int nthread, linux_thread_message_t *msg) {
    rassert(nthread < (unsigned)thread_pool_->n_threads);
    queues_[nthread].msg_local_list.push_back(msg);
}

// Collects a message for a given thread onto a local list.
void linux_message_hub_t::store_message(unsigned int nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    // We default to 1, not zero, to allow store_message_sometime messages to sometimes jump ahead of
    // store_message messages.
    msg->reloop_count_ = 1;
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

int rand_reloop_count() {
    int x;
    frexp(randint(10000) / 10000.0, &x);
    int ret = -x;
    rassert(ret >= 0);
    return ret;
}

void linux_message_hub_t::store_message_sometime(unsigned int nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    msg->reloop_count_ = rand_reloop_count();
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

void linux_message_hub_t::insert_external_message(linux_thread_message_t *msg) {
    incoming_messages_lock_.lock();
    incoming_messages_.push_back(msg);
    incoming_messages_lock_.unlock();

    // Wakey wakey eggs and bakey
    notify_[current_thread_].event.write(1);
}

void linux_message_hub_t::notify_t::on_event(int events) {

    if (events != poll_event_in) {
        logERR("Unexpected event mask: %d", events);
    }

    // Read from the event so level-triggered mechanism such as poll
    // don't pester us and use 100% cpu
    event.read();

    msg_list_t msg_list;

    parent->incoming_messages_lock_.lock();
    // Pull the messages
    //msg_list.append_and_clear(parent->thread_pool_->threads[parent->current_thread_]->message_hub);
    msg_list.append_and_clear(&parent->incoming_messages_);
    parent->incoming_messages_lock_.unlock();

#ifndef NDEBUG
    start_watchdog(); // Initialize watchdog before handling messages
#endif

    while (linux_thread_message_t *m = msg_list.head()) {
        msg_list.remove(m);
#ifndef NDEBUG
        if (m->reloop_count_ > 0) {
            --m->reloop_count_;
            parent->do_store_message(parent->current_thread_, m);
            continue;
        }
#endif

        m->on_thread_switch();

#ifndef NDEBUG
        pet_watchdog(); // Verify that each message completes in the acceptable time range
#endif
    }
}

// Pushes messages collected locally global lists available to all
// threads.
void linux_message_hub_t::push_messages() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Append the local list for ith thread to that thread's global
        // message list.
        thread_queue_t *queue = &queues_[i];
        if (!queue->msg_local_list.empty()) {
            // Transfer messages to the other core

            thread_pool_->threads[i]->message_hub.incoming_messages_lock_.lock();

            //We only need to do a wake up if the global
            bool do_wake_up = thread_pool_->threads[i]->message_hub.incoming_messages_.empty();

            thread_pool_->threads[i]->message_hub.incoming_messages_.append_and_clear(&queue->msg_local_list);

            thread_pool_->threads[i]->message_hub.incoming_messages_lock_.unlock();

            // Wakey wakey, perhaps eggs and bakey
            if (do_wake_up) {
                thread_pool_->threads[i]->message_hub.notify_[current_thread_].event.write(1);
            }
        }

        // TODO: we should use regular mutexes on single core CPU
        // instead of spinlocks
    }
}
<commit_msg>Removed unused variable res in linux_message_hub_t destructor.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#include "arch/runtime/message_hub.hpp"

#include <math.h>
#include <unistd.h>

#include "config/args.hpp"
#include "arch/runtime/event_queue.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "logger.hpp"

// Set this to 1 if you would like some "unordered" messages to be unordered.
#ifndef NDEBUG
#define RDB_RELOOP_MESSAGES 0
#endif

linux_message_hub_t::linux_message_hub_t(linux_event_queue_t *queue, linux_thread_pool_t *thread_pool, int current_thread)
    : queue_(queue), thread_pool_(thread_pool), current_thread_(current_thread) {

    // We have to do this through dynamically, otherwise we might
    // allocate far too many file descriptors since this is what the
    // constructor of the system_event_t object (which is a member of
    // notify_t) does.
    notify_ = new notify_t[thread_pool_->n_threads];

    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Create notify fd for other cores that send work to us
        notify_[i].notifier_thread = i;
        notify_[i].parent = this;

        queue_->watch_resource(notify_[i].event.get_notify_fd(), poll_event_in, &notify_[i]);
    }
}

linux_message_hub_t::~linux_message_hub_t() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        guarantee(queues_[i].msg_local_list.empty());
    }

    guarantee(incoming_messages_.empty());

    delete[] notify_;
}

void linux_message_hub_t::do_store_message(unsigned int nthread, linux_thread_message_t *msg) {
    rassert(nthread < (unsigned)thread_pool_->n_threads);
    queues_[nthread].msg_local_list.push_back(msg);
}

// Collects a message for a given thread onto a local list.
void linux_message_hub_t::store_message(unsigned int nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    // We default to 1, not zero, to allow store_message_sometime messages to sometimes jump ahead of
    // store_message messages.
    msg->reloop_count_ = 1;
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

int rand_reloop_count() {
    int x;
    frexp(randint(10000) / 10000.0, &x);
    int ret = -x;
    rassert(ret >= 0);
    return ret;
}

void linux_message_hub_t::store_message_sometime(unsigned int nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    msg->reloop_count_ = rand_reloop_count();
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

void linux_message_hub_t::insert_external_message(linux_thread_message_t *msg) {
    incoming_messages_lock_.lock();
    incoming_messages_.push_back(msg);
    incoming_messages_lock_.unlock();

    // Wakey wakey eggs and bakey
    notify_[current_thread_].event.write(1);
}

void linux_message_hub_t::notify_t::on_event(int events) {

    if (events != poll_event_in) {
        logERR("Unexpected event mask: %d", events);
    }

    // Read from the event so level-triggered mechanism such as poll
    // don't pester us and use 100% cpu
    event.read();

    msg_list_t msg_list;

    parent->incoming_messages_lock_.lock();
    // Pull the messages
    //msg_list.append_and_clear(parent->thread_pool_->threads[parent->current_thread_]->message_hub);
    msg_list.append_and_clear(&parent->incoming_messages_);
    parent->incoming_messages_lock_.unlock();

#ifndef NDEBUG
    start_watchdog(); // Initialize watchdog before handling messages
#endif

    while (linux_thread_message_t *m = msg_list.head()) {
        msg_list.remove(m);
#ifndef NDEBUG
        if (m->reloop_count_ > 0) {
            --m->reloop_count_;
            parent->do_store_message(parent->current_thread_, m);
            continue;
        }
#endif

        m->on_thread_switch();

#ifndef NDEBUG
        pet_watchdog(); // Verify that each message completes in the acceptable time range
#endif
    }
}

// Pushes messages collected locally global lists available to all
// threads.
void linux_message_hub_t::push_messages() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Append the local list for ith thread to that thread's global
        // message list.
        thread_queue_t *queue = &queues_[i];
        if (!queue->msg_local_list.empty()) {
            // Transfer messages to the other core

            thread_pool_->threads[i]->message_hub.incoming_messages_lock_.lock();

            //We only need to do a wake up if the global
            bool do_wake_up = thread_pool_->threads[i]->message_hub.incoming_messages_.empty();

            thread_pool_->threads[i]->message_hub.incoming_messages_.append_and_clear(&queue->msg_local_list);

            thread_pool_->threads[i]->message_hub.incoming_messages_lock_.unlock();

            // Wakey wakey, perhaps eggs and bakey
            if (do_wake_up) {
                thread_pool_->threads[i]->message_hub.notify_[current_thread_].event.write(1);
            }
        }

        // TODO: we should use regular mutexes on single core CPU
        // instead of spinlocks
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011, Robert Escriva
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of po6 nor the names of its contributors may be used
//       to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// C++
#include <tr1/functional>

// Google Test
#include <gtest/gtest.h>

// po6
#include "po6/threads/rwlock.h"
#include "po6/threads/thread.h"

#pragma GCC diagnostic ignored "-Wswitch-default"

class RwlockTestThread
{
    public:
        RwlockTestThread(po6::threads::rwlock* rwl, bool mode)
            : m_rwl(rwl)
            , m_mode(mode)
        {
        }

        ~RwlockTestThread()
        {
        }

        void operator () ()
        {
            for (int i = 0; i < 1000000; ++i)
            {
                if (m_mode)
                {
                    m_rwl->rdlock();
                }
                else
                {
                    m_rwl->wrlock();
                }

                m_rwl->unlock();
            }
        }

    private:
        RwlockTestThread(const RwlockTestThread&);

    private:
        RwlockTestThread& operator = (const RwlockTestThread&);

    private:
        po6::threads::rwlock* m_rwl;
        bool m_mode;
};

namespace
{

TEST(RwlockTest, CtorAndDtor)
{
    po6::threads::rwlock rwl;
}

TEST(RwlockTest, LockAndUnlock)
{
    po6::threads::rwlock rwl;
    rwl.rdlock();
    rwl.unlock();
    rwl.wrlock();
    rwl.unlock();
}

TEST(RwlockTest, TwoThreads)
{
    po6::threads::rwlock rwl;
    RwlockTestThread read(&rwl, true);
    RwlockTestThread write(&rwl, false);
    po6::threads::thread t1(std::tr1::ref(read));
    po6::threads::thread t2(std::tr1::ref(read));
    po6::threads::thread t3(std::tr1::ref(write));

    t1.start();
    t2.start();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
}

TEST(RwlockTest, Holding)
{
    po6::threads::rwlock rwl;

    {
        po6::threads::rwlock::rdhold h(&rwl);
    }

    {
        po6::threads::rwlock::wrhold h(&rwl);
    }

    rwl.unlock();
}

} // namespace
<commit_msg>Remove extraneous unlock in rwlock::holding.<commit_after>// Copyright (c) 2011, Robert Escriva
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of po6 nor the names of its contributors may be used
//       to endorse or promote products derived from this software without
//       specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// C++
#include <tr1/functional>

// Google Test
#include <gtest/gtest.h>

// po6
#include "po6/threads/rwlock.h"
#include "po6/threads/thread.h"

#pragma GCC diagnostic ignored "-Wswitch-default"

class RwlockTestThread
{
    public:
        RwlockTestThread(po6::threads::rwlock* rwl, bool mode)
            : m_rwl(rwl)
            , m_mode(mode)
        {
        }

        ~RwlockTestThread()
        {
        }

        void operator () ()
        {
            for (int i = 0; i < 1000000; ++i)
            {
                if (m_mode)
                {
                    m_rwl->rdlock();
                }
                else
                {
                    m_rwl->wrlock();
                }

                m_rwl->unlock();
            }
        }

    private:
        RwlockTestThread(const RwlockTestThread&);

    private:
        RwlockTestThread& operator = (const RwlockTestThread&);

    private:
        po6::threads::rwlock* m_rwl;
        bool m_mode;
};

namespace
{

TEST(RwlockTest, CtorAndDtor)
{
    po6::threads::rwlock rwl;
}

TEST(RwlockTest, LockAndUnlock)
{
    po6::threads::rwlock rwl;
    rwl.rdlock();
    rwl.unlock();
    rwl.wrlock();
    rwl.unlock();
}

TEST(RwlockTest, TwoThreads)
{
    po6::threads::rwlock rwl;
    RwlockTestThread read(&rwl, true);
    RwlockTestThread write(&rwl, false);
    po6::threads::thread t1(std::tr1::ref(read));
    po6::threads::thread t2(std::tr1::ref(read));
    po6::threads::thread t3(std::tr1::ref(write));

    t1.start();
    t2.start();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
}

TEST(RwlockTest, Holding)
{
    po6::threads::rwlock rwl;

    {
        po6::threads::rwlock::rdhold h(&rwl);
    }

    {
        po6::threads::rwlock::wrhold h(&rwl);
    }
}

} // namespace
<|endoftext|>


<commit_before>// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// Permission to use, copy, modify and distribute this software and its     *
// documentation strictly for non-commercial purposes is hereby granted     *
// without fee, provided that the above copyright notice appears in all     *
// copies and that both the copyright notice and this permission notice     *
// appear in the supporting documentation. The authors make no claims       *
// about the suitability of this software for any purpose. It is            *
// provided "as is" without express or implied warranty.                    *
//                                                                          *
//***************************************************************************

#include "AliHLTTPCCAStandaloneFramework.h"
#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCCAMerger.h"
#include "AliHLTTPCCAMergerOutput.h"
#include "AliHLTTPCCADataCompressor.h"
#include "AliHLTTPCCAMath.h"
#include "AliHLTTPCCAClusterData.h"
#include "TStopwatch.h"

//If not building GPU Code then build dummy functions to link against
#ifndef BUILD_GPU
AliHLTTPCCAGPUTracker::AliHLTTPCCAGPUTracker() : gpuTracker(), DebugLevel(0) {}
AliHLTTPCCAGPUTracker::~AliHLTTPCCAGPUTracker() {}
int AliHLTTPCCAGPUTracker::InitGPU() {return(0);}
//template <class T> inline T* AliHLTTPCCAGPUTracker::alignPointer(T* ptr, int alignment) {return(NULL);}
//bool AliHLTTPCCAGPUTracker::CUDA_FAILED_MSG(cudaError_t error) {return(true);}
//int AliHLTTPCCAGPUTracker::CUDASync() {return(1);}
//void AliHLTTPCCAGPUTracker::SetDebugLevel(int dwLevel, std::ostream *NewOutFile) {};
int AliHLTTPCCAGPUTracker::Reconstruct(AliHLTTPCCATracker* tracker) {return(1);}
int AliHLTTPCCAGPUTracker::ExitGPU() {return(0);}
#endif

AliHLTTPCCAStandaloneFramework &AliHLTTPCCAStandaloneFramework::Instance()
{
  // reference to static object
  static AliHLTTPCCAStandaloneFramework gAliHLTTPCCAStandaloneFramework;
  return gAliHLTTPCCAStandaloneFramework;
}

AliHLTTPCCAStandaloneFramework::AliHLTTPCCAStandaloneFramework()
    : fMerger(), fStatNEvents( 0 ), fUseGPUTracker(false), fGPUDebugLevel(0)
{
  //* constructor

  for ( int i = 0; i < 20; i++ ) {
    fLastTime[i] = 0;
    fStatTime[i] = 0;
  }
}

AliHLTTPCCAStandaloneFramework::AliHLTTPCCAStandaloneFramework( const AliHLTTPCCAStandaloneFramework& )
    : fMerger(), fStatNEvents( 0 )
{
  //* dummy
}

const AliHLTTPCCAStandaloneFramework &AliHLTTPCCAStandaloneFramework::operator=( const AliHLTTPCCAStandaloneFramework& ) const
{
  //* dummy
  return *this;
}

AliHLTTPCCAStandaloneFramework::~AliHLTTPCCAStandaloneFramework()
{
  //* destructor
}

void AliHLTTPCCAStandaloneFramework::StartDataReading( int guessForNumberOfClusters )
{
  //prepare for reading of the event

  int sliceGuess = 2 * guessForNumberOfClusters / fgkNSlices;

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fClusterData[i].StartReading( i, sliceGuess );
  }
}

void AliHLTTPCCAStandaloneFramework::FinishDataReading()
{
  // finish reading of the event

  /*static int event_number = 0;
  char filename[256];

  sprintf(filename, "events/event.%d.dump", event_number);
  printf("Dumping event into file %s\n", filename);
  std::ofstream outfile(filename, std::ofstream::binary);
  if (outfile.fail())
  {
    printf("Error opening event dump file\n");
    exit(1);
  }
  WriteEvent(outfile);
  if (outfile.fail())
  {
    printf("Error writing event dump file\n");
    exit(1);
  }
  outfile.close();

  sprintf(filename, "events/settings.%d.dump", event_number);
  outfile.open(filename);
  WriteSettings(outfile);
  outfile.close();

  event_number++;

  std::ifstream infile(filename, std::ifstream::binary);
  ReadEvent(infile);
  infile.close();*/

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fClusterData[i].FinishReading();
  }
}

//int
void AliHLTTPCCAStandaloneFramework::ProcessEvent()
{
  // perform the event reconstruction

  fStatNEvents++;

  TStopwatch timer0;
  TStopwatch timer1;

  if (!fUseGPUTracker || fGPUDebugLevel >= 3)
  {
	for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
	  fSliceTrackers[iSlice].ReadEvent( &( fClusterData[iSlice] ) );
      fSliceTrackers[iSlice].Reconstruct();
	}
	if (fGPUDebugLevel >= 2) printf("\n");
  }

  if (fUseGPUTracker)
  {
	  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
	    fSliceTrackers[iSlice].ReadEvent( &( fClusterData[iSlice] ) );
		if (fGPUTracker.Reconstruct(&fSliceTrackers[iSlice]))
		{
			printf("Error during GPU Reconstruction!!!\n");
			//return(1);
		}
	  }
	  if (fGPUDebugLevel >= 2) printf("\n");
  }

  timer1.Stop();
  TStopwatch timer2;

  fMerger.Clear();
  fMerger.SetSliceParam( fSliceTrackers[0].Param() );

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fMerger.SetSliceData( i, fSliceTrackers[i].Output() );
  }

  fMerger.Reconstruct();

  timer2.Stop();
  timer0.Stop();

  fLastTime[0] = timer0.CpuTime();
  fLastTime[1] = timer1.CpuTime();
  fLastTime[2] = timer2.CpuTime();

  for ( int i = 0; i < 3; i++ ) fStatTime[i] += fLastTime[i];

  //return(0);
}

void AliHLTTPCCAStandaloneFramework::WriteSettings( std::ostream &out ) const
{
  //* write settings to the file
  out << NSlices() << std::endl;
  for ( int iSlice = 0; iSlice < NSlices(); iSlice++ ) {
    fSliceTrackers[iSlice].Param().WriteSettings( out );
  }
}

void AliHLTTPCCAStandaloneFramework::ReadSettings( std::istream &in )
{
  //* Read settings from the file
  int nSlices = 0;
  in >> nSlices;
  for ( int iSlice = 0; iSlice < nSlices; iSlice++ ) {
    AliHLTTPCCAParam param;
    param.ReadSettings ( in );
    fSliceTrackers[iSlice].Initialize( param );
  }
}

void AliHLTTPCCAStandaloneFramework::WriteEvent( std::ostream &out ) const
{
  // write event to the file
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fClusterData[iSlice].WriteEvent( out );
  }
}

void AliHLTTPCCAStandaloneFramework::ReadEvent( std::istream &in )
{
  //* Read event from file
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fClusterData[iSlice].ReadEvent( in );
  }
}

void AliHLTTPCCAStandaloneFramework::WriteTracks( std::ostream &out ) const
{
  //* Write tracks to file

  for ( int i = 0; i < 20; i++ ) out << fLastTime[i] << std::endl;
  //fMerger.Output()->Write( out );
}

void AliHLTTPCCAStandaloneFramework::ReadTracks( std::istream &in )
{
  //* Read tracks  from file

  for ( int i = 0; i < 20; i++ ) {
    in >> fLastTime[i];
    fStatTime[i] += fLastTime[i];
  }
  //fMerger.Output()->Read( in );
}

int AliHLTTPCCAStandaloneFramework::InitGPU()
{
	if (fUseGPUTracker) return(1);
	int retVal = fGPUTracker.InitGPU();
	fUseGPUTracker = retVal == 0;
	return(retVal);
}

int AliHLTTPCCAStandaloneFramework::ExitGPU()
{
	if (!fUseGPUTracker) return(1);
	return(fGPUTracker.ExitGPU());
}

void AliHLTTPCCAStandaloneFramework::SetGPUDebugLevel(int Level, std::ostream *OutFile, std::ostream *GPUOutFile)
{
	fGPUTracker.SetDebugLevel(Level, GPUOutFile);
	fGPUDebugLevel = Level;
	for (int i = 0;i < fgkNSlices;i++)
	{
		fSliceTrackers[i].SetGPUDebugLevel(Level, OutFile);
	}
}
<commit_msg>implementation of GPUTracker::SetDebugLevel() added<commit_after>// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// Permission to use, copy, modify and distribute this software and its     *
// documentation strictly for non-commercial purposes is hereby granted     *
// without fee, provided that the above copyright notice appears in all     *
// copies and that both the copyright notice and this permission notice     *
// appear in the supporting documentation. The authors make no claims       *
// about the suitability of this software for any purpose. It is            *
// provided "as is" without express or implied warranty.                    *
//                                                                          *
//***************************************************************************

#include "AliHLTTPCCAStandaloneFramework.h"
#include "AliHLTTPCCATrackParam.h"
#include "AliHLTTPCCAMerger.h"
#include "AliHLTTPCCAMergerOutput.h"
#include "AliHLTTPCCADataCompressor.h"
#include "AliHLTTPCCAMath.h"
#include "AliHLTTPCCAClusterData.h"
#include "TStopwatch.h"

//If not building GPU Code then build dummy functions to link against
#ifndef BUILD_GPU
AliHLTTPCCAGPUTracker::AliHLTTPCCAGPUTracker() : gpuTracker(), DebugLevel(0) {}
AliHLTTPCCAGPUTracker::~AliHLTTPCCAGPUTracker() {}
int AliHLTTPCCAGPUTracker::InitGPU() {return(0);}
//template <class T> inline T* AliHLTTPCCAGPUTracker::alignPointer(T* ptr, int alignment) {return(NULL);}
//bool AliHLTTPCCAGPUTracker::CUDA_FAILED_MSG(cudaError_t error) {return(true);}
//int AliHLTTPCCAGPUTracker::CUDASync() {return(1);}
void AliHLTTPCCAGPUTracker::SetDebugLevel(int dwLevel, std::ostream *NewOutFile) {};
int AliHLTTPCCAGPUTracker::Reconstruct(AliHLTTPCCATracker* tracker) {return(1);}
int AliHLTTPCCAGPUTracker::ExitGPU() {return(0);}
#endif

AliHLTTPCCAStandaloneFramework &AliHLTTPCCAStandaloneFramework::Instance()
{
  // reference to static object
  static AliHLTTPCCAStandaloneFramework gAliHLTTPCCAStandaloneFramework;
  return gAliHLTTPCCAStandaloneFramework;
}

AliHLTTPCCAStandaloneFramework::AliHLTTPCCAStandaloneFramework()
    : fMerger(), fStatNEvents( 0 ), fUseGPUTracker(false), fGPUDebugLevel(0)
{
  //* constructor

  for ( int i = 0; i < 20; i++ ) {
    fLastTime[i] = 0;
    fStatTime[i] = 0;
  }
}

AliHLTTPCCAStandaloneFramework::AliHLTTPCCAStandaloneFramework( const AliHLTTPCCAStandaloneFramework& )
    : fMerger(), fStatNEvents( 0 )
{
  //* dummy
}

const AliHLTTPCCAStandaloneFramework &AliHLTTPCCAStandaloneFramework::operator=( const AliHLTTPCCAStandaloneFramework& ) const
{
  //* dummy
  return *this;
}

AliHLTTPCCAStandaloneFramework::~AliHLTTPCCAStandaloneFramework()
{
  //* destructor
}

void AliHLTTPCCAStandaloneFramework::StartDataReading( int guessForNumberOfClusters )
{
  //prepare for reading of the event

  int sliceGuess = 2 * guessForNumberOfClusters / fgkNSlices;

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fClusterData[i].StartReading( i, sliceGuess );
  }
}

void AliHLTTPCCAStandaloneFramework::FinishDataReading()
{
  // finish reading of the event

  /*static int event_number = 0;
  char filename[256];

  sprintf(filename, "events/event.%d.dump", event_number);
  printf("Dumping event into file %s\n", filename);
  std::ofstream outfile(filename, std::ofstream::binary);
  if (outfile.fail())
  {
    printf("Error opening event dump file\n");
    exit(1);
  }
  WriteEvent(outfile);
  if (outfile.fail())
  {
    printf("Error writing event dump file\n");
    exit(1);
  }
  outfile.close();

  sprintf(filename, "events/settings.%d.dump", event_number);
  outfile.open(filename);
  WriteSettings(outfile);
  outfile.close();

  event_number++;

  std::ifstream infile(filename, std::ifstream::binary);
  ReadEvent(infile);
  infile.close();*/

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fClusterData[i].FinishReading();
  }
}

//int
void AliHLTTPCCAStandaloneFramework::ProcessEvent()
{
  // perform the event reconstruction

  fStatNEvents++;

  TStopwatch timer0;
  TStopwatch timer1;

  if (!fUseGPUTracker || fGPUDebugLevel >= 3)
  {
	for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
	  fSliceTrackers[iSlice].ReadEvent( &( fClusterData[iSlice] ) );
      fSliceTrackers[iSlice].Reconstruct();
	}
	if (fGPUDebugLevel >= 2) printf("\n");
  }

  if (fUseGPUTracker)
  {
	  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
	    fSliceTrackers[iSlice].ReadEvent( &( fClusterData[iSlice] ) );
		if (fGPUTracker.Reconstruct(&fSliceTrackers[iSlice]))
		{
			printf("Error during GPU Reconstruction!!!\n");
			//return(1);
		}
	  }
	  if (fGPUDebugLevel >= 2) printf("\n");
  }

  timer1.Stop();
  TStopwatch timer2;

  fMerger.Clear();
  fMerger.SetSliceParam( fSliceTrackers[0].Param() );

  for ( int i = 0; i < fgkNSlices; i++ ) {
    fMerger.SetSliceData( i, fSliceTrackers[i].Output() );
  }

  fMerger.Reconstruct();

  timer2.Stop();
  timer0.Stop();

  fLastTime[0] = timer0.CpuTime();
  fLastTime[1] = timer1.CpuTime();
  fLastTime[2] = timer2.CpuTime();

  for ( int i = 0; i < 3; i++ ) fStatTime[i] += fLastTime[i];

  //return(0);
}

void AliHLTTPCCAStandaloneFramework::WriteSettings( std::ostream &out ) const
{
  //* write settings to the file
  out << NSlices() << std::endl;
  for ( int iSlice = 0; iSlice < NSlices(); iSlice++ ) {
    fSliceTrackers[iSlice].Param().WriteSettings( out );
  }
}

void AliHLTTPCCAStandaloneFramework::ReadSettings( std::istream &in )
{
  //* Read settings from the file
  int nSlices = 0;
  in >> nSlices;
  for ( int iSlice = 0; iSlice < nSlices; iSlice++ ) {
    AliHLTTPCCAParam param;
    param.ReadSettings ( in );
    fSliceTrackers[iSlice].Initialize( param );
  }
}

void AliHLTTPCCAStandaloneFramework::WriteEvent( std::ostream &out ) const
{
  // write event to the file
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fClusterData[iSlice].WriteEvent( out );
  }
}

void AliHLTTPCCAStandaloneFramework::ReadEvent( std::istream &in )
{
  //* Read event from file
  for ( int iSlice = 0; iSlice < fgkNSlices; iSlice++ ) {
    fClusterData[iSlice].ReadEvent( in );
  }
}

void AliHLTTPCCAStandaloneFramework::WriteTracks( std::ostream &out ) const
{
  //* Write tracks to file

  for ( int i = 0; i < 20; i++ ) out << fLastTime[i] << std::endl;
  //fMerger.Output()->Write( out );
}

void AliHLTTPCCAStandaloneFramework::ReadTracks( std::istream &in )
{
  //* Read tracks  from file

  for ( int i = 0; i < 20; i++ ) {
    in >> fLastTime[i];
    fStatTime[i] += fLastTime[i];
  }
  //fMerger.Output()->Read( in );
}

int AliHLTTPCCAStandaloneFramework::InitGPU()
{
	if (fUseGPUTracker) return(1);
	int retVal = fGPUTracker.InitGPU();
	fUseGPUTracker = retVal == 0;
	return(retVal);
}

int AliHLTTPCCAStandaloneFramework::ExitGPU()
{
	if (!fUseGPUTracker) return(1);
	return(fGPUTracker.ExitGPU());
}

void AliHLTTPCCAStandaloneFramework::SetGPUDebugLevel(int Level, std::ostream *OutFile, std::ostream *GPUOutFile)
{
	fGPUTracker.SetDebugLevel(Level, GPUOutFile);
	fGPUDebugLevel = Level;
	for (int i = 0;i < fgkNSlices;i++)
	{
		fSliceTrackers[i].SetGPUDebugLevel(Level, OutFile);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 */

#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__

#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"

namespace SparcISA {

// This contains all of the common elements of a SPARC Linux process which
// are not shared by other operating systems. The rest come from the common
// SPARC process class.
class SparcLinuxProcess
{
  public:
     /// Array of syscall descriptors, indexed by call number.
    static SyscallDesc syscallDescs[];

     /// Array of 32 bit compatibility syscall descriptors,
     /// indexed by call number.
    static SyscallDesc syscall32Descs[];

    SyscallDesc* getDesc(int callnum);
    SyscallDesc* getDesc32(int callnum);

    static const int Num_Syscall_Descs;
    static const int Num_Syscall32_Descs;
};

/// A process with emulated SPARC/Linux syscalls.
class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process
{
  public:
    /// Constructor.
    Sparc32LinuxProcess(ProcessParams * params, ObjectFile *objFile);

    SyscallDesc*
    getDesc(int callnum)
    {
        return SparcLinuxProcess::getDesc32(callnum);
    }

    void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};

/// A process with emulated 32 bit SPARC/Linux syscalls.
class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64Process
{
  public:
    /// Constructor.
    Sparc64LinuxProcess(ProcessParams * params, ObjectFile *objFile);

    SyscallDesc*
    getDesc(int callnum)
    {
        return SparcLinuxProcess::getDesc(callnum);
    }

    void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};

SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
                            Process *p, ThreadContext *tc);

} // namespace SparcISA
#endif // __SPARC_LINUX_PROCESS_HH__
<commit_msg>sparc: Fix the getresuidFunc prototype.<commit_after>/*
 * Copyright (c) 2003-2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 */

#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__

#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"

namespace SparcISA {

// This contains all of the common elements of a SPARC Linux process which
// are not shared by other operating systems. The rest come from the common
// SPARC process class.
class SparcLinuxProcess
{
  public:
     /// Array of syscall descriptors, indexed by call number.
    static SyscallDesc syscallDescs[];

     /// Array of 32 bit compatibility syscall descriptors,
     /// indexed by call number.
    static SyscallDesc syscall32Descs[];

    SyscallDesc* getDesc(int callnum);
    SyscallDesc* getDesc32(int callnum);

    static const int Num_Syscall_Descs;
    static const int Num_Syscall32_Descs;
};

/// A process with emulated SPARC/Linux syscalls.
class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process
{
  public:
    /// Constructor.
    Sparc32LinuxProcess(ProcessParams * params, ObjectFile *objFile);

    SyscallDesc*
    getDesc(int callnum)
    {
        return SparcLinuxProcess::getDesc32(callnum);
    }

    void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};

/// A process with emulated 32 bit SPARC/Linux syscalls.
class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64Process
{
  public:
    /// Constructor.
    Sparc64LinuxProcess(ProcessParams * params, ObjectFile *objFile);

    SyscallDesc*
    getDesc(int callnum)
    {
        return SparcLinuxProcess::getDesc(callnum);
    }

    void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};

SyscallReturn getresuidFunc(SyscallDesc *desc, int num, ThreadContext *tc);

} // namespace SparcISA
#endif // __SPARC_LINUX_PROCESS_HH__
<|endoftext|>


<commit_before>#include "cLuaCommandBinder.h"
#include "cMCLogger.h"
#include "cPlayer.h"
#include "cPlugin_Lua.h"

#include "tolua++.h"

extern std::vector<std::string> StringSplit(std::string str, std::string delim);
extern bool report_errors(lua_State* lua, int status);

cLuaCommandBinder::cLuaCommandBinder()
{
}

cLuaCommandBinder::~cLuaCommandBinder()
{
}

void cLuaCommandBinder::ClearBindings()
{
	m_BoundCommands.clear();
}

void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
{
	for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); )
	{
		if( itr->second.Plugin == a_Plugin )
		{
			LOGINFO("Unbinding %s ", itr->first.c_str( ) );
			luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference
			CommandMap::iterator eraseme = itr;
			++itr;
			m_BoundCommands.erase( eraseme );
			continue;
		}
		++itr;
	}
}

bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference )
{
	if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() )
	{
		LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() );
		return false;
	}
	LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() );
	m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission );
	return true;
}

bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
{
	std::vector<std::string> Split = StringSplit( a_Command, " ");
	CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] );
	if( FoundCommand != m_BoundCommands.end() )
	{
		const BoundFunction & func = FoundCommand->second;
		if( func.Permission.size() > 0 )
		{
			if( !a_Player->HasPermission( func.Permission.c_str() ) )
			{
				return false;
			}
		}

		// For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go
		lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX);
			lua_pushstring(func.LuaState, "self");
			tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" );
			lua_rawset(func.LuaState, -3);
		lua_pop(func.LuaState, 1);

		LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) );
		lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref()

		// Push the split
		LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) );
		lua_createtable(func.LuaState, Split.size(), 0);
		int newTable = lua_gettop(func.LuaState);
		int index = 1;
		std::vector<std::string>::const_iterator iter = Split.begin();
		while(iter != Split.end()) {
			tolua_pushstring( func.LuaState, (*iter).c_str() );
			lua_rawseti(func.LuaState, newTable, index);
			++iter;
			++index;
		}
		LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) );
		// Push player
		tolua_pushusertype( func.LuaState, a_Player, "cPlayer" );
		LOGINFO("Calling bound function! :D");
		int s = lua_pcall(func.LuaState, 2, 1, 0);
		if( report_errors( func.LuaState, s ) )
		{
			LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) );
			return false;
		}
		bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0);
		lua_pop(func.LuaState, 1); // Pop return value
		LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) );
		return RetVal;
	}
	return false;
}
<commit_msg>Fixed crash when client only sends a space in the chat<commit_after>#include "cLuaCommandBinder.h"
#include "cMCLogger.h"
#include "cPlayer.h"
#include "cPlugin_Lua.h"

#include "tolua++.h"

extern std::vector<std::string> StringSplit(std::string str, std::string delim);
extern bool report_errors(lua_State* lua, int status);

cLuaCommandBinder::cLuaCommandBinder()
{
}

cLuaCommandBinder::~cLuaCommandBinder()
{
}

void cLuaCommandBinder::ClearBindings()
{
	m_BoundCommands.clear();
}

void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
{
	for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); )
	{
		if( itr->second.Plugin == a_Plugin )
		{
			LOGINFO("Unbinding %s ", itr->first.c_str( ) );
			luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference
			CommandMap::iterator eraseme = itr;
			++itr;
			m_BoundCommands.erase( eraseme );
			continue;
		}
		++itr;
	}
}

bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference )
{
	if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() )
	{
		LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() );
		return false;
	}
	LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() );
	m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission );
	return true;
}

bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
{
	std::vector<std::string> Split = StringSplit( a_Command, " ");
	if( Split.size() == 0 ) return false;

	CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] );
	if( FoundCommand != m_BoundCommands.end() )
	{
		const BoundFunction & func = FoundCommand->second;
		if( func.Permission.size() > 0 )
		{
			if( !a_Player->HasPermission( func.Permission.c_str() ) )
			{
				return false;
			}
		}

		// For enabling 'self' in the function, it's kind of a hack I'm not sure this is the way to go
		lua_pushvalue(func.LuaState, LUA_GLOBALSINDEX);
			lua_pushstring(func.LuaState, "self");
			tolua_pushusertype( func.LuaState, func.Plugin, "cPlugin" );
			lua_rawset(func.LuaState, -3);
		lua_pop(func.LuaState, 1);

		LOGINFO("1. Stack size: %i", lua_gettop(func.LuaState) );
		lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref()

		// Push the split
		LOGINFO("2. Stack size: %i", lua_gettop(func.LuaState) );
		lua_createtable(func.LuaState, Split.size(), 0);
		int newTable = lua_gettop(func.LuaState);
		int index = 1;
		std::vector<std::string>::const_iterator iter = Split.begin();
		while(iter != Split.end()) {
			tolua_pushstring( func.LuaState, (*iter).c_str() );
			lua_rawseti(func.LuaState, newTable, index);
			++iter;
			++index;
		}
		LOGINFO("3. Stack size: %i", lua_gettop(func.LuaState) );
		// Push player
		tolua_pushusertype( func.LuaState, a_Player, "cPlayer" );
		LOGINFO("Calling bound function! :D");
		int s = lua_pcall(func.LuaState, 2, 1, 0);
		if( report_errors( func.LuaState, s ) )
		{
			LOGINFO("error. Stack size: %i", lua_gettop(func.LuaState) );
			return false;
		}
		bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0);
		lua_pop(func.LuaState, 1); // Pop return value
		LOGINFO("ok. Stack size: %i", lua_gettop(func.LuaState) );
		return RetVal;
	}
	return false;
}
<|endoftext|>


<commit_before>#include "graph.h"
#include "util.h"

EdgeEndStar::EdgeEndStar(){
	ptInAreaLocation[0]=Location::UNDEF;
	ptInAreaLocation[1]=Location::UNDEF;
	edgeMap=new map<EdgeEnd*,void*,EdgeEndLT>();
	edgeList=new vector<EdgeEnd*>();
}

EdgeEndStar::~EdgeEndStar(){
	delete edgeMap;
	delete edgeList;
}

/**
 * Insert an EdgeEnd into the map, and clear the edgeList cache,
 * since the list of edges has now changed
 */
void EdgeEndStar::insertEdgeEnd(EdgeEnd *e,void* obj){
	edgeMap->insert(pair<EdgeEnd*,void*>(e,obj));
//	(*edgeMap)[e]=obj;
	edgeList=NULL;  // edge list has changed - clear the cache
}

/**
 * @return the coordinate for the node this star is based at
 */
Coordinate EdgeEndStar::getCoordinate(){
	vector<EdgeEnd*>::iterator it=getIterator();
	if (it==NULL) return Coordinate::getNull();
	EdgeEnd *e=*it;
	return e->getCoordinate();
}

int EdgeEndStar::getDegree(){
	return (int)edgeMap->size();
}

vector<EdgeEnd*>* EdgeEndStar::getEdges() {
	map<EdgeEnd*,void*,EdgeEndLT>::iterator mapIter;
	if (edgeList==NULL) {
		edgeList=new vector<EdgeEnd*>();
		for(mapIter=edgeMap->begin();mapIter!=edgeMap->end();mapIter++) {
//			edgeList->push_back(mapIter->first);
			EdgeEnd *e=(EdgeEnd*) mapIter->second;
			edgeList->push_back(e);
		}
	}
	return edgeList;
}

vector<EdgeEnd*>::iterator EdgeEndStar::getIterator(){
	return getEdges()->begin();
}

EdgeEnd* EdgeEndStar::getNextCW(EdgeEnd *ee){
	getEdges();
	int i;
	for(unsigned int j=0;j<edgeList->size();j++)
    {
//        if (ee->compareTo( *(edgeList->at(j)))==0) {
        if (ee->compareTo( *((*edgeList)[j]) )==0) {
			i=j;
			break;
		}
    }
	int iNextCW=i-1;
	if (i==0)
		iNextCW=(int)edgeList->size()-1;
	return (*edgeList)[iNextCW];
}

void EdgeEndStar::computeLabelling(vector<GeometryGraph*> *geom){
	computeEdgeEndLabels();
	// Propagate side labels  around the edges in the star
	// for each parent Geometry
	propagateSideLabels(0);
	propagateSideLabels(1);

	/**
	* If there are edges that still have null labels for a geometry
	* this must be because there are no area edges for that geometry incident on this node.
	* In this case, to label the edge for that geometry we must test whether the
	* edge is in the interior of the geometry.
	* To do this it suffices to determine whether the node for the edge is in the interior of an area.
	* If so, the edge has location INTERIOR for the geometry.
	* In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge
	* has the location EXTERIOR for the geometry.
	*

	* Note that the edge cannot be on the BOUNDARY of the geometry, since then
	* there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY
	* and this edge would have been labelled in the previous step.
	*

	* This code causes a problem when dimensional collapses are present, since it may try and
	* determine the location of a node where a dimensional collapse has occurred.
	* The point should be considered to be on the EXTERIOR
	* of the polygon, but locate() will return INTERIOR, since it is passed
	* the original Geometry, not the collapsed version.
	*
	* If there are incident edges which are Line edges labelled BOUNDARY,
	* then they must be edges resulting from dimensional collapses.
	* In this case the other edges can be labelled EXTERIOR for this Geometry.
	*
	* MD 8/11/01 - NOT TRUE!  The collapsed edges may in fact be in the interior of the Geometry,
	* which means the other edges should be labelled INTERIOR for this Geometry.
	* Not sure how solve this...  Possibly labelling needs to be split into several phases:
	* area label propagation, symLabel merging, then finally null label resolution.
	*/
	bool hasDimensionalCollapseEdge[2]={false,false};
    vector<EdgeEnd*>::iterator it;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		for(int geomi=0; geomi<2; geomi++) {
			if (label->isLine(geomi) && label->getLocation(geomi)==Location::BOUNDARY)
				hasDimensionalCollapseEdge[geomi]=true;
		}
	}
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		for(int geomi=0;geomi<2;geomi++){
			if (label->isAnyNull(geomi)) {
				int loc=Location::UNDEF;
				if (hasDimensionalCollapseEdge[geomi]){
					loc=Location::EXTERIOR;
				}else {
					Coordinate p(e->getCoordinate());
					loc=getLocation(geomi,p,geom);
				}
				label->setAllLocationsIfNull(geomi,loc);
			}
		}
	}
}

void EdgeEndStar::computeEdgeEndLabels(){
	// Compute edge label for each EdgeEnd
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		e->computeLabel();
	}
}

int EdgeEndStar::getLocation(int geomIndex,Coordinate p,vector<GeometryGraph*> *geom){
	// compute location only on demand
	if (ptInAreaLocation[geomIndex]==Location::UNDEF) {
//		ptInAreaLocation[geomIndex]=SimplePointInAreaLocator::locate(p,(geom->at(geomIndex))->getGeometry());
        ptInAreaLocation[geomIndex]=SimplePointInAreaLocator::locate(p,(*geom)[geomIndex]->getGeometry());
	}
	return ptInAreaLocation[geomIndex];
}

bool EdgeEndStar::isAreaLabelsConsistent(){
	computeEdgeEndLabels();
	return checkAreaLabelsConsistent(0);
}

bool EdgeEndStar::checkAreaLabelsConsistent(int geomIndex){
	// Since edges are stored in CCW order around the node,
	// As we move around the ring we move from the right to the left side of the edge
	vector<EdgeEnd*> *edges=getEdges();
	// if no edges, trivially consistent
	if (edges->size()<=0)
		return true;
	// initialize startLoc to location of last L side (if any)
	int lastEdgeIndex=(int)edges->size()-1;
	Label *startLabel=((*edgeList)[lastEdgeIndex])->getLabel();
	int startLoc=startLabel->getLocation(geomIndex,Position::LEFT);
	Assert::isTrue(startLoc!=Location::UNDEF, "Found unlabelled area edge");
	int currLoc=startLoc;
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *eLabel=e->getLabel();
		// we assume that we are only checking a area
		Assert::isTrue(eLabel->isArea(geomIndex), "Found non-area edge");
		int leftLoc=eLabel->getLocation(geomIndex,Position::LEFT);
		int rightLoc=eLabel->getLocation(geomIndex,Position::RIGHT);
		// check that edge is really a boundary between inside and outside!
		if (leftLoc==rightLoc) {
			return false;
		}
		// check side location conflict
		//Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr);
		if (rightLoc!=currLoc) {
			return false;
		}
		currLoc=leftLoc;
	}
	return true;
}

void EdgeEndStar::propagateSideLabels(int geomIndex){
	// Since edges are stored in CCW order around the node,
	// As we move around the ring we move from the right to the left side of the edge
	int startLoc=Location::UNDEF ;
	// initialize loc to location of last L side (if any)
    vector<EdgeEnd*>::iterator it;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		if (label->isArea(geomIndex) && label->getLocation(geomIndex,Position::LEFT)!=Location::UNDEF)
			startLoc=label->getLocation(geomIndex,Position::LEFT);
	}
		// no labelled sides found, so no labels to propagate
	if (startLoc==Location::UNDEF) return;
	int currLoc=startLoc;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		// set null ON values to be in current location
		if (label->getLocation(geomIndex,Position::ON)==Location::UNDEF)
			label->setLocation(geomIndex,Position::ON,currLoc);
		// set side labels (if any)
		// if (label.isArea()) {   //ORIGINAL
		if (label->isArea(geomIndex)) {
			int leftLoc=label->getLocation(geomIndex,Position::LEFT);
			int rightLoc=label->getLocation(geomIndex,Position::RIGHT);
			// if there is a right location, that is the next location to propagate
			if (rightLoc!=Location::UNDEF) {
				string locStr="(at " + (e->getCoordinate()).toString() + ")";
				//Debug.print(rightLoc != currLoc, this);
				Assert::isTrue(rightLoc==currLoc, "side location conflict " + locStr);
				Assert::isTrue(leftLoc!=Location::UNDEF, "found single null side " + locStr);
				currLoc=leftLoc;
			} else {
				/** RHS is null - LHS must be null too.
				 *  This must be an edge from the other geometry, which has no location
				 *  labelling for this geometry.  This edge must lie wholly inside or outside
				 *  the other geometry (which is determined by the current location).
				 *  Assign both sides to be the current location.
				 */
				Assert::isTrue(label->getLocation(geomIndex,Position::LEFT)==Location::UNDEF, "found single null side");
				label->setLocation(geomIndex,Position::RIGHT, currLoc);
				label->setLocation(geomIndex,Position::LEFT, currLoc);
			}
		}
	}
}

int EdgeEndStar::findIndex(EdgeEnd *eSearch){
	getIterator();   // force edgelist to be computed
	for (unsigned int i=0; i<edgeList->size(); i++ ) {
		EdgeEnd *e=(*edgeList)[i];
		if (e->compareTo(*eSearch)) return i;
	}
	return -1;
}

string EdgeEndStar::print(){
	string out="EdgeEndStar:   " + getCoordinate().toString()+"\n";
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		out+=e->print();
	}
	return out;
}<commit_msg>Remove NULL test.<commit_after>#include "graph.h"
#include "util.h"

EdgeEndStar::EdgeEndStar(){
	ptInAreaLocation[0]=Location::UNDEF;
	ptInAreaLocation[1]=Location::UNDEF;
	edgeMap=new map<EdgeEnd*,void*,EdgeEndLT>();
	edgeList=new vector<EdgeEnd*>();
}

EdgeEndStar::~EdgeEndStar(){
	delete edgeMap;
	delete edgeList;
}

/**
 * Insert an EdgeEnd into the map, and clear the edgeList cache,
 * since the list of edges has now changed
 */
void EdgeEndStar::insertEdgeEnd(EdgeEnd *e,void* obj){
	edgeMap->insert(pair<EdgeEnd*,void*>(e,obj));
//	(*edgeMap)[e]=obj;
	edgeList=NULL;  // edge list has changed - clear the cache
}

/**
 * @return the coordinate for the node this star is based at
 */
Coordinate EdgeEndStar::getCoordinate(){
	if ( getEdges()->size() == 0 )
		return Coordinate::getNull();
	vector<EdgeEnd*>::iterator it=getIterator();
	EdgeEnd *e=*it;
	return e->getCoordinate();
}

int EdgeEndStar::getDegree(){
	return (int)edgeMap->size();
}

vector<EdgeEnd*>* EdgeEndStar::getEdges() {
	map<EdgeEnd*,void*,EdgeEndLT>::iterator mapIter;
	if (edgeList==NULL) {
		edgeList=new vector<EdgeEnd*>();
		for(mapIter=edgeMap->begin();mapIter!=edgeMap->end();mapIter++) {
//			edgeList->push_back(mapIter->first);
			EdgeEnd *e=(EdgeEnd*) mapIter->second;
			edgeList->push_back(e);
		}
	}
	return edgeList;
}

vector<EdgeEnd*>::iterator EdgeEndStar::getIterator(){
	return getEdges()->begin();
}

EdgeEnd* EdgeEndStar::getNextCW(EdgeEnd *ee){
	getEdges();
	int i;
	for(unsigned int j=0;j<edgeList->size();j++)
    {
//        if (ee->compareTo( *(edgeList->at(j)))==0) {
        if (ee->compareTo( *((*edgeList)[j]) )==0) {
			i=j;
			break;
		}
    }
	int iNextCW=i-1;
	if (i==0)
		iNextCW=(int)edgeList->size()-1;
	return (*edgeList)[iNextCW];
}

void EdgeEndStar::computeLabelling(vector<GeometryGraph*> *geom){
	computeEdgeEndLabels();
	// Propagate side labels  around the edges in the star
	// for each parent Geometry
	propagateSideLabels(0);
	propagateSideLabels(1);

	/**
	* If there are edges that still have null labels for a geometry
	* this must be because there are no area edges for that geometry incident on this node.
	* In this case, to label the edge for that geometry we must test whether the
	* edge is in the interior of the geometry.
	* To do this it suffices to determine whether the node for the edge is in the interior of an area.
	* If so, the edge has location INTERIOR for the geometry.
	* In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge
	* has the location EXTERIOR for the geometry.
	*

	* Note that the edge cannot be on the BOUNDARY of the geometry, since then
	* there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY
	* and this edge would have been labelled in the previous step.
	*

	* This code causes a problem when dimensional collapses are present, since it may try and
	* determine the location of a node where a dimensional collapse has occurred.
	* The point should be considered to be on the EXTERIOR
	* of the polygon, but locate() will return INTERIOR, since it is passed
	* the original Geometry, not the collapsed version.
	*
	* If there are incident edges which are Line edges labelled BOUNDARY,
	* then they must be edges resulting from dimensional collapses.
	* In this case the other edges can be labelled EXTERIOR for this Geometry.
	*
	* MD 8/11/01 - NOT TRUE!  The collapsed edges may in fact be in the interior of the Geometry,
	* which means the other edges should be labelled INTERIOR for this Geometry.
	* Not sure how solve this...  Possibly labelling needs to be split into several phases:
	* area label propagation, symLabel merging, then finally null label resolution.
	*/
	bool hasDimensionalCollapseEdge[2]={false,false};
    vector<EdgeEnd*>::iterator it;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		for(int geomi=0; geomi<2; geomi++) {
			if (label->isLine(geomi) && label->getLocation(geomi)==Location::BOUNDARY)
				hasDimensionalCollapseEdge[geomi]=true;
		}
	}
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		for(int geomi=0;geomi<2;geomi++){
			if (label->isAnyNull(geomi)) {
				int loc=Location::UNDEF;
				if (hasDimensionalCollapseEdge[geomi]){
					loc=Location::EXTERIOR;
				}else {
					Coordinate p(e->getCoordinate());
					loc=getLocation(geomi,p,geom);
				}
				label->setAllLocationsIfNull(geomi,loc);
			}
		}
	}
}

void EdgeEndStar::computeEdgeEndLabels(){
	// Compute edge label for each EdgeEnd
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		e->computeLabel();
	}
}

int EdgeEndStar::getLocation(int geomIndex,Coordinate p,vector<GeometryGraph*> *geom){
	// compute location only on demand
	if (ptInAreaLocation[geomIndex]==Location::UNDEF) {
//		ptInAreaLocation[geomIndex]=SimplePointInAreaLocator::locate(p,(geom->at(geomIndex))->getGeometry());
        ptInAreaLocation[geomIndex]=SimplePointInAreaLocator::locate(p,(*geom)[geomIndex]->getGeometry());
	}
	return ptInAreaLocation[geomIndex];
}

bool EdgeEndStar::isAreaLabelsConsistent(){
	computeEdgeEndLabels();
	return checkAreaLabelsConsistent(0);
}

bool EdgeEndStar::checkAreaLabelsConsistent(int geomIndex){
	// Since edges are stored in CCW order around the node,
	// As we move around the ring we move from the right to the left side of the edge
	vector<EdgeEnd*> *edges=getEdges();
	// if no edges, trivially consistent
	if (edges->size()<=0)
		return true;
	// initialize startLoc to location of last L side (if any)
	int lastEdgeIndex=(int)edges->size()-1;
	Label *startLabel=((*edgeList)[lastEdgeIndex])->getLabel();
	int startLoc=startLabel->getLocation(geomIndex,Position::LEFT);
	Assert::isTrue(startLoc!=Location::UNDEF, "Found unlabelled area edge");
	int currLoc=startLoc;
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *eLabel=e->getLabel();
		// we assume that we are only checking a area
		Assert::isTrue(eLabel->isArea(geomIndex), "Found non-area edge");
		int leftLoc=eLabel->getLocation(geomIndex,Position::LEFT);
		int rightLoc=eLabel->getLocation(geomIndex,Position::RIGHT);
		// check that edge is really a boundary between inside and outside!
		if (leftLoc==rightLoc) {
			return false;
		}
		// check side location conflict
		//Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr);
		if (rightLoc!=currLoc) {
			return false;
		}
		currLoc=leftLoc;
	}
	return true;
}

void EdgeEndStar::propagateSideLabels(int geomIndex){
	// Since edges are stored in CCW order around the node,
	// As we move around the ring we move from the right to the left side of the edge
	int startLoc=Location::UNDEF ;
	// initialize loc to location of last L side (if any)
    vector<EdgeEnd*>::iterator it;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		if (label->isArea(geomIndex) && label->getLocation(geomIndex,Position::LEFT)!=Location::UNDEF)
			startLoc=label->getLocation(geomIndex,Position::LEFT);
	}
		// no labelled sides found, so no labels to propagate
	if (startLoc==Location::UNDEF) return;
	int currLoc=startLoc;
	for (it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		Label *label=e->getLabel();
		// set null ON values to be in current location
		if (label->getLocation(geomIndex,Position::ON)==Location::UNDEF)
			label->setLocation(geomIndex,Position::ON,currLoc);
		// set side labels (if any)
		// if (label.isArea()) {   //ORIGINAL
		if (label->isArea(geomIndex)) {
			int leftLoc=label->getLocation(geomIndex,Position::LEFT);
			int rightLoc=label->getLocation(geomIndex,Position::RIGHT);
			// if there is a right location, that is the next location to propagate
			if (rightLoc!=Location::UNDEF) {
				string locStr="(at " + (e->getCoordinate()).toString() + ")";
				//Debug.print(rightLoc != currLoc, this);
				Assert::isTrue(rightLoc==currLoc, "side location conflict " + locStr);
				Assert::isTrue(leftLoc!=Location::UNDEF, "found single null side " + locStr);
				currLoc=leftLoc;
			} else {
				/** RHS is null - LHS must be null too.
				 *  This must be an edge from the other geometry, which has no location
				 *  labelling for this geometry.  This edge must lie wholly inside or outside
				 *  the other geometry (which is determined by the current location).
				 *  Assign both sides to be the current location.
				 */
				Assert::isTrue(label->getLocation(geomIndex,Position::LEFT)==Location::UNDEF, "found single null side");
				label->setLocation(geomIndex,Position::RIGHT, currLoc);
				label->setLocation(geomIndex,Position::LEFT, currLoc);
			}
		}
	}
}

int EdgeEndStar::findIndex(EdgeEnd *eSearch){
	getIterator();   // force edgelist to be computed
	for (unsigned int i=0; i<edgeList->size(); i++ ) {
		EdgeEnd *e=(*edgeList)[i];
		if (e->compareTo(*eSearch)) return i;
	}
	return -1;
}

string EdgeEndStar::print(){
	string out="EdgeEndStar:   " + getCoordinate().toString()+"\n";
	for (vector<EdgeEnd*>::iterator it=getIterator();it<edgeList->end();it++) {
		EdgeEnd *e=*it;
		out+=e->print();
	}
	return out;
}
<|endoftext|>


<commit_before>#include "estimator/atmospheric_location_estimator.hpp"

#include "protocol/messages.hpp"

#include "unit_config.hpp"

AtmosphericLocationEstimator::AtmosphericLocationEstimator(Communicator& communicator)
  : locationMessageStream(communicator, 5) {
}

LocationEstimate AtmosphericLocationEstimator::update(const SensorMeasurements& meas) {
  makeEstimate(meas);
  updateStream();

  return loc;
}

LocationEstimate AtmosphericLocationEstimator::makeEstimate(const SensorMeasurements& meas) {
  if(meas.gps) {
    loc.lat = (*meas.gps).lat;
    loc.lon = (*meas.gps).lat;
  }

  if(meas.bar) {
    // TODO: Mix GPS and barometer readings to get an accuration altitude?
    // TODO: Pressure != altitude.
    loc.alt = (*meas.bar).pressure;
  }

  return loc;
}

void AtmosphericLocationEstimator::updateStream() {
  if(locationMessageStream.ready()) {
    protocol::message::location_message_t m {
      .lat = loc.lat,
      .lon = loc.lon,
      .alt = loc.alt
    };

    locationMessageStream.publish(m);
  }
}
<commit_msg>Initialize location.<commit_after>#include "estimator/atmospheric_location_estimator.hpp"

#include "protocol/messages.hpp"

#include "unit_config.hpp"

// TODO: Initial location is not valid. Maybe we should be able to mark the
// estimate as invalid until a GPS fix is found?
AtmosphericLocationEstimator::AtmosphericLocationEstimator(Communicator& communicator)
  : loc{0.0, 0.0, 0.0}
    locationMessageStream(communicator, 5) {
}

LocationEstimate AtmosphericLocationEstimator::update(const SensorMeasurements& meas) {
  makeEstimate(meas);
  updateStream();

  return loc;
}

LocationEstimate AtmosphericLocationEstimator::makeEstimate(const SensorMeasurements& meas) {
  if(meas.gps) {
    loc.lat = (*meas.gps).lat;
    loc.lon = (*meas.gps).lat;
  }

  if(meas.bar) {
    // TODO: Mix GPS and barometer readings to get an accuration altitude?
    // TODO: Pressure != altitude.
    loc.alt = (*meas.bar).pressure;
  }

  return loc;
}

void AtmosphericLocationEstimator::updateStream() {
  if(locationMessageStream.ready()) {
    protocol::message::location_message_t m {
      .lat = loc.lat,
      .lon = loc.lon,
      .alt = loc.alt
    };

    locationMessageStream.publish(m);
  }
}
<|endoftext|>


<commit_before>
//#include <OGRE/ExampleApplication.h>
//#include <OGRE/OgreLogManager.h>
#include "Actions/Action.h"
#include "Actions/ActionPump.h"
#include "Application/Application.h"
#include "Common/Common.h"
#include "Input/Input.h"
#include "Networking/Network.h"
#include "Graphics/Graphics.h"

#include <iostream>
#include <fstream>
#include <OGRE/ExampleApplication.h>
#include <OGRE/ExampleFrameListener.h>
using namespace std;

int main(int argc, char **argv)
{
  /*Network* x = Network::instance();
  x->connect("127.0.0.1");

  // This is necessary to have the networking branch off on its own thread.
  asio::thread t(boost::bind(&asio::io_service::run, &Network::service()));

  Action a;
  a["id"] = 4;
  a["target"] = 300;
  Network::instance()->send(a, UNKNOWN);

  t.join();
  */
  //Example app;
  Application app2;
  try {
    //app.go();
    app2.go();
  }
  catch( Ogre::Exception& e ) {
    std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
  }

  return 0;
}
<commit_msg>Uncomments main application in main.cpp<commit_after>
//#include <OGRE/ExampleApplication.h>
//#include <OGRE/OgreLogManager.h>
#include "Actions/Action.h"
#include "Actions/ActionPump.h"
#include "Application/Application.h"
#include "Common/Common.h"
#include "Input/Input.h"
#include "Networking/Network.h"
#include "Graphics/Graphics.h"

#include <iostream>
#include <fstream>
#include <OGRE/ExampleApplication.h>
#include <OGRE/ExampleFrameListener.h>

#include <btBulletDynamicsCommon.h>

using namespace std;

int main(int argc, char **argv)
{
   btBroadphaseInterface* broadphase = new btDbvtBroadphase();

  /*Network* x = Network::instance();
  x->connect("127.0.0.1");

  // This is necessary to have the networking branch off on its own thread.
  asio::thread t(boost::bind(&asio::io_service::run, &Network::service()));

  Action a;
  a["id"] = 4;
  a["target"] = 300;
  Network::instance()->send(a, UNKNOWN);

  t.join();*/

  //Example app;
  Application app2;
  try {
    //app.go();
    app2.go();
  }
  catch( Ogre::Exception& e ) {
    std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
  }

  return 0;
}
<|endoftext|>