<commit_before>/*
 Copyright (c) 2010, Hector Sanchez-Pajares
 Aer Studio http://www.aerstudio.com
 All rights reserved.

 This is a block for OSC Integration for Cinder framework developed by The Barbarian Group, 2010

 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.

 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 "cinder/app/AppBasic.h"

using namespace ci;
using namespace ci::app;

#include "OscListener.h"

// We'll create a new Cinder Application by deriving from the BasicApp class
class OSCListenerApp : public AppBasic {
 public:

	void prepareSettings(Settings *settings);
	void setup();
	void update();
	void draw();

	osc::Listener listener;
	float positionX;
};

void OSCListenerApp::prepareSettings(Settings *settings){
	settings->setFrameRate(60.0f);
	settings->setWindowSize(640, 480);
}

void OSCListenerApp::setup(){
	listener.setup(3000);
}

void OSCListenerApp::update(){
	while (listener.hasWaitingMessages()) {
		osc::Message message;
		listener.getNextMessage(&message);

		console() << "New message received" << std::endl;
		console() << "Address: " << message.getAddress() << std::endl;
		console() << "Num Arg: " << message.getNumArgs() << std::endl;
		for (int i = 0; i < message.getNumArgs(); i++) {
			console() << "-- Argument " << i << std::endl;
			console() << "---- type: " << message.getArgTypeName(i) << std::endl;
			if (message.getArgType(i) == osc::TYPE_INT32){
				try {
					console() << "------ value: "<< message.getArgAsInt32(i) << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as int32" << std::endl;
				}

			}else if (message.getArgType(i) == osc::TYPE_FLOAT){
				try {
					console() << "------ value: " << message.getArgAsFloat(i) << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as float" << std::endl;
				}

				positionX = message.getArgAsFloat(0);
			}else if (message.getArgType(i) == osc::TYPE_STRING){
				try {
					console() << "------ value: " << message.getArgAsString(i).c_str() << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as string" << std::endl;
				}

			}
		}

	}
}

void OSCListenerApp::draw()
{
	gl::clear(Color(0,0,0), true);
	gl::color(Color(1, 1, 1));
	gl::drawSolidRect(Rectf(Vec2f(0, 0), Vec2f(positionX * getWindowWidth(), getWindowHeight())));
}

// This line tells Cinder to actually create the application
CINDER_APP_BASIC( OSCListenerApp, RendererGl )
<commit_msg>reduced fragility of OSCListener sample. Gets rid of crash when testing with MSARemote.<commit_after>/*
 Copyright (c) 2010, Hector Sanchez-Pajares
 Aer Studio http://www.aerstudio.com
 All rights reserved.

 This is a block for OSC Integration for Cinder framework developed by The Barbarian Group, 2010

 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.

 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 "cinder/app/AppBasic.h"

using namespace ci;
using namespace ci::app;

#include "OscListener.h"

// We'll create a new Cinder Application by deriving from the BasicApp class
class OSCListenerApp : public AppBasic {
 public:

	void prepareSettings(Settings *settings);
	void setup();
	void update();
	void draw();

	osc::Listener listener;
	float positionX;
};

void OSCListenerApp::prepareSettings(Settings *settings){
	settings->setFrameRate(60.0f);
	settings->setWindowSize(640, 480);
}

void OSCListenerApp::setup(){
	listener.setup(3000);
}

void OSCListenerApp::update(){
	while (listener.hasWaitingMessages()) {
		osc::Message message;
		listener.getNextMessage(&message);

		console() << "New message received" << std::endl;
		console() << "Address: " << message.getAddress() << std::endl;
		console() << "Num Arg: " << message.getNumArgs() << std::endl;
		for (int i = 0; i < message.getNumArgs(); i++) {
			console() << "-- Argument " << i << std::endl;
			console() << "---- type: " << message.getArgTypeName(i) << std::endl;
			if (message.getArgType(i) == osc::TYPE_INT32){
				try {
					console() << "------ value: "<< message.getArgAsInt32(i) << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as int32" << std::endl;
				}

			}else if (message.getArgType(i) == osc::TYPE_FLOAT){
				try {
					console() << "------ value: " << message.getArgAsFloat(i) << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as float" << std::endl;
				}
			}else if (message.getArgType(i) == osc::TYPE_STRING){
				try {
					console() << "------ value: " << message.getArgAsString(i).c_str() << std::endl;
				}
				catch (...) {
					console() << "Exception reading argument as string" << std::endl;
				}

			}
		}

        if( message.getNumArgs() != 0 && message.getArgType( 0 ) == osc::TYPE_FLOAT )
        {
            positionX = message.getArgAsFloat(0);
        }

	}
}

void OSCListenerApp::draw()
{
	gl::clear(Color(0,0,0), true);
	gl::color(Color(1, 1, 1));
	gl::drawSolidRect(Rectf(Vec2f(0, 0), Vec2f(positionX * getWindowWidth(), getWindowHeight())));
}

// This line tells Cinder to actually create the application
CINDER_APP_BASIC( OSCListenerApp, RendererGl )
<|endoftext|>


<commit_before>#include <chrono>
#include <iostream>
using namespace std;

class Timer
{
public:
	Timer()
		: start_(std::chrono::high_resolution_clock::now())
	{
	}

	~Timer()
	{
		const auto finish = std::chrono::high_resolution_clock::now();
		std::cout << std::chrono::duration_cast<std::chrono::microseconds>(finish - start_).count() << " us = ";
		std::cout << std::chrono::duration_cast<std::chrono::microseconds>(finish - start_).count()/1.0e6 << " s" << std::endl;
	}

private:
	const std::chrono::high_resolution_clock::time_point start_;
};

int main()
{
	int N = 10000;
	volatile int sum = 0;

	int** data = new int*[N];
	for (int i = 0; i < N; i++) {
		data[i] = new int[N];
	}

	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			data[i][j] = i + j;

	Timer t;
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			sum += data[i][j];
	return 0;
}
<commit_msg>Update sum_by_rows.cpp<commit_after>#include <chrono>
#include <iostream>
using namespace std;

class Timer
{
public:
	Timer()
		: start_(std::chrono::high_resolution_clock::now())
	{
	}

	~Timer()
	{
		const auto finish = std::chrono::high_resolution_clock::now();
		std::cout << std::chrono::duration_cast<std::chrono::microseconds>(finish - start_).count() << " us = ";
		std::cout << std::chrono::duration_cast<std::chrono::microseconds>(finish - start_).count()/1.0e6 << " s" << std::endl;
	}

private:
	const std::chrono::high_resolution_clock::time_point start_;
};

int main()
{
	int N = 10000;
	volatile int sum = 0;

	//инициализация матрицы
	int** data = new int*[N];
	for (int i = 0; i < N; i++) {
		data[i] = new int[N];
	}

	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			data[i][j] = i + j;

	//запуск таймера
	Timer t;
	//суммируем
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			sum += data[i][j];

	//чистим память
	delete[] data;
	return 0;
}
<|endoftext|>


<commit_before>/**
 *  ifaces.cpp
 *  ExternalExtensions project
 *
 *  Copyright (c) 2015 thesupremecommander
 *  MIT License
 *  http://opensource.org/licenses/MIT
 *
 */

#include "ifaces.h"

#include "tier0/valve_minmax_on.h"
#include "cdll_int.h"
#include "engine/ivmodelinfo.h"
#include "entitylist_base.h"
#include "filesystem_init.h"
#include "icliententitylist.h"
#include "igameevents.h"
#include "ivrenderview.h"
#include "steam/steam_api.h"
#include "teamplayroundbased_gamerules.h"
#include "tier3/tier3.h"
#include "vgui_controls/Controls.h"
#include "tier0/valve_minmax_off.h"

#include "exceptions.h"
#include "platform.h"

IBaseClientDLL *Interfaces::pClientDLL = nullptr;
IClientEntityList *Interfaces::pClientEntityList = nullptr;
CDllDemandLoader *Interfaces::pClientModule = nullptr;
IVEngineClient *Interfaces::pEngineClient = nullptr;
IGameEventManager2 *Interfaces::pGameEventManager = nullptr;
IVModelInfoClient *Interfaces::pModelInfoClient = nullptr;
IVRenderView *Interfaces::pRenderView = nullptr;
CSteamAPIContext *Interfaces::pSteamAPIContext = nullptr;

bool Interfaces::steamLibrariesAvailable = false;
bool Interfaces::vguiLibrariesAvailable = false;

CBaseEntityList *g_pEntityList;

void Interfaces::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) {
	ConnectTier1Libraries(&interfaceFactory, 1);
	ConnectTier2Libraries(&interfaceFactory, 1);
	ConnectTier3Libraries(&interfaceFactory, 1);

	vguiLibrariesAvailable = vgui::VGui_InitInterfacesList("externalextensions", &interfaceFactory, 1);

	pEngineClient = (IVEngineClient *)interfaceFactory(VENGINE_CLIENT_INTERFACE_VERSION, nullptr);
	pGameEventManager = (IGameEventManager2 *)interfaceFactory(INTERFACEVERSION_GAMEEVENTSMANAGER2, nullptr);
	pModelInfoClient = (IVModelInfoClient *)interfaceFactory(VMODELINFO_CLIENT_INTERFACE_VERSION, nullptr);
	pRenderView = (IVRenderView *)interfaceFactory(VENGINE_RENDERVIEW_INTERFACE_VERSION, nullptr);

	pClientModule = new CDllDemandLoader(CLIENT_MODULE_FILE);

	CreateInterfaceFn gameClientFactory = pClientModule->GetFactory();

	pClientDLL = (IBaseClientDLL*)gameClientFactory(CLIENT_DLL_INTERFACE_VERSION, nullptr);
	pClientEntityList = (IClientEntityList*)gameClientFactory(VCLIENTENTITYLIST_INTERFACE_VERSION, nullptr);

	pSteamAPIContext = new CSteamAPIContext();
	steamLibrariesAvailable = SteamAPI_InitSafe() && pSteamAPIContext->Init();

	g_pEntityList = (CBaseEntityList *) Interfaces::pClientEntityList;
}

void Interfaces::Unload() {
	DisconnectTier3Libraries();
	DisconnectTier2Libraries();
	DisconnectTier1Libraries();

	pSteamAPIContext->Clear();

	pClientModule->Unload();
	pClientModule = nullptr;

	pClientDLL = nullptr;
	pClientEntityList = nullptr;
	pEngineClient = nullptr;
	pGameEventManager = nullptr;
	pRenderView = nullptr;
}
<commit_msg>Don't include TeamplayRoundBasedGameRules.<commit_after>/**
 *  ifaces.cpp
 *  ExternalExtensions project
 *
 *  Copyright (c) 2015 thesupremecommander
 *  MIT License
 *  http://opensource.org/licenses/MIT
 *
 */

#include "ifaces.h"

#include "tier0/valve_minmax_on.h"
#include "cdll_int.h"
#include "engine/ivmodelinfo.h"
#include "entitylist_base.h"
#include "filesystem_init.h"
#include "icliententitylist.h"
#include "igameevents.h"
#include "ivrenderview.h"
#include "steam/steam_api.h"
#include "tier3/tier3.h"
#include "vgui_controls/Controls.h"
#include "tier0/valve_minmax_off.h"

#include "exceptions.h"
#include "platform.h"

IBaseClientDLL *Interfaces::pClientDLL = nullptr;
IClientEntityList *Interfaces::pClientEntityList = nullptr;
CDllDemandLoader *Interfaces::pClientModule = nullptr;
IVEngineClient *Interfaces::pEngineClient = nullptr;
IGameEventManager2 *Interfaces::pGameEventManager = nullptr;
IVModelInfoClient *Interfaces::pModelInfoClient = nullptr;
IVRenderView *Interfaces::pRenderView = nullptr;
CSteamAPIContext *Interfaces::pSteamAPIContext = nullptr;

bool Interfaces::steamLibrariesAvailable = false;
bool Interfaces::vguiLibrariesAvailable = false;

CBaseEntityList *g_pEntityList;

void Interfaces::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) {
	ConnectTier1Libraries(&interfaceFactory, 1);
	ConnectTier2Libraries(&interfaceFactory, 1);
	ConnectTier3Libraries(&interfaceFactory, 1);

	vguiLibrariesAvailable = vgui::VGui_InitInterfacesList("externalextensions", &interfaceFactory, 1);

	pEngineClient = (IVEngineClient *)interfaceFactory(VENGINE_CLIENT_INTERFACE_VERSION, nullptr);
	pGameEventManager = (IGameEventManager2 *)interfaceFactory(INTERFACEVERSION_GAMEEVENTSMANAGER2, nullptr);
	pModelInfoClient = (IVModelInfoClient *)interfaceFactory(VMODELINFO_CLIENT_INTERFACE_VERSION, nullptr);
	pRenderView = (IVRenderView *)interfaceFactory(VENGINE_RENDERVIEW_INTERFACE_VERSION, nullptr);

	pClientModule = new CDllDemandLoader(CLIENT_MODULE_FILE);

	CreateInterfaceFn gameClientFactory = pClientModule->GetFactory();

	pClientDLL = (IBaseClientDLL*)gameClientFactory(CLIENT_DLL_INTERFACE_VERSION, nullptr);
	pClientEntityList = (IClientEntityList*)gameClientFactory(VCLIENTENTITYLIST_INTERFACE_VERSION, nullptr);

	pSteamAPIContext = new CSteamAPIContext();
	steamLibrariesAvailable = SteamAPI_InitSafe() && pSteamAPIContext->Init();

	g_pEntityList = (CBaseEntityList *) Interfaces::pClientEntityList;
}

void Interfaces::Unload() {
	DisconnectTier3Libraries();
	DisconnectTier2Libraries();
	DisconnectTier1Libraries();

	pSteamAPIContext->Clear();

	pClientModule->Unload();
	pClientModule = nullptr;

	pClientDLL = nullptr;
	pClientEntityList = nullptr;
	pEngineClient = nullptr;
	pGameEventManager = nullptr;
	pRenderView = nullptr;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This test validates that the ProcessSingleton class properly makes sure
// that there is only one main browser process.
//
// It is currently compiled and ran on the windows platform only but has been
// written in a platform independent way (using the process/threads/sync
// routines from base). So it does compile fine on Mac and Linux but fails to
// launch the app and thus have not been tested for success/failures. Since it
// was written to validate a change made to fix a bug only seen on Windows, it
// was left as is until it gets to be needed on the other platforms.

#include <list>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
#include "base/thread.h"
#include "base/waitable_event.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/ui/ui_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// This is for the code that is to be ran in multiple threads at once,
// to stress a race condition on first process start.
// We use the thread safe ref counted base class so that we can use the
// NewRunnableMethod class to run the StartChrome methods in many threads.
class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> {
 public:
  ChromeStarter()
      : ready_event_(false /* manual */, false /* signaled */),
        done_event_(false /* manual */, false /* signaled */),
        process_handle_(NULL),
        process_terminated_(false) {
  }

  // We must reset some data members since we reuse the same ChromeStarter
  // object and start/stop it a few times. We must start fresh! :-)
  void Reset() {
    ready_event_.Reset();
    done_event_.Reset();
    if (process_handle_ != NULL)
      base::CloseProcessHandle(process_handle_);
    process_handle_ = NULL;
    process_terminated_ = false;
  }

  void StartChrome(base::WaitableEvent* start_event) {
    // TODO(port): For some reason the LaunchApp call below fails even though
    // we use the platform independent constant for the executable path.
    // This is the current blocker for running this test on Mac & Linux.
    CommandLine command_line(FilePath::FromWStringHack(
        chrome::kBrowserProcessExecutablePath));

    // Try to get all threads to launch the app at the same time.
    // So let the test know we are ready.
    ready_event_.Signal();
    // And then wait for the test to tell us to GO!
    ASSERT_NE(static_cast<base::WaitableEvent*>(NULL), start_event);
    ASSERT_TRUE(start_event->Wait());

    // Here we don't wait for the app to be terminated because one of the
    // process will stay alive while the others will be restarted. If we would
    // wait here, we would never get a handle to the main process...
    base::LaunchApp(command_line, false /* wait */,
                    false /* hidden */, &process_handle_);
    ASSERT_NE(static_cast<base::ProcessHandle>(NULL), process_handle_);

    // We can wait on the handle here, we should get stuck on one and only
    // one process. The test below will take care of killing that process
    // to unstuck us once it confirms there is only one.
    static const int64 kWaitForProcessDeath = 5000;
    process_terminated_ = base::WaitForSingleProcess(process_handle_,
                                                     kWaitForProcessDeath);
    // Let the test know we are done.
    done_event_.Signal();
  }

  // Public access to simplify the test code using them.
  base::WaitableEvent ready_event_;
  base::WaitableEvent done_event_;
  base::ProcessHandle process_handle_;
  bool process_terminated_;

 private:
  friend class base::RefCountedThreadSafe<ChromeStarter>;
  ~ChromeStarter() {
    if (process_handle_ != NULL)
      base::CloseProcessHandle(process_handle_);
  }
  DISALLOW_COPY_AND_ASSIGN(ChromeStarter);
};

// Our test fixture that initializes and holds onto a few global vars.
class ProcessSingletonWinTest : public UITest {
 public:
  ProcessSingletonWinTest()
      // We use a manual reset so that all threads wake up at once when signaled
      // and thus we must manually reset it for each attempt.
      : threads_waker_(true /* manual */, false /* signaled */) {
  }

  void SetUp() {
    // Start the threads and create the starters.
    for (size_t i = 0; i < kNbThreads; ++i) {
      chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter"));
      ASSERT_TRUE(chrome_starter_threads_[i]->Start());
      chrome_starters_[i] = new ChromeStarter;
    }
  }

  void TearDown() {
    // Stop the threads.
    for (size_t i = 0; i < kNbThreads; ++i)
      chrome_starter_threads_[i]->Stop();
  }

  // This method is used to make sure we kill the main browser process after
  // all of its child processes have successfully attached to it. This was added
  // when we realized that if we just kill the parent process right away, we
  // sometimes end up with dangling child processes. If we Sleep for a certain
  // amount of time, we are OK... So we introduced this method to avoid a
  // flaky wait. Instead, we kill all descendants of the main process after we
  // killed it, relying on the fact that we can still get the parent id of a
  // child process, even when the parent dies.
  void KillProcessTree(base::ProcessHandle process_handle) {
    class ProcessTreeFilter : public base::ProcessFilter {
     public:
      explicit ProcessTreeFilter(base::ProcessId parent_pid) {
        ancestor_pids_.insert(parent_pid);
      }
      virtual bool Includes(base::ProcessId pid,
                            base::ProcessId parent_pid) const {
        if (ancestor_pids_.find(parent_pid) != ancestor_pids_.end()) {
          ancestor_pids_.insert(pid);
          return true;
        } else {
          return false;
        }
      }
     private:
      mutable std::set<base::ProcessId> ancestor_pids_;
    } process_tree_filter(base::GetProcId(process_handle));

    // Start by explicitly killing the main process we know about...
    static const int kExitCode = 42;
    EXPECT_TRUE(base::KillProcess(process_handle, kExitCode, true /* wait */));

    // Then loop until we can't find any of its descendant.
    // But don't try more than kNbTries times...
    static const int kNbTries = 10;
    int num_tries = 0;
    while (base::GetProcessCount(chrome::kBrowserProcessExecutablePath,
        &process_tree_filter) > 0 && num_tries++ < kNbTries) {
      base::KillProcesses(chrome::kBrowserProcessExecutablePath,
                          kExitCode, &process_tree_filter);
    }
    DLOG_IF(ERROR, num_tries >= kNbTries) << "Failed to kill all processes!";
  }

  // Since this is a hard to reproduce problem, we make a few attempts.
  // We stop the attempts at the first error, and when there are no errors,
  // we don't time-out of any wait, so it executes quite fast anyway.
  static const size_t kNbAttempts = 5;

  // The idea is to start chrome from multiple threads all at once.
  static const size_t kNbThreads = 5;
  scoped_refptr<ChromeStarter> chrome_starters_[kNbThreads];
  scoped_ptr<base::Thread> chrome_starter_threads_[kNbThreads];

  // The event that will get all threads to wake up simultaneously and try
  // to start a chrome process at the same time.
  base::WaitableEvent threads_waker_;
};

TEST_F(ProcessSingletonWinTest, StartupRaceCondition) {
  // We use this to stop the attempts loop on the first failure.
  bool failed = false;
  for (size_t attempt = 0; attempt < kNbAttempts && !failed; ++attempt) {
    SCOPED_TRACE(testing::Message() << "Attempt: " << attempt << ".");
    // We use a single event to get all threads to do the AppLaunch at the same
    // time...
    threads_waker_.Reset();

    // Here we prime all the threads with a ChromeStarter that will wait for
    // our signal to launch its chrome process.
    for (size_t i = 0; i < kNbThreads; ++i) {
      ASSERT_NE(static_cast<ChromeStarter*>(NULL), chrome_starters_[i].get());
      chrome_starters_[i]->Reset();

      ASSERT_TRUE(chrome_starter_threads_[i]->IsRunning());
      ASSERT_NE(static_cast<MessageLoop*>(NULL),
                chrome_starter_threads_[i]->message_loop());

      chrome_starter_threads_[i]->message_loop()->PostTask(
          FROM_HERE, NewRunnableMethod(chrome_starters_[i].get(),
                                       &ChromeStarter::StartChrome,
                                       &threads_waker_));
    }

    // Wait for all the starters to be ready.
    // We could replace this loop if we ever implement a WaitAll().
    for (size_t i = 0; i < kNbThreads; ++i) {
      SCOPED_TRACE(testing::Message() << "Waiting on thread: " << i << ".");
      ASSERT_TRUE(chrome_starters_[i]->ready_event_.Wait());
    }
    // GO!
    threads_waker_.Signal();

    // As we wait for all threads to signal that they are done, we remove their
    // index from this vector so that we get left with only the index of
    // the thread that started the main process.
    std::vector<size_t> pending_starters(kNbThreads);
    for (size_t i = 0; i < kNbThreads; ++i)
      pending_starters[i] = i;

    // We use a local array of starter's done events we must wait on...
    // These are collected from the starters that we have not yet been removed
    // from the pending_starters vector.
    base::WaitableEvent* starters_done_events[kNbThreads];
    // At the end, "There can be only one" main browser process alive.
    while (pending_starters.size() > 1) {
      SCOPED_TRACE(testing::Message() << pending_starters.size() <<
                   " starters left.");
      for (size_t i = 0; i < pending_starters.size(); ++i) {
        starters_done_events[i] =
            &chrome_starters_[pending_starters[i]]->done_event_;
      }
      size_t done_index = base::WaitableEvent::WaitMany(
          starters_done_events, pending_starters.size());
      size_t starter_index = pending_starters[done_index];
      // If the starter is done but has not marked itself as terminated,
      // it is because it timed out of its WaitForSingleProcess(). Only the
      // last one standing should be left waiting... So we failed...
      EXPECT_TRUE(chrome_starters_[starter_index]->process_terminated_ ||
                  failed) << "There is more than one main process.";
      if (!chrome_starters_[starter_index]->process_terminated_) {
        // This will stop the "for kNbAttempts" loop.
        failed = true;
        // But we let the last loop turn finish so that we can properly
        // kill all remaining processes. Starting with this one...
        if (chrome_starters_[starter_index]->process_handle_ != NULL) {
          KillProcessTree(chrome_starters_[starter_index]->process_handle_);
        }
      }
      pending_starters.erase(pending_starters.begin() + done_index);
    }

    // "There can be only one!" :-)
    ASSERT_EQ(static_cast<size_t>(1), pending_starters.size());
    size_t last_index = pending_starters.front();
    pending_starters.empty();
    if (chrome_starters_[last_index]->process_handle_ != NULL) {
      KillProcessTree(chrome_starters_[last_index]->process_handle_);
      chrome_starters_[last_index]->done_event_.Wait();
    }
  }
}

}  // namespace
<commit_msg>Disable ProcessSingletonWinTest.StartupRaceCondition as it's failing consistently.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This test validates that the ProcessSingleton class properly makes sure
// that there is only one main browser process.
//
// It is currently compiled and ran on the windows platform only but has been
// written in a platform independent way (using the process/threads/sync
// routines from base). So it does compile fine on Mac and Linux but fails to
// launch the app and thus have not been tested for success/failures. Since it
// was written to validate a change made to fix a bug only seen on Windows, it
// was left as is until it gets to be needed on the other platforms.

#include <list>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
#include "base/thread.h"
#include "base/waitable_event.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/ui/ui_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// This is for the code that is to be ran in multiple threads at once,
// to stress a race condition on first process start.
// We use the thread safe ref counted base class so that we can use the
// NewRunnableMethod class to run the StartChrome methods in many threads.
class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> {
 public:
  ChromeStarter()
      : ready_event_(false /* manual */, false /* signaled */),
        done_event_(false /* manual */, false /* signaled */),
        process_handle_(NULL),
        process_terminated_(false) {
  }

  // We must reset some data members since we reuse the same ChromeStarter
  // object and start/stop it a few times. We must start fresh! :-)
  void Reset() {
    ready_event_.Reset();
    done_event_.Reset();
    if (process_handle_ != NULL)
      base::CloseProcessHandle(process_handle_);
    process_handle_ = NULL;
    process_terminated_ = false;
  }

  void StartChrome(base::WaitableEvent* start_event) {
    // TODO(port): For some reason the LaunchApp call below fails even though
    // we use the platform independent constant for the executable path.
    // This is the current blocker for running this test on Mac & Linux.
    CommandLine command_line(FilePath::FromWStringHack(
        chrome::kBrowserProcessExecutablePath));

    // Try to get all threads to launch the app at the same time.
    // So let the test know we are ready.
    ready_event_.Signal();
    // And then wait for the test to tell us to GO!
    ASSERT_NE(static_cast<base::WaitableEvent*>(NULL), start_event);
    ASSERT_TRUE(start_event->Wait());

    // Here we don't wait for the app to be terminated because one of the
    // process will stay alive while the others will be restarted. If we would
    // wait here, we would never get a handle to the main process...
    base::LaunchApp(command_line, false /* wait */,
                    false /* hidden */, &process_handle_);
    ASSERT_NE(static_cast<base::ProcessHandle>(NULL), process_handle_);

    // We can wait on the handle here, we should get stuck on one and only
    // one process. The test below will take care of killing that process
    // to unstuck us once it confirms there is only one.
    static const int64 kWaitForProcessDeath = 5000;
    process_terminated_ = base::WaitForSingleProcess(process_handle_,
                                                     kWaitForProcessDeath);
    // Let the test know we are done.
    done_event_.Signal();
  }

  // Public access to simplify the test code using them.
  base::WaitableEvent ready_event_;
  base::WaitableEvent done_event_;
  base::ProcessHandle process_handle_;
  bool process_terminated_;

 private:
  friend class base::RefCountedThreadSafe<ChromeStarter>;
  ~ChromeStarter() {
    if (process_handle_ != NULL)
      base::CloseProcessHandle(process_handle_);
  }
  DISALLOW_COPY_AND_ASSIGN(ChromeStarter);
};

// Our test fixture that initializes and holds onto a few global vars.
class ProcessSingletonWinTest : public UITest {
 public:
  ProcessSingletonWinTest()
      // We use a manual reset so that all threads wake up at once when signaled
      // and thus we must manually reset it for each attempt.
      : threads_waker_(true /* manual */, false /* signaled */) {
  }

  void SetUp() {
    // Start the threads and create the starters.
    for (size_t i = 0; i < kNbThreads; ++i) {
      chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter"));
      ASSERT_TRUE(chrome_starter_threads_[i]->Start());
      chrome_starters_[i] = new ChromeStarter;
    }
  }

  void TearDown() {
    // Stop the threads.
    for (size_t i = 0; i < kNbThreads; ++i)
      chrome_starter_threads_[i]->Stop();
  }

  // This method is used to make sure we kill the main browser process after
  // all of its child processes have successfully attached to it. This was added
  // when we realized that if we just kill the parent process right away, we
  // sometimes end up with dangling child processes. If we Sleep for a certain
  // amount of time, we are OK... So we introduced this method to avoid a
  // flaky wait. Instead, we kill all descendants of the main process after we
  // killed it, relying on the fact that we can still get the parent id of a
  // child process, even when the parent dies.
  void KillProcessTree(base::ProcessHandle process_handle) {
    class ProcessTreeFilter : public base::ProcessFilter {
     public:
      explicit ProcessTreeFilter(base::ProcessId parent_pid) {
        ancestor_pids_.insert(parent_pid);
      }
      virtual bool Includes(base::ProcessId pid,
                            base::ProcessId parent_pid) const {
        if (ancestor_pids_.find(parent_pid) != ancestor_pids_.end()) {
          ancestor_pids_.insert(pid);
          return true;
        } else {
          return false;
        }
      }
     private:
      mutable std::set<base::ProcessId> ancestor_pids_;
    } process_tree_filter(base::GetProcId(process_handle));

    // Start by explicitly killing the main process we know about...
    static const int kExitCode = 42;
    EXPECT_TRUE(base::KillProcess(process_handle, kExitCode, true /* wait */));

    // Then loop until we can't find any of its descendant.
    // But don't try more than kNbTries times...
    static const int kNbTries = 10;
    int num_tries = 0;
    while (base::GetProcessCount(chrome::kBrowserProcessExecutablePath,
        &process_tree_filter) > 0 && num_tries++ < kNbTries) {
      base::KillProcesses(chrome::kBrowserProcessExecutablePath,
                          kExitCode, &process_tree_filter);
    }
    DLOG_IF(ERROR, num_tries >= kNbTries) << "Failed to kill all processes!";
  }

  // Since this is a hard to reproduce problem, we make a few attempts.
  // We stop the attempts at the first error, and when there are no errors,
  // we don't time-out of any wait, so it executes quite fast anyway.
  static const size_t kNbAttempts = 5;

  // The idea is to start chrome from multiple threads all at once.
  static const size_t kNbThreads = 5;
  scoped_refptr<ChromeStarter> chrome_starters_[kNbThreads];
  scoped_ptr<base::Thread> chrome_starter_threads_[kNbThreads];

  // The event that will get all threads to wake up simultaneously and try
  // to start a chrome process at the same time.
  base::WaitableEvent threads_waker_;
};

// http://code.google.com/p/chromium/issues/detail?id=38572
TEST_F(ProcessSingletonWinTest, DISABLED_StartupRaceCondition) {
  // We use this to stop the attempts loop on the first failure.
  bool failed = false;
  for (size_t attempt = 0; attempt < kNbAttempts && !failed; ++attempt) {
    SCOPED_TRACE(testing::Message() << "Attempt: " << attempt << ".");
    // We use a single event to get all threads to do the AppLaunch at the same
    // time...
    threads_waker_.Reset();

    // Here we prime all the threads with a ChromeStarter that will wait for
    // our signal to launch its chrome process.
    for (size_t i = 0; i < kNbThreads; ++i) {
      ASSERT_NE(static_cast<ChromeStarter*>(NULL), chrome_starters_[i].get());
      chrome_starters_[i]->Reset();

      ASSERT_TRUE(chrome_starter_threads_[i]->IsRunning());
      ASSERT_NE(static_cast<MessageLoop*>(NULL),
                chrome_starter_threads_[i]->message_loop());

      chrome_starter_threads_[i]->message_loop()->PostTask(
          FROM_HERE, NewRunnableMethod(chrome_starters_[i].get(),
                                       &ChromeStarter::StartChrome,
                                       &threads_waker_));
    }

    // Wait for all the starters to be ready.
    // We could replace this loop if we ever implement a WaitAll().
    for (size_t i = 0; i < kNbThreads; ++i) {
      SCOPED_TRACE(testing::Message() << "Waiting on thread: " << i << ".");
      ASSERT_TRUE(chrome_starters_[i]->ready_event_.Wait());
    }
    // GO!
    threads_waker_.Signal();

    // As we wait for all threads to signal that they are done, we remove their
    // index from this vector so that we get left with only the index of
    // the thread that started the main process.
    std::vector<size_t> pending_starters(kNbThreads);
    for (size_t i = 0; i < kNbThreads; ++i)
      pending_starters[i] = i;

    // We use a local array of starter's done events we must wait on...
    // These are collected from the starters that we have not yet been removed
    // from the pending_starters vector.
    base::WaitableEvent* starters_done_events[kNbThreads];
    // At the end, "There can be only one" main browser process alive.
    while (pending_starters.size() > 1) {
      SCOPED_TRACE(testing::Message() << pending_starters.size() <<
                   " starters left.");
      for (size_t i = 0; i < pending_starters.size(); ++i) {
        starters_done_events[i] =
            &chrome_starters_[pending_starters[i]]->done_event_;
      }
      size_t done_index = base::WaitableEvent::WaitMany(
          starters_done_events, pending_starters.size());
      size_t starter_index = pending_starters[done_index];
      // If the starter is done but has not marked itself as terminated,
      // it is because it timed out of its WaitForSingleProcess(). Only the
      // last one standing should be left waiting... So we failed...
      EXPECT_TRUE(chrome_starters_[starter_index]->process_terminated_ ||
                  failed) << "There is more than one main process.";
      if (!chrome_starters_[starter_index]->process_terminated_) {
        // This will stop the "for kNbAttempts" loop.
        failed = true;
        // But we let the last loop turn finish so that we can properly
        // kill all remaining processes. Starting with this one...
        if (chrome_starters_[starter_index]->process_handle_ != NULL) {
          KillProcessTree(chrome_starters_[starter_index]->process_handle_);
        }
      }
      pending_starters.erase(pending_starters.begin() + done_index);
    }

    // "There can be only one!" :-)
    ASSERT_EQ(static_cast<size_t>(1), pending_starters.size());
    size_t last_index = pending_starters.front();
    pending_starters.empty();
    if (chrome_starters_[last_index]->process_handle_ != NULL) {
      KillProcessTree(chrome_starters_[last_index]->process_handle_);
      chrome_starters_[last_index]->done_event_.Wait();
    }
  }
}

}  // namespace
<|endoftext|>


<commit_before>#include <LightGBM/utils/common.h>
#include <LightGBM/bin.h>

#include "dense_bin.hpp"
#include "sparse_bin.hpp"

#include <cmath>
#include <cstring>
#include <cstdint>

#include <limits>
#include <vector>
#include <algorithm>

namespace LightGBM {

BinMapper::BinMapper()
  :bin_upper_bound_(nullptr) {
}

// deep copy function for BinMapper
BinMapper::BinMapper(const BinMapper& other)
  : bin_upper_bound_(nullptr) {
  num_bin_ = other.num_bin_;
  is_trival_ = other.is_trival_;
  sparse_rate_ = other.sparse_rate_;
  bin_upper_bound_ = new float[num_bin_];
  for (int i = 0; i < num_bin_; ++i) {
    bin_upper_bound_[i] = other.bin_upper_bound_[i];
  }
}

BinMapper::BinMapper(const void* memory)
  :bin_upper_bound_(nullptr) {
  CopyFrom(reinterpret_cast<const char*>(memory));
}

BinMapper::~BinMapper() {
  delete[] bin_upper_bound_;
}

void BinMapper::FindBin(std::vector<float>* values, int max_bin) {
  std::vector<float>& ref_values = (*values);
  size_t sample_size = values->size();
  // find distinct_values first
  std::vector<float> distinct_values;
  std::vector<int> counts;

  std::sort(ref_values.begin(), ref_values.end());
  distinct_values.push_back(ref_values[0]);
  counts.push_back(1);
  for (size_t i = 1; i < ref_values.size(); ++i) {
    if (ref_values[i] != ref_values[i - 1]) {
      distinct_values.push_back(ref_values[i]);
      counts.push_back(1);
    } else {
      ++counts.back();
    }
  }
  int num_values = static_cast<int>(distinct_values.size());
  int cnt_in_bin0 = 0;

  if (num_values <= max_bin) {
    // use distinct value is enough
    num_bin_ = num_values;
    bin_upper_bound_ = new float[num_values];
    for (int i = 0; i < num_values - 1; ++i) {
      bin_upper_bound_[i] = (distinct_values[i] + distinct_values[i + 1]) / 2;
    }
    cnt_in_bin0 = counts[0];
    bin_upper_bound_[num_values - 1] = std::numeric_limits<float>::infinity();
  } else {
    // mean size for one bin
    float mean_bin_size = sample_size / static_cast<float>(max_bin);
    int rest_sample_cnt = static_cast<int>(sample_size);
    int bin_cnt = 0;

    num_bin_ = max_bin;
    std::vector<float> upper_bounds(max_bin, std::numeric_limits<float>::infinity());
    std::vector<float> lower_bounds(max_bin, std::numeric_limits<float>::infinity());
    // sort by count, descent
    Common::SortForPair(counts, distinct_values, 0, true);
    // fetch big slot as unique bin
    while (counts[bin_cnt] > mean_bin_size) {
      upper_bounds[bin_cnt] = distinct_values[bin_cnt];
      lower_bounds[bin_cnt] = distinct_values[bin_cnt];
      rest_sample_cnt -= counts[bin_cnt];
      ++bin_cnt;
    }
    // process reminder bins
    if (bin_cnt < max_bin) {
      // sort rest by values
      Common::SortForPair<float, int>(distinct_values, counts, bin_cnt, false);
      mean_bin_size = rest_sample_cnt / static_cast<float>(max_bin - bin_cnt);
      lower_bounds[bin_cnt] = distinct_values[bin_cnt];
      int cur_cnt_inbin = 0;
      for (int i = bin_cnt; i < num_values - 1; ++i) {
        rest_sample_cnt -= counts[i];
        cur_cnt_inbin += counts[i];
        // need a new bin
        if (cur_cnt_inbin >= mean_bin_size) {
          upper_bounds[bin_cnt] = distinct_values[i];
          if (bin_cnt == 0) { cnt_in_bin0 = cur_cnt_inbin; }
          ++bin_cnt;
          lower_bounds[bin_cnt] = distinct_values[i + 1];
          if (bin_cnt >= max_bin - 1) break;
          cur_cnt_inbin = 0;
          mean_bin_size = rest_sample_cnt / static_cast<float>(max_bin - bin_cnt);
        }
      }
      cur_cnt_inbin += counts[num_values - 1];

    }
    Common::SortForPair<float, float>(lower_bounds, upper_bounds, 0, false);
    // update bin upper bound
    bin_upper_bound_ = new float[bin_cnt];
    for (int i = 0; i < bin_cnt - 1; ++i) {
      bin_upper_bound_[i] = (upper_bounds[i] + lower_bounds[i + 1]) / 2.0f;
    }

    // last bin upper bound
    bin_upper_bound_[bin_cnt - 1] = std::numeric_limits<float>::infinity();

    CHECK(bin_cnt <= max_bin);

  }
  // check trival(num_bin_ == 1) feature
  if (num_bin_ <= 1) {
    is_trival_ = true;
  } else {
    is_trival_ = false;
  }
  // calculate sparse rate
  sparse_rate_ = static_cast<float>(cnt_in_bin0) / static_cast<float>(sample_size);
}

int BinMapper::SizeForSpecificBin(int bin) {
  int size = 0;
  size += sizeof(int);
  size += sizeof(bool);
  size += sizeof(float);
  size += bin * sizeof(float);
  return size;
}

void BinMapper::CopyTo(char * buffer) {
  std::memcpy(buffer, &num_bin_, sizeof(num_bin_));
  buffer += sizeof(num_bin_);
  std::memcpy(buffer, &is_trival_, sizeof(is_trival_));
  buffer += sizeof(is_trival_);
  std::memcpy(buffer, &sparse_rate_, sizeof(sparse_rate_));
  buffer += sizeof(sparse_rate_);
  std::memcpy(buffer, bin_upper_bound_, num_bin_ * sizeof(float));
}

void BinMapper::CopyFrom(const char * buffer) {
  std::memcpy(&num_bin_, buffer, sizeof(num_bin_));
  buffer += sizeof(num_bin_);
  std::memcpy(&is_trival_, buffer, sizeof(is_trival_));
  buffer += sizeof(is_trival_);
  std::memcpy(&sparse_rate_, buffer, sizeof(sparse_rate_));
  buffer += sizeof(sparse_rate_);
  if (bin_upper_bound_ != nullptr) { delete[] bin_upper_bound_; }
  bin_upper_bound_ = new float[num_bin_];
  std::memcpy(bin_upper_bound_, buffer, num_bin_ * sizeof(float));
}

void BinMapper::SaveBinaryToFile(FILE* file) const {
  fwrite(&num_bin_, sizeof(num_bin_), 1, file);
  fwrite(&is_trival_, sizeof(is_trival_), 1, file);
  fwrite(&sparse_rate_, sizeof(sparse_rate_), 1, file);
  fwrite(bin_upper_bound_, sizeof(float), num_bin_, file);
}

size_t BinMapper::SizesInByte() const {
  return sizeof(num_bin_) + sizeof(is_trival_) + sizeof(sparse_rate_) + sizeof(float) * num_bin_;
}

template class DenseBin<uint8_t>;
template class DenseBin<uint16_t>;
template class DenseBin<uint32_t>;

template class SparseBin<uint8_t>;
template class SparseBin<uint16_t>;
template class SparseBin<uint32_t>;

template class OrderedSparseBin<uint8_t>;
template class OrderedSparseBin<uint16_t>;
template class OrderedSparseBin<uint32_t>;

Bin* Bin::CreateBin(data_size_t num_data, int num_bin, float sparse_rate, bool is_enable_sparse, bool* is_sparse, int default_bin) {
  // sparse threshold
  const float kSparseThreshold = 0.8f;
  if (sparse_rate >= kSparseThreshold && is_enable_sparse) {
    *is_sparse = true;
    return CreateSparseBin(num_data, num_bin, default_bin);
  } else {
    *is_sparse = false;
    return CreateDenseBin(num_data, num_bin, default_bin);
  }
}

Bin* Bin::CreateDenseBin(data_size_t num_data, int num_bin, int default_bin) {
  if (num_bin <= 256) {
    return new DenseBin<uint8_t>(num_data, default_bin);
  } else if (num_bin <= 65536) {
    return new DenseBin<uint16_t>(num_data, default_bin);
  } else {
    return new DenseBin<uint32_t>(num_data, default_bin);
  }
}

Bin* Bin::CreateSparseBin(data_size_t num_data, int num_bin, int default_bin) {
  if (num_bin <= 256) {
    return new SparseBin<uint8_t>(num_data, default_bin);
  } else if (num_bin <= 65536) {
    return new SparseBin<uint16_t>(num_data, default_bin);
  } else {
    return new SparseBin<uint32_t>(num_data, default_bin);
  }
}

}  // namespace LightGBM
<commit_msg>fixed a bug in bin.cpp<commit_after>#include <LightGBM/utils/common.h>
#include <LightGBM/bin.h>

#include "dense_bin.hpp"
#include "sparse_bin.hpp"

#include <cmath>
#include <cstring>
#include <cstdint>

#include <limits>
#include <vector>
#include <algorithm>

namespace LightGBM {

BinMapper::BinMapper()
  :bin_upper_bound_(nullptr) {
}

// deep copy function for BinMapper
BinMapper::BinMapper(const BinMapper& other)
  : bin_upper_bound_(nullptr) {
  num_bin_ = other.num_bin_;
  is_trival_ = other.is_trival_;
  sparse_rate_ = other.sparse_rate_;
  bin_upper_bound_ = new float[num_bin_];
  for (int i = 0; i < num_bin_; ++i) {
    bin_upper_bound_[i] = other.bin_upper_bound_[i];
  }
}

BinMapper::BinMapper(const void* memory)
  :bin_upper_bound_(nullptr) {
  CopyFrom(reinterpret_cast<const char*>(memory));
}

BinMapper::~BinMapper() {
  delete[] bin_upper_bound_;
}

void BinMapper::FindBin(std::vector<float>* values, int max_bin) {
  std::vector<float>& ref_values = (*values);
  size_t sample_size = values->size();
  // find distinct_values first
  std::vector<float> distinct_values;
  std::vector<int> counts;

  std::sort(ref_values.begin(), ref_values.end());
  distinct_values.push_back(ref_values[0]);
  counts.push_back(1);
  for (size_t i = 1; i < ref_values.size(); ++i) {
    if (ref_values[i] != ref_values[i - 1]) {
      distinct_values.push_back(ref_values[i]);
      counts.push_back(1);
    } else {
      ++counts.back();
    }
  }
  int num_values = static_cast<int>(distinct_values.size());
  int cnt_in_bin0 = 0;

  if (num_values <= max_bin) {
    // use distinct value is enough
    num_bin_ = num_values;
    bin_upper_bound_ = new float[num_values];
    for (int i = 0; i < num_values - 1; ++i) {
      bin_upper_bound_[i] = (distinct_values[i] + distinct_values[i + 1]) / 2;
    }
    cnt_in_bin0 = counts[0];
    bin_upper_bound_[num_values - 1] = std::numeric_limits<float>::infinity();
  } else {
    // mean size for one bin
    float mean_bin_size = sample_size / static_cast<float>(max_bin);
    int rest_sample_cnt = static_cast<int>(sample_size);
    int bin_cnt = 0;

    num_bin_ = max_bin;
    std::vector<float> upper_bounds(max_bin, std::numeric_limits<float>::infinity());
    std::vector<float> lower_bounds(max_bin, std::numeric_limits<float>::infinity());
    // sort by count, descent
    Common::SortForPair(counts, distinct_values, 0, true);
    // fetch big slot as unique bin
    while (counts[bin_cnt] > mean_bin_size) {
      upper_bounds[bin_cnt] = distinct_values[bin_cnt];
      lower_bounds[bin_cnt] = distinct_values[bin_cnt];
      rest_sample_cnt -= counts[bin_cnt];
      ++bin_cnt;
    }
    // process reminder bins
    if (bin_cnt < max_bin) {
      // sort rest by values
      Common::SortForPair<float, int>(distinct_values, counts, bin_cnt, false);
      mean_bin_size = rest_sample_cnt / static_cast<float>(max_bin - bin_cnt);
      lower_bounds[bin_cnt] = distinct_values[bin_cnt];
      int cur_cnt_inbin = 0;
      for (int i = bin_cnt; i < num_values - 1; ++i) {
        rest_sample_cnt -= counts[i];
        cur_cnt_inbin += counts[i];
        // need a new bin
        if (cur_cnt_inbin >= mean_bin_size) {
          upper_bounds[bin_cnt] = distinct_values[i];
          if (bin_cnt == 0) { cnt_in_bin0 = cur_cnt_inbin; }
          ++bin_cnt;
          lower_bounds[bin_cnt] = distinct_values[i + 1];
          if (bin_cnt >= max_bin - 1) break;
          cur_cnt_inbin = 0;
          mean_bin_size = rest_sample_cnt / static_cast<float>(max_bin - bin_cnt);
        }
      }
      cur_cnt_inbin += counts[num_values - 1];

    }
    Common::SortForPair<float, float>(lower_bounds, upper_bounds, 0, false);
    // update bin upper bound
    bin_upper_bound_ = new float[bin_cnt];
    num_bin_ = bin_cnt;
    for (int i = 0; i < bin_cnt - 1; ++i) {
      bin_upper_bound_[i] = (upper_bounds[i] + lower_bounds[i + 1]) / 2.0f;
    }
    // last bin upper bound
    bin_upper_bound_[bin_cnt - 1] = std::numeric_limits<float>::infinity();
  }
  // check trival(num_bin_ == 1) feature
  if (num_bin_ <= 1) {
    is_trival_ = true;
  } else {
    is_trival_ = false;
  }
  // calculate sparse rate
  sparse_rate_ = static_cast<float>(cnt_in_bin0) / static_cast<float>(sample_size);
}

int BinMapper::SizeForSpecificBin(int bin) {
  int size = 0;
  size += sizeof(int);
  size += sizeof(bool);
  size += sizeof(float);
  size += bin * sizeof(float);
  return size;
}

void BinMapper::CopyTo(char * buffer) {
  std::memcpy(buffer, &num_bin_, sizeof(num_bin_));
  buffer += sizeof(num_bin_);
  std::memcpy(buffer, &is_trival_, sizeof(is_trival_));
  buffer += sizeof(is_trival_);
  std::memcpy(buffer, &sparse_rate_, sizeof(sparse_rate_));
  buffer += sizeof(sparse_rate_);
  std::memcpy(buffer, bin_upper_bound_, num_bin_ * sizeof(float));
}

void BinMapper::CopyFrom(const char * buffer) {
  std::memcpy(&num_bin_, buffer, sizeof(num_bin_));
  buffer += sizeof(num_bin_);
  std::memcpy(&is_trival_, buffer, sizeof(is_trival_));
  buffer += sizeof(is_trival_);
  std::memcpy(&sparse_rate_, buffer, sizeof(sparse_rate_));
  buffer += sizeof(sparse_rate_);
  if (bin_upper_bound_ != nullptr) { delete[] bin_upper_bound_; }
  bin_upper_bound_ = new float[num_bin_];
  std::memcpy(bin_upper_bound_, buffer, num_bin_ * sizeof(float));
}

void BinMapper::SaveBinaryToFile(FILE* file) const {
  fwrite(&num_bin_, sizeof(num_bin_), 1, file);
  fwrite(&is_trival_, sizeof(is_trival_), 1, file);
  fwrite(&sparse_rate_, sizeof(sparse_rate_), 1, file);
  fwrite(bin_upper_bound_, sizeof(float), num_bin_, file);
}

size_t BinMapper::SizesInByte() const {
  return sizeof(num_bin_) + sizeof(is_trival_) + sizeof(sparse_rate_) + sizeof(float) * num_bin_;
}

template class DenseBin<uint8_t>;
template class DenseBin<uint16_t>;
template class DenseBin<uint32_t>;

template class SparseBin<uint8_t>;
template class SparseBin<uint16_t>;
template class SparseBin<uint32_t>;

template class OrderedSparseBin<uint8_t>;
template class OrderedSparseBin<uint16_t>;
template class OrderedSparseBin<uint32_t>;

Bin* Bin::CreateBin(data_size_t num_data, int num_bin, float sparse_rate, bool is_enable_sparse, bool* is_sparse, int default_bin) {
  // sparse threshold
  const float kSparseThreshold = 0.8f;
  if (sparse_rate >= kSparseThreshold && is_enable_sparse) {
    *is_sparse = true;
    return CreateSparseBin(num_data, num_bin, default_bin);
  } else {
    *is_sparse = false;
    return CreateDenseBin(num_data, num_bin, default_bin);
  }
}

Bin* Bin::CreateDenseBin(data_size_t num_data, int num_bin, int default_bin) {
  if (num_bin <= 256) {
    return new DenseBin<uint8_t>(num_data, default_bin);
  } else if (num_bin <= 65536) {
    return new DenseBin<uint16_t>(num_data, default_bin);
  } else {
    return new DenseBin<uint32_t>(num_data, default_bin);
  }
}

Bin* Bin::CreateSparseBin(data_size_t num_data, int num_bin, int default_bin) {
  if (num_bin <= 256) {
    return new SparseBin<uint8_t>(num_data, default_bin);
  } else if (num_bin <= 65536) {
    return new SparseBin<uint16_t>(num_data, default_bin);
  } else {
    return new SparseBin<uint32_t>(num_data, default_bin);
  }
}

}  // namespace LightGBM
<|endoftext|>


<commit_before>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/application_manager/local_fetcher.h"

#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/common/data_pipe_utils.h"
#include <sys/stat.h>
#include "url/url_util.h"

namespace shell {

namespace {

void IgnoreResult(bool result) {
}

}  // namespace

// A loader for local files.
LocalFetcher::LocalFetcher(const GURL& url,
                           const GURL& url_without_query,
                           const FetchCallback& loader_callback)
    : Fetcher(loader_callback), url_(url), path_(UrlToFile(url_without_query)) {
  TRACE_EVENT1("mojo_shell", "LocalFetcher::LocalFetcher", "url", url.spec());
  loader_callback_.Run(make_scoped_ptr(this));
}

base::FilePath LocalFetcher::UrlToFile(const GURL& url) {
  DCHECK(url.SchemeIsFile());
  url::RawCanonOutputW<1024> output;
  url::DecodeURLEscapeSequences(url.path().data(),
                                static_cast<int>(url.path().length()), &output);
  base::string16 decoded_path = base::string16(output.data(), output.length());
  return base::FilePath(base::UTF16ToUTF8(decoded_path));
}

const GURL& LocalFetcher::GetURL() const {
  return url_;
}

GURL LocalFetcher::GetRedirectURL() const {
  return GURL::EmptyGURL();
}

mojo::URLResponsePtr LocalFetcher::AsURLResponse(base::TaskRunner* task_runner,
                                                 uint32_t skip) {
  mojo::URLResponsePtr response(mojo::URLResponse::New());
  response->url = mojo::String::From(url_);
  mojo::DataPipe data_pipe;
  response->body = data_pipe.consumer_handle.Pass();
  base::stat_wrapper_t stat_result;
  if (stat64(path_.value().c_str(), &stat_result) == 0) {
    response->headers = mojo::Array<mojo::String>(2);
    response->headers[0] =
        base::StringPrintf("Content-Length: %" PRId64, stat_result.st_size);
    response->headers[1] = base::StringPrintf(
        "ETag: \"%" PRId64 "-%" PRId64 "-%" PRId64 "\"", stat_result.st_dev,
        stat_result.st_ino, static_cast<uint64_t>(stat_result.st_mtime));
  }
  mojo::common::CopyFromFile(path_, data_pipe.producer_handle.Pass(), skip,
                             task_runner, base::Bind(&IgnoreResult));
  return response.Pass();
}

void LocalFetcher::AsPath(
    base::TaskRunner* task_runner,
    base::Callback<void(const base::FilePath&, bool)> callback) {
  // Async for consistency with network case.
  base::MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
}

std::string LocalFetcher::MimeType() {
  return "";
}

bool LocalFetcher::HasMojoMagic() {
  std::string magic;
  ReadFileToString(path_, &magic, strlen(kMojoMagic));
  return magic == kMojoMagic;
}

bool LocalFetcher::PeekFirstLine(std::string* line) {
  std::string start_of_file;
  ReadFileToString(path_, &start_of_file, kMaxShebangLength);
  size_t return_position = start_of_file.find('\n');
  if (return_position == std::string::npos)
    return false;
  *line = start_of_file.substr(0, return_position + 1);
  return true;
}

}  // namespace shell
<commit_msg>Avoid using stat64 in local_fetcher<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/application_manager/local_fetcher.h"

#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/common/data_pipe_utils.h"
#include <sys/stat.h>
#include "url/url_util.h"

namespace shell {

namespace {

void IgnoreResult(bool result) {
}

}  // namespace

// A loader for local files.
LocalFetcher::LocalFetcher(const GURL& url,
                           const GURL& url_without_query,
                           const FetchCallback& loader_callback)
    : Fetcher(loader_callback), url_(url), path_(UrlToFile(url_without_query)) {
  TRACE_EVENT1("mojo_shell", "LocalFetcher::LocalFetcher", "url", url.spec());
  loader_callback_.Run(make_scoped_ptr(this));
}

base::FilePath LocalFetcher::UrlToFile(const GURL& url) {
  DCHECK(url.SchemeIsFile());
  url::RawCanonOutputW<1024> output;
  url::DecodeURLEscapeSequences(url.path().data(),
                                static_cast<int>(url.path().length()), &output);
  base::string16 decoded_path = base::string16(output.data(), output.length());
  return base::FilePath(base::UTF16ToUTF8(decoded_path));
}

const GURL& LocalFetcher::GetURL() const {
  return url_;
}

GURL LocalFetcher::GetRedirectURL() const {
  return GURL::EmptyGURL();
}

mojo::URLResponsePtr LocalFetcher::AsURLResponse(base::TaskRunner* task_runner,
                                                 uint32_t skip) {
  mojo::URLResponsePtr response(mojo::URLResponse::New());
  response->url = mojo::String::From(url_);
  mojo::DataPipe data_pipe;
  response->body = data_pipe.consumer_handle.Pass();
  base::stat_wrapper_t stat_result;
  if (stat(path_.value().c_str(), &stat_result) == 0) {
    response->headers = mojo::Array<mojo::String>(2);
    response->headers[0] =
        base::StringPrintf("Content-Length: %" PRId64, stat_result.st_size);
    response->headers[1] = base::StringPrintf(
        "ETag: \"%" PRId32 "-%" PRId64 "-%" PRId64 "\"", stat_result.st_dev,
        stat_result.st_ino, static_cast<uint64_t>(stat_result.st_mtime));
  }
  mojo::common::CopyFromFile(path_, data_pipe.producer_handle.Pass(), skip,
                             task_runner, base::Bind(&IgnoreResult));
  return response.Pass();
}

void LocalFetcher::AsPath(
    base::TaskRunner* task_runner,
    base::Callback<void(const base::FilePath&, bool)> callback) {
  // Async for consistency with network case.
  base::MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
}

std::string LocalFetcher::MimeType() {
  return "";
}

bool LocalFetcher::HasMojoMagic() {
  std::string magic;
  ReadFileToString(path_, &magic, strlen(kMojoMagic));
  return magic == kMojoMagic;
}

bool LocalFetcher::PeekFirstLine(std::string* line) {
  std::string start_of_file;
  ReadFileToString(path_, &start_of_file, kMaxShebangLength);
  size_t return_position = start_of_file.find('\n');
  if (return_position == std::string::npos)
    return false;
  *line = start_of_file.substr(0, return_position + 1);
  return true;
}

}  // namespace shell
<|endoftext|>


<commit_before>/**
 * @file
 *  Zenderer/Levels/LevelLoader.hpp - A loader for @a Zenderer level files.
 *
 * @author      George Kudrayvtsev (halcyon)
 * @version     1.0
 * @copyright   Apache License v2.0
 *  Licensed under the Apache License, Version 2.0 (the "License").         \n
 *  You may not use this file except in compliance with the License.        \n
 *  You may obtain a copy of the License at:
 *  http://www.apache.org/licenses/LICENSE-2.0                              \n
 *  Unless required by applicable law or agreed to in writing, software     \n
 *  distributed under the License is distributed on an "AS IS" BASIS,       \n
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n
 *  See the License for the specific language governing permissions and     \n
 *  limitations under the License.
 *
 * @addtogroup Levels
 * @{
 **/

#ifndef ZENDERER__LEVELS__LEVEL_LOADER_HPP
#define ZENDERER__LEVELS__LEVEL_LOADER_HPP

#include <regex>

#include "Zenderer/Assets/AssetManager.hpp"
#include "Zenderer/Graphics/Polygon.hpp"
#include "Zenderer/Graphics/Scene.hpp"
#include "Zenderer/Utilities/Utilities.hpp"
#include "Zenderer/Utilities/FileParser.hpp"
#include "Level.hpp"

namespace zen
{
namespace lvl
{
    /// Loads levels (go figure).
    class ZEN_API zLevelLoader
    {
    public:
        zLevelLoader(gfx::zScene& Scene, asset::zAssetManager& Assets) :
            m_Scene(Scene), m_Assets(Assets), m_Log(util::zLog::GetEngineLog())
        {
            m_levels.clear();
        }

        ~zLevelLoader()
        {
            for(auto& i : m_levels)
            {
                for(auto& j : i.lights)
                    ;//m_Scene.RemoveLight(j);

                for(auto& j : i.entities)
                    m_Scene.RemoveEntity(*j);

                i.valid = false;
            }

            m_levels.clear();
        }

        /// @todo Error checking.
        virtual bool LoadFromFile(const string_t& filename)
        {
            using std::stoi;
            using std::stod;

            std::ifstream file(filename);
            util::zFileParser Parser;
            level_t level;
            string_t line;

            level.valid = false;

            // The spec. states that the first object tag within a level must
            // be an entity, so we can safely parse everything prior to finding
            // one and consider that to be the metadata.
            Parser.LoadFromStreamUntil(file, "<entity>", 0, filename.c_str());
            level.metadata.author = Parser.GetFirstResult("author");
            level.metadata.description = Parser.GetFirstResult("description");

            // Back up so we see "<entity>" again for parsing in the loop.
            file.seekg(-10, std::ios::cur);

            // Find each block of data and parse it.
            std::vector<string_t> parts;
            while(std::getline(file, line))
            {
                util::strip(line);
                if(line.empty() || (line.size() >= 2 && line.substr(0, 2) == '//'))
                    continue;

                else if(line.find("<entity") == 0)
                {
                    gfx::zPolygon Poly(m_Assets);
                    obj::zEntity& Latest = m_Scene.AddEntity();
                    Parser.LoadFromStreamUntil(file, "</entity>", file.tellg(),
                                               filename.c_str());

                    parts = util::split(Parser.PopResult("position", "0,0"), ',');

                    Latest.SetDepth(stoi(Parser.PopResult("depth", "1")));
                    Latest.Move(stod(parts[0]), stod(parts[1]));

                    string_t result;
                    do
                    {
                        result = Parser.PopResult("vertex");
                        parts = util::split(result, ',');
                        Poly.AddVertex(math::vector_t(stod(parts[0]), stod(parts[1])));
                    } while(!result.empty());

                    parts = util::split(Parser.PopResult("indices"), ',');
                    if(!parts.empty())
                    {
                        std::vector<gfxcore::index_t> indices(parts.size());
                        Poly.SetIndices(indices);
                    }

                    result = Parser.PopResult("stretch");
                    if(util::zFileParser::ResultToBool(result))
                    {
                        /// @todo
                    }

                    gfx::zMaterial M(m_Assets);
                    result = Parser.PopResult("texture");
                    M.LoadTextureFromFile(result);
                    Poly.AttachMaterial(std::move(M));

                    result = Parser.PopResult("attributes", "0x00");
                    uint8_t attr = this->ParseAttribute(result);
                    /// @todo

                    level.entities.emplace_back(&Latest);
                }

                /// @todo Differentiate between player and enemy spawns.
                else if(line.find("<spawn") == 0)
                {
                    std::ssmatch type;
                    if(!std::regex_match(line, std::regex("<spawn type=\"([A-Z]+)\">"),
                                         std::regex_constants::icase, type))
                    {
                        /// @todo
                        return;
                    }

                    spawn_t point;
                    point.type == SpawnType::ENEMY_SPAWN;

                    if      (type[0] == "PLAYER") point.type = SpawnType::PLAYER_SPAWN;
                    else if (type[0] == "ITEM")   point.type = SpawnType::ITEM_SPAWN;

                    Parser.LoadFromStreamUntil(file, "</spawn>",
                                               file.tellg(), filename.c_str());

                    parts = util::split(Parser.PopResult("position"), ',');
                    point.position = math::vector_t(stod(parts[0]), stod(parts[1]));

                    point.whitelist = util::split(Parser.PopResult("whitelist"), ',');
                    point.blacklist = util::split(Parser.PopResult("blacklist"), ',');
                }

                else if(line.find("<light type=\"") == 0)
                {
                    std::ssmatch type;
                    if(!std::regex_match(line, std::regex("<spawn type=\"([A-Z]+)\">"),
                                         std::regex_constants::icase, type))
                    {
                        /// @todo
                        return;
                    }

                    gfx::LightType lType = gfx::LightType::ZEN_AMBIENT;
                    else if (type[0] == "POINT")    lType = gfx::LightType::ZEN_POINT;
                    else if (type[0] == "SPOT")     lType = gfx::LightType::ZEN_SPOTLIGHT;

                    gfx::zLight& Light = m_Scene.AddLight(lType);
                    Light.Init();

                    Parser.LoadFromStreamUntil(file, "</light>", file.tellg(),
                                               filename.c_str());

                    parts = util::split(Parser.PopResult("color"), ',');
                    Light.SetColor(stod(parts[0]), stod(parts[1]), stod(parts[2]));

                    Light.SetBrightness(stod(
                        Parser.PopResult("brightness", "0.01")));

                    if(Light.GetType() != gfx::LightType::ZEN_AMBIENT)
                    {
                        parts = util::split(Parser.PopResult("position"), ',');
                        Light.SetPosition(stod(parts[0]), stod(parts[1]));

                        parts = util::split(Parser.PopResult("attenuation"), ',');
                        Light.SetAttenuation(stod(parts[0]),
                                             stod(parts[1]),
                                             stod(parts[2]));

                        if(Light.GetType() == gfx::LightType::ZEN_SPOTLIGHT)
                        {
                            Light.SetMaximumAngle(stod(Parser.PopResult("maxangle")));
                            Light.SetMinimumAngle(stod(Parser.PopResult("minangle")));
                        }
                    }
                }

                else
                {
                    m_Log << m_Log.SetMode(util::LogMode::ZEN_DEBUG)
                          << m_Log.SetSystem("Level") << "Unrecognized line: "
                          << line << util::zLog::endl;
                }
            }

            if(level.valid) m_levels.emplace_back(std::move(level));
            return level.valid;
        }

        bool PopLevel(level_t& lvl)
        {
            if(m_levels.empty()) return false;
            lvl = m_levels.front();
            m_levels.erase(m_levels.begin());
            return true;
        }

    private:
        uint8_t ParseAttribute(const string_t& hex)
        {
            return static_cast<uint8_t>(std::stoul(hex, nullptr, 16));
        }

        util::zLog& m_Log;
        gfx::zScene& m_Scene;
        asset::zAssetManager& m_Assets;
        std::vector<level_t> m_levels;
    };
}
}

#endif // ZENDERER__LEVELS__LEVEL_LOADER_HPP

/** @} **/
<commit_msg>#4: Actually add primitive to the entity.<commit_after>/**
 * @file
 *  Zenderer/Levels/LevelLoader.hpp - A loader for @a Zenderer level files.
 *
 * @author      George Kudrayvtsev (halcyon)
 * @version     1.0
 * @copyright   Apache License v2.0
 *  Licensed under the Apache License, Version 2.0 (the "License").         \n
 *  You may not use this file except in compliance with the License.        \n
 *  You may obtain a copy of the License at:
 *  http://www.apache.org/licenses/LICENSE-2.0                              \n
 *  Unless required by applicable law or agreed to in writing, software     \n
 *  distributed under the License is distributed on an "AS IS" BASIS,       \n
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n
 *  See the License for the specific language governing permissions and     \n
 *  limitations under the License.
 *
 * @addtogroup Levels
 * @{
 **/

#ifndef ZENDERER__LEVELS__LEVEL_LOADER_HPP
#define ZENDERER__LEVELS__LEVEL_LOADER_HPP

#include <regex>

#include "Zenderer/Assets/AssetManager.hpp"
#include "Zenderer/Graphics/Polygon.hpp"
#include "Zenderer/Graphics/Scene.hpp"
#include "Zenderer/Utilities/Utilities.hpp"
#include "Zenderer/Utilities/FileParser.hpp"
#include "Level.hpp"

namespace zen
{
namespace lvl
{
    /// Loads levels (go figure).
    class ZEN_API zLevelLoader
    {
    public:
        zLevelLoader(gfx::zScene& Scene, asset::zAssetManager& Assets) :
            m_Scene(Scene), m_Assets(Assets), m_Log(util::zLog::GetEngineLog())
        {
            m_levels.clear();
        }

        ~zLevelLoader()
        {
            for(auto& i : m_levels)
            {
                for(auto& j : i.lights)
                    ;//m_Scene.RemoveLight(j);

                for(auto& j : i.entities)
                    m_Scene.RemoveEntity(*j);

                i.valid = false;
            }

            m_levels.clear();
        }

        /// @todo Error checking.
        virtual bool LoadFromFile(const string_t& filename)
        {
            using std::stoi;
            using std::stod;

            std::ifstream file(filename);
            util::zFileParser Parser;
            level_t level;
            string_t line;

            level.valid = false;

            // The spec. states that the first object tag within a level must
            // be an entity, so we can safely parse everything prior to finding
            // one and consider that to be the metadata.
            Parser.LoadFromStreamUntil(file, "<entity>", 0, filename.c_str());
            level.metadata.author = Parser.GetFirstResult("author");
            level.metadata.description = Parser.GetFirstResult("description");

            // Back up so we see "<entity>" again for parsing in the loop.
            file.seekg(-10, std::ios::cur);

            // Find each block of data and parse it.
            std::vector<string_t> parts;
            while(std::getline(file, line))
            {
                util::strip(line);
                if(line.empty() || (line.size() >= 2 && line.substr(0, 2) == '//'))
                    continue;

                else if(line.find("<entity") == 0)
                {
                    gfx::zPolygon Poly(m_Assets);
                    obj::zEntity& Latest = m_Scene.AddEntity();
                    Parser.LoadFromStreamUntil(file, "</entity>", file.tellg(),
                                               filename.c_str());

                    parts = util::split(Parser.PopResult("position", "0,0"), ',');

                    Latest.SetDepth(stoi(Parser.PopResult("depth", "1")));
                    Latest.Move(stod(parts[0]), stod(parts[1]));

                    string_t result;
                    do
                    {
                        result = Parser.PopResult("vertex");
                        parts = util::split(result, ',');
                        Poly.AddVertex(math::vector_t(stod(parts[0]), stod(parts[1])));
                    } while(!result.empty());

                    parts = util::split(Parser.PopResult("indices"), ',');
                    if(!parts.empty())
                    {
                        std::vector<gfxcore::index_t> indices(parts.size());
                        Poly.SetIndices(indices);
                    }

                    result = Parser.PopResult("stretch");
                    if(util::zFileParser::ResultToBool(result))
                    {
                        /// @todo
                    }

                    gfx::zMaterial M(m_Assets);
                    result = Parser.PopResult("texture");
                    M.LoadTextureFromFile(result);
                    Poly.AttachMaterial(std::move(M));
                    Poly.Create(false);

                    result = Parser.PopResult("attributes", "0x00");
                    uint8_t attr = this->ParseAttribute(result);
                    /// @todo

                    Latest.AddPrimitive(std::move(Poly));
                    level.entities.emplace_back(&Latest);
                }

                /// @todo Differentiate between player and enemy spawns.
                else if(line.find("<spawn") == 0)
                {
                    std::ssmatch type;
                    if(!std::regex_match(line, std::regex("<spawn type=\"([A-Z]+)\">"),
                                         std::regex_constants::icase, type))
                    {
                        /// @todo
                        return;
                    }

                    spawn_t point;
                    point.type == SpawnType::ENEMY_SPAWN;

                    if      (type[0] == "PLAYER") point.type = SpawnType::PLAYER_SPAWN;
                    else if (type[0] == "ITEM")   point.type = SpawnType::ITEM_SPAWN;

                    Parser.LoadFromStreamUntil(file, "</spawn>",
                                               file.tellg(), filename.c_str());

                    parts = util::split(Parser.PopResult("position"), ',');
                    point.position = math::vector_t(stod(parts[0]), stod(parts[1]));

                    point.whitelist = util::split(Parser.PopResult("whitelist"), ',');
                    point.blacklist = util::split(Parser.PopResult("blacklist"), ',');
                }

                else if(line.find("<light type=\"") == 0)
                {
                    std::ssmatch type;
                    if(!std::regex_match(line, std::regex("<spawn type=\"([A-Z]+)\">"),
                                         std::regex_constants::icase, type))
                    {
                        /// @todo
                        return;
                    }

                    gfx::LightType lType = gfx::LightType::ZEN_AMBIENT;
                    else if (type[0] == "POINT")    lType = gfx::LightType::ZEN_POINT;
                    else if (type[0] == "SPOT")     lType = gfx::LightType::ZEN_SPOTLIGHT;

                    gfx::zLight& Light = m_Scene.AddLight(lType);
                    Light.Init();

                    Parser.LoadFromStreamUntil(file, "</light>", file.tellg(),
                                               filename.c_str());

                    parts = util::split(Parser.PopResult("color"), ',');
                    Light.SetColor(stod(parts[0]), stod(parts[1]), stod(parts[2]));

                    Light.SetBrightness(stod(
                        Parser.PopResult("brightness", "0.01")));

                    if(Light.GetType() != gfx::LightType::ZEN_AMBIENT)
                    {
                        parts = util::split(Parser.PopResult("position"), ',');
                        Light.SetPosition(stod(parts[0]), stod(parts[1]));

                        parts = util::split(Parser.PopResult("attenuation"), ',');
                        Light.SetAttenuation(stod(parts[0]),
                                             stod(parts[1]),
                                             stod(parts[2]));

                        if(Light.GetType() == gfx::LightType::ZEN_SPOTLIGHT)
                        {
                            Light.SetMaximumAngle(stod(Parser.PopResult("maxangle")));
                            Light.SetMinimumAngle(stod(Parser.PopResult("minangle")));
                        }
                    }
                }

                else
                {
                    m_Log << m_Log.SetMode(util::LogMode::ZEN_DEBUG)
                          << m_Log.SetSystem("Level") << "Unrecognized line: "
                          << line << util::zLog::endl;
                }
            }

            if(level.valid) m_levels.emplace_back(std::move(level));
            return level.valid;
        }

        bool PopLevel(level_t& lvl)
        {
            if(m_levels.empty()) return false;
            lvl = m_levels.front();
            m_levels.erase(m_levels.begin());
            return true;
        }

    private:
        uint8_t ParseAttribute(const string_t& hex)
        {
            return static_cast<uint8_t>(std::stoul(hex, nullptr, 16));
        }

        util::zLog& m_Log;
        gfx::zScene& m_Scene;
        asset::zAssetManager& m_Assets;
        std::vector<level_t> m_levels;
    };
}
}

#endif // ZENDERER__LEVELS__LEVEL_LOADER_HPP

/** @} **/
<|endoftext|>


<commit_before>/*
 * CUDArrays is a library for easy multi-GPU program development.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2015 Barcelona Supercomputing Center and
 *                         University of Illinois
 *
 *  Developed by: Javier Cabezas <javier.cabezas@gmail.com>
 *
 * 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. */

#pragma once
#ifndef CUDARRAYS_DETAIL_UTILS_MISC_HPP_
#define CUDARRAYS_DETAIL_UTILS_MISC_HPP_

#include <type_traits>
#include <vector>

namespace utils {

namespace mpl {

template <typename T, class V1, class V2>
struct merge;

template <typename T, T... Values1, T... Values2, template <T...> class S>
struct merge<T, S<Values1...>, S<Values2...>> {
    using type = S<Values1..., Values2...>;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Generated>
struct fill_detail {
    using type = typename fill_detail<T, Size - 1, FillValue, S, FillValue, Generated...>::type;
};

template <typename T, T FillValue, template <T...> class S, T... Generated>
struct fill_detail<T, 0, FillValue, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S>
struct fill {
    using type = typename fill_detail<T, Size, FillValue, S>::type;
};

template <typename T, unsigned Size, T Current, template <T...> class S, T... Generated>
struct seq_inc_detail {
    using type = typename seq_inc_detail<T, Size - 1, Current + 1, S, Current, Generated...>::type;
};

template <typename T, T Current, template <T...> class S, T... Generated>
struct seq_inc_detail<T, 1, Current, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, template <T...> class S>
struct seq_inc {
    using type = typename seq_inc_detail<T, Size, 0, S>::type;
};

template <typename T, unsigned Size, T Current, template <T...> class S, T... Generated>
struct seq_dec_detail {
    using type = typename seq_dec_detail<T, Size - 1, Current - 1, S, Current, Generated...>::type;
};

template <typename T, T Current, template <T...> class S, T... Generated>
struct seq_dec_detail<T, 1, Current, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, template <T...> class S>
struct seq_dec {
    using type = typename seq_dec_detail<T, Size, Size - 1, S>::type;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Rest>
struct seq_prepend {
    using prepend_values_type = typename fill<T, Size - sizeof...(Rest), FillValue, S>::type;
    using type = typename merge<T, prepend_values_type, S<Rest...>>::type;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Rest>
struct seq_append {
    using append_values_type = typename fill<T, Size - sizeof...(Rest), FillValue, S>::type;
    using type = typename merge<T, S<Rest...>, append_values_type>::type;
};

}

template <typename T>
void
_get_factors(T n, std::vector<T> &factors)
{
    if (n <= 1) return;

    unsigned z = 2;
    while (z <= n) {
        if (n % z == 0) {
            break;
        }
        ++z;
    }
    factors.push_back(z);
    _get_factors(n/z, factors);
    return;
}

template <typename T>
std::vector<T>
get_factors(T n)
{
    std::vector<T> ret;

    _get_factors(n, ret);

    return ret;
}

template <class T, class U>
T div_ceil(T a, U b)
{
    static_assert(std::is_integral<T>::value &&
                  std::is_integral<U>::value, "div_ceil works on integral types only");
    ASSERT(b > U(0));
    T res = a / b;
    if (a % b != 0) ++res;
    return res;
}

template <class T, class U>
typename std::common_type<T, U>::type
round_next(T val, U step)
{
    static_assert(std::is_integral<T>::value &&
                  std::is_integral<U>::value, "round_next works on integral types only");
    if (val % step != 0)
        val = ((val / step) + 1) * step;
    return val;
}

#ifdef CUDARRAYS_UNITTEST
#define CUDARRAYS_TESTED(C,T) friend ::C##_##T##_Test;
#else
#define CUDARRAYS_TESTED(C,T)
#endif

#define CUDA_CALL(x)                                       \
do {                                                       \
    cudaError_t err__ = (x);                               \
    if (err__ != cudaSuccess) {                            \
        fprintf(stderr,                                    \
                "Error calling CUDA: %d. Message: '%s'\n", \
                err__,                                     \
                cudaGetErrorString(err__));                \
        abort();                                           \
    }                                                      \
} while (0)

#ifdef CUDARRAYS_UNITTEST
#define CUDARRAYS_TESTED(C,T) friend ::C##_##T##_Test;
#else
#define CUDARRAYS_TESTED(C,T)
#endif

#define CUDA_CALL(x)                                       \
do {                                                       \
    cudaError_t err__ = (x);                               \
    if (err__ != cudaSuccess) {                            \
        fprintf(stderr,                                    \
                "Error calling CUDA: %d. Message: '%s'\n", \
                err__,                                     \
                cudaGetErrorString(err__));                \
        abort();                                           \
    }                                                      \
} while (0)

}

#endif

/* vim:set ft=cpp backspace=2 tabstop=4 shiftwidth=4 textwidth=120 foldmethod=marker expandtab: */
<commit_msg>Remove duplicate macro definition.<commit_after>/*
 * CUDArrays is a library for easy multi-GPU program development.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2015 Barcelona Supercomputing Center and
 *                         University of Illinois
 *
 *  Developed by: Javier Cabezas <javier.cabezas@gmail.com>
 *
 * 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. */

#pragma once
#ifndef CUDARRAYS_DETAIL_UTILS_MISC_HPP_
#define CUDARRAYS_DETAIL_UTILS_MISC_HPP_

#include <type_traits>
#include <vector>

namespace utils {

namespace mpl {

template <typename T, class V1, class V2>
struct merge;

template <typename T, T... Values1, T... Values2, template <T...> class S>
struct merge<T, S<Values1...>, S<Values2...>> {
    using type = S<Values1..., Values2...>;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Generated>
struct fill_detail {
    using type = typename fill_detail<T, Size - 1, FillValue, S, FillValue, Generated...>::type;
};

template <typename T, T FillValue, template <T...> class S, T... Generated>
struct fill_detail<T, 0, FillValue, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S>
struct fill {
    using type = typename fill_detail<T, Size, FillValue, S>::type;
};

template <typename T, unsigned Size, T Current, template <T...> class S, T... Generated>
struct seq_inc_detail {
    using type = typename seq_inc_detail<T, Size - 1, Current + 1, S, Current, Generated...>::type;
};

template <typename T, T Current, template <T...> class S, T... Generated>
struct seq_inc_detail<T, 1, Current, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, template <T...> class S>
struct seq_inc {
    using type = typename seq_inc_detail<T, Size, 0, S>::type;
};

template <typename T, unsigned Size, T Current, template <T...> class S, T... Generated>
struct seq_dec_detail {
    using type = typename seq_dec_detail<T, Size - 1, Current - 1, S, Current, Generated...>::type;
};

template <typename T, T Current, template <T...> class S, T... Generated>
struct seq_dec_detail<T, 1, Current, S, Generated...> {
    using type = S<Generated...>;
};

template <typename T, unsigned Size, template <T...> class S>
struct seq_dec {
    using type = typename seq_dec_detail<T, Size, Size - 1, S>::type;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Rest>
struct seq_prepend {
    using prepend_values_type = typename fill<T, Size - sizeof...(Rest), FillValue, S>::type;
    using type = typename merge<T, prepend_values_type, S<Rest...>>::type;
};

template <typename T, unsigned Size, T FillValue, template <T...> class S, T... Rest>
struct seq_append {
    using append_values_type = typename fill<T, Size - sizeof...(Rest), FillValue, S>::type;
    using type = typename merge<T, S<Rest...>, append_values_type>::type;
};

}

template <typename T>
void
_get_factors(T n, std::vector<T> &factors)
{
    if (n <= 1) return;

    unsigned z = 2;
    while (z <= n) {
        if (n % z == 0) {
            break;
        }
        ++z;
    }
    factors.push_back(z);
    _get_factors(n/z, factors);
    return;
}

template <typename T>
std::vector<T>
get_factors(T n)
{
    std::vector<T> ret;

    _get_factors(n, ret);

    return ret;
}

template <class T, class U>
T div_ceil(T a, U b)
{
    static_assert(std::is_integral<T>::value &&
                  std::is_integral<U>::value, "div_ceil works on integral types only");
    ASSERT(b > U(0));
    T res = a / b;
    if (a % b != 0) ++res;
    return res;
}

template <class T, class U>
typename std::common_type<T, U>::type
round_next(T val, U step)
{
    static_assert(std::is_integral<T>::value &&
                  std::is_integral<U>::value, "round_next works on integral types only");
    if (val % step != 0)
        val = ((val / step) + 1) * step;
    return val;
}

#ifdef CUDARRAYS_UNITTEST
#define CUDARRAYS_TESTED(C,T) friend ::C##_##T##_Test;
#else
#define CUDARRAYS_TESTED(C,T)
#endif

#define CUDA_CALL(x)                                       \
do {                                                       \
    cudaError_t err__ = (x);                               \
    if (err__ != cudaSuccess) {                            \
        fprintf(stderr,                                    \
                "Error calling CUDA: %d. Message: '%s'\n", \
                err__,                                     \
                cudaGetErrorString(err__));                \
        abort();                                           \
    }                                                      \
} while (0)

}

#endif

/* vim:set ft=cpp backspace=2 tabstop=4 shiftwidth=4 textwidth=120 foldmethod=marker expandtab: */
<|endoftext|>