<commit_before>
extern "C" {
#include "string.h"
}

#include "Arduino.h"

#include "ESP8266Client.h"

#define AT "AT+\n"
#define AT_DISCONNECT "AT+CLOSE\n"
#define AT_RESET "AT+RST\n"
#define AT_WIFI_MODE "AT+CWMODE"
#define AT_JOIN_AP "AT+CWJAP"
#define AT_LIST_AP "AT+CWLAP"
#define AT_STATUS "AT+CIPSTATUS"
#define AT_TCPSTART "AT+CIPSTART"
#define AT_CIPSEND "AT+CIPSEND"
#define AT_GET_IP "AT+CIFSR"

#define MAX_SOCK_NUM 1

uint16_t ESP8266Client::_srcport = 1024;
//AT+CIPSTART="TCP","192.168.10.117",10000
//AT+CIPSTART="TCP","192.168.10.117",10000
char buffer[50];
SoftwareSerial *serialPort=0;

#define DEBUG_SERIAL

ESP8266Client::ESP8266Client() : _sock(MAX_SOCK_NUM) {
}

ESP8266Client::ESP8266Client(uint8_t sock) : _sock(sock) {
}

int ESP8266Client::connect(const char* host, uint16_t port) {
	// Look up the host first
	// No DNS implementation as of now
	return 1;
}
void ESP8266Client::setSerial( SoftwareSerial *port ){
	serialPort = port;
}
int ESP8266Client::connect(IPAddress ip, uint16_t port) {
	//Close anny connection
	serialPort->println("AT+CIPCLOSE");
	delay(20);

	uint8_t* rawAdress = rawIPAddress(ip);
	sprintf( buffer, "AT+CIPSTART=\"TCP\",\"%d.%d.%d.%d\",%d", rawAdress[0], rawAdress[1], rawAdress[2], rawAdress[3], port);
	serialPort->println(buffer);
	serialPort->setTimeout(5000);
	if( serialPort->find("OK\r\n") ){
		return true;
	} else {
		return false;
	}
}

size_t ESP8266Client::write(uint8_t b) {
	serialPort->print("AT+CIPSEND=1");
	if (serialPort->find(">"))
	{
		//OK
		serialPort->write(b);
		serialPort->println("\n");
		return sizeof(uint8_t);
	}else
	{
		serialPort->println("AT+CIPCLOSE");
		return 0;
	}
}

size_t ESP8266Client::write(const uint8_t *buf, size_t size) {
	//serialPort->write(buf,(size/sizeof(uint8_t)));
	sprintf( buffer, "AT+CIPSEND=%d\n", size/sizeof(uint8_t) );
	serialPort->print(buffer);
	if (serialPort->find(">"))
	{
		//OK
		serialPort->write(buf,(size/sizeof(uint8_t)));
		serialPort->print("\n");
		return size;
	} else {
		serialPort->println("AT+CIPCLOSE");
		return 0;
	}

}

int ESP8266Client::available() {
	serialPort->print(AT);
	if (serialPort->find("OK"))
	{
		return 1;
	}else{
		return 0;
	}

}

/*
 * Received data starts with +IPD
 */
int ESP8266Client::read() {
	serialPort->println("::read");
return 0;
/*uint8_t b;
 if ( recv(_sock, &b, 1) > 0 )
 {
 // recv worked
 return b;
 }
 else
 {
 // No data available
 return -1;
 }*/
}

int ESP8266Client::read(uint8_t *buf, size_t size) {
	serialPort->println("::read(uint8_t");
	//return recv(_sock, buf, size);
	return 0;
}

int ESP8266Client::peek() {
	serialPort->println("::peek");
	/*  uint8_t b;
	 // Unlike recv, peek doesn't check to see if there's any data available, so we must
	 if (!available())
	 return -1;
	 ::peek(_sock, &b);
	 return b;*/
	return 0;
}

void ESP8266Client::flush() {
	serialPort->println("::flush");
	while (available())
	read();
}

void ESP8266Client::stop() {
	serialPort->print( AT_DISCONNECT );
}

uint8_t ESP8266Client::connected() {
	return sendWaitRespond("AT+CIPSTATUS", "STATUS:3", 200 );
}

uint8_t ESP8266Client::status() {
	return sendWaitRespond("AT+CIPSTATUS", "STATUS:3", 200 );
}

// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.

ESP8266Client::operator bool() {
	return 1;
}

bool ESP8266Client::operator==(const ESP8266Client& rhs) {
	return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
}

bool ESP8266Client::connectAP(char *ssid, char *password) {
	char buffer[50];

	if( !sendWaitRespond("AT", "OK", 10000 ) ){
#ifdef DEBUG_SERIAL
		Serial.println("AT FAIL");
#endif
		return false;
	}
#ifdef DEBUG_SERIAL
		Serial.println("AT OK");
#endif
	serialPort->println("AT+CWQAP");
	delay(500);
	serialPort->println("AT+CWMODE=1");
	delay(500);
	sprintf( buffer, "AT+CWJAP=\"%s\",\"%s\"", ssid, password);
#ifdef DEBUG_SERIAL
	Serial.println(buffer);
#endif
	return sendWaitRespond(buffer, "OK", 10000 );
	/*serialPort->println( buffer );
	delay(2000);
	if(serialPort->find("OK")) {
		return true;
	} else {
		return false;
	}*/
}

bool ESP8266Client::sendWaitRespond( char *message, char *response, int msTimeout) {
	serialPort->println(message);
	serialPort->setTimeout(msTimeout);
	if( serialPort->find(response) ){
		return true;
	} else {
		serialPort->setTimeout(msTimeout);
		if( serialPort->find(response) ){
				return true;
		}else{
			return false;
		}
	}
}
<commit_msg>Adding Software Serial reading of buffer to handle busy signals<commit_after>
extern "C" {
#include "string.h"
}

#include "Arduino.h"

#include "ESP8266Client.h"

#define AT "AT"
#define AT_DISCONNECT "AT+CIPCLOSE"
#define AT_RESET "AT+RST"
#define AT_WIFI_MODE "AT+CWMODE"
#define AT_JOIN_AP "AT+CWJAP"
#define AT_LIST_AP "AT+CWLAP"
#define AT_STATUS "AT+CIPSTATUS"
#define AT_TCPSTART "AT+CIPSTART"
#define AT_CIPSEND "AT+CIPSEND"
#define AT_GET_IP "AT+CIFSR"

#define MAX_SOCK_NUM 1

uint16_t ESP8266Client::_srcport = 1024;
//AT+CIPSTART="TCP","192.168.10.117",10000
//AT+CIPSTART="TCP","192.168.10.117",10000
char buffer[50];
SoftwareSerial *serialPort=0;

#define DEBUG_SERIAL
/*
 * Using a modified SoftwareSerial library to read directly what is on the Serial Buffer
 * Official SoftwareSerial has receive buffer private, modified to use it public
 */
ESP8266Client::ESP8266Client() : _sock(MAX_SOCK_NUM) {
}

ESP8266Client::ESP8266Client(uint8_t sock) : _sock(sock) {
}

int ESP8266Client::connect(const char* host, uint16_t port) {
	// Look up the host first
	// No DNS implementation as of now
	return 1;
}
void ESP8266Client::setSerial( SoftwareSerial *port ){
	serialPort = port;
}
int ESP8266Client::connect(IPAddress ip, uint16_t port) {
	//Close anny connection
	serialPort->println("AT+CIPCLOSE");
	delay(20);

	uint8_t* rawAdress = rawIPAddress(ip);
	sprintf( buffer, "AT+CIPSTART=\"TCP\",\"%d.%d.%d.%d\",%d", rawAdress[0], rawAdress[1], rawAdress[2], rawAdress[3], port);
	serialPort->println(buffer);
	serialPort->setTimeout(5000);
	if( serialPort->find("OK\r\n") ){
		return true;
	} else {
		return false;
	}
}

size_t ESP8266Client::write(uint8_t b) {
	serialPort->print("AT+CIPSEND=1");
	if (serialPort->find(">"))
	{
		//OK
		serialPort->write(b);
		serialPort->println("\n");
		return sizeof(uint8_t);
	}else
	{
		serialPort->println("AT+CIPCLOSE");
		return 0;
	}
}

size_t ESP8266Client::write(const uint8_t *buf, size_t size) {
	//serialPort->write(buf,(size/sizeof(uint8_t)));
	sprintf( buffer, "AT+CIPSEND=%d\n", size/sizeof(uint8_t) );
	serialPort->print(buffer);
	if (serialPort->find(">"))
	{
		//OK
		serialPort->write(buf,(size/sizeof(uint8_t)));
		serialPort->print("\n");
		return size;
	} else {
		serialPort->println("AT+CIPCLOSE");
		return 0;
	}

}

int ESP8266Client::available() {
	if (sendWaitRespond(AT, "OK", 10000 ))
	{
		return 1;
	}else{
		return 0;
	}

}

/*
 * Received data starts with +IPD
 */
int ESP8266Client::read() {
	serialPort->println("::read");
return 0;
/*uint8_t b;
 if ( recv(_sock, &b, 1) > 0 )
 {
 // recv worked
 return b;
 }
 else
 {
 // No data available
 return -1;
 }*/
}

int ESP8266Client::read(uint8_t *buf, size_t size) {
	serialPort->println("::read(uint8_t");
	//return recv(_sock, buf, size);
	return 0;
}

int ESP8266Client::peek() {
	serialPort->println("::peek");
	/*  uint8_t b;
	 // Unlike recv, peek doesn't check to see if there's any data available, so we must
	 if (!available())
	 return -1;
	 ::peek(_sock, &b);
	 return b;*/
	return 0;
}

void ESP8266Client::flush() {
	serialPort->println("::flush");
	while (available())
	read();
}

void ESP8266Client::stop() {
	serialPort->print( AT_DISCONNECT );
}

uint8_t ESP8266Client::connected() {
#ifdef DEBUG_SERIAL
	Serial.println("::connected()");
#endif
	return sendWaitRespond("AT+CIPSTATUS", "STATUS:5", 300 );
}

uint8_t ESP8266Client::status() {
#ifdef DEBUG_SERIAL
	Serial.println("::status()");
#endif
	return sendWaitRespond("AT+CIPSTATUS", "STATUS:5", 300 );
}

// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.

ESP8266Client::operator bool() {
	return 1;
}

bool ESP8266Client::operator==(const ESP8266Client& rhs) {
	return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
}

bool ESP8266Client::connectAP(char *ssid, char *password) {
	char buffer[50];

	if( !sendWaitRespond("AT", "OK", 300 ) ){
		!sendWaitRespond("AT+RST", "wwww.", 500 );
		if( !sendWaitRespond("AT", "OK", 300 ) ){
			#ifdef DEBUG_SERIAL
			Serial.println("AT FAIL");
			#endif
			return false;
		}

	}
#ifdef DEBUG_SERIAL
		Serial.println("AT OK");
#endif
	serialPort->println("AT+CWQAP");
	delay(500);
	serialPort->println("AT+CWMODE=1");
	delay(500);
	sprintf( buffer, "AT+CWJAP=\"%s\",\"%s\"", ssid, password);

	return sendWaitRespond(buffer, "OK", 10000 );
	/*serialPort->println( buffer );
	delay(2000);
	if(serialPort->find("OK")) {
		return true;
	} else {
		return false;
	}*/
}
String recBuffer;
bool ESP8266Client::sendWaitRespond( char *message, char *response, int msTimeout) {
	bool bussy = false;
	do{
		bussy = false;
		serialPort->println(message);
		serialPort->setTimeout(msTimeout);
		#ifdef DEBUG_SERIAL
			Serial.println(message);
		#endif

		if( serialPort->find(response) ){
			#ifdef DEBUG_SERIAL
					Serial.println("ret true");
					serialPort->flush();
			#endif
				return true;
		}
		if( strstr(serialPort->_receive_buffer, "busy p")){
			bussy =true;
			#ifdef DEBUG_SERIAL
				Serial.println("bussy");
				serialPort->flush();
			#endif
		}
	}while(bussy);
	#ifdef DEBUG_SERIAL
		Serial.println(serialPort->_receive_buffer);
		Serial.println("ret false");
	#endif
	return false;
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "normalmappingmodifier.h"

// appleseed.renderer headers.
#include "renderer/modeling/input/source.h"

// appleseed.foundation headers.
#include "foundation/image/color.h"
#include "foundation/math/basis.h"

// Standard headers.
#include <cassert>

using namespace foundation;

namespace renderer
{

NormalMappingModifier::NormalMappingModifier(
    const Source*       map,
    const UpVector      up_vector)
  : m_map(map)
  , m_y(up_vector == UpVectorY ? 1 : 2)
{
}

Vector3d NormalMappingModifier::evaluate(
    TextureCache&       texture_cache,
    const Vector3d&     n,
    const Vector2d&     uv,
    const Vector3d&     dpdu,
    const Vector3d&     dpdv) const
{
    // Lookup the normal map.
    Color3f normal_rgb;
    m_map->evaluate(texture_cache, uv, normal_rgb);

    // Reconstruct the normal from the texel value.
    const Vector3d normal(
        static_cast<double>(normal_rgb[0]) * 2.0 - 1.0,
        static_cast<double>(normal_rgb[m_y]) * 2.0 - 1.0,
        static_cast<double>(normal_rgb[3 - m_y]) * 2.0 - 1.0);

    // Transform the normal to world space and normalize it.
    const Basis3d basis(n, dpdu);
    return normalize(basis.transform_to_parent(normal));
}

}   // namespace renderer
<commit_msg>added an assertion and tweaked a comment.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "normalmappingmodifier.h"

// appleseed.renderer headers.
#include "renderer/modeling/input/source.h"

// appleseed.foundation headers.
#include "foundation/image/color.h"
#include "foundation/math/basis.h"

// Standard headers.
#include <cassert>

using namespace foundation;

namespace renderer
{

NormalMappingModifier::NormalMappingModifier(
    const Source*       map,
    const UpVector      up_vector)
  : m_map(map)
  , m_y(up_vector == UpVectorY ? 1 : 2)
{
}

Vector3d NormalMappingModifier::evaluate(
    TextureCache&       texture_cache,
    const Vector3d&     n,
    const Vector2d&     uv,
    const Vector3d&     dpdu,
    const Vector3d&     dpdv) const
{
    assert(is_normalized(n));

    // Lookup the normal map.
    Color3f normal_rgb;
    m_map->evaluate(texture_cache, uv, normal_rgb);

    // Reconstruct the normal from the texel value.
    const Vector3d normal(
        static_cast<double>(normal_rgb[0]) * 2.0 - 1.0,
        static_cast<double>(normal_rgb[m_y]) * 2.0 - 1.0,
        static_cast<double>(normal_rgb[3 - m_y]) * 2.0 - 1.0);

    // Transform the normal to parent space and normalize it.
    const Basis3d basis(n, dpdu);
    return normalize(basis.transform_to_parent(normal));
}

}   // namespace renderer
<|endoftext|>


<commit_before>#include "EntityManager.hpp"

#ifndef KENGINE_MAX_SAVE_PATH_LENGTH
# define KENGINE_MAX_SAVE_PATH_LENGTH 64
#endif

#ifndef KENGINE_MAX_COMPONENT_NAME_LENGTH
# define KENGINE_MAX_COMPONENT_NAME_LENGTH 64
#endif

namespace kengine {
	Entity EntityManager::getEntity(Entity::ID id) {
		detail::ReadLock l(_entitiesMutex);
		return Entity(id, _entities[id].mask, this);
	}

	EntityView EntityManager::getEntity(Entity::ID id) const {
		detail::ReadLock l(_entitiesMutex);
		return EntityView(id, _entities[id].mask);
	}

	void EntityManager::removeEntity(EntityView e) {
		removeEntity(e.id);
	}

	void EntityManager::removeEntity(Entity::ID id) {
		detail::WriteLock l(_updatesMutex);
		if (_updatesLocked) {
			_removals.push_back({ id });
		}
		else
			doRemove(id);
	}

	void EntityManager::setEntityActive(EntityView e, bool active) {
		setEntityActive(e.id, active);
	}

	void EntityManager::setEntityActive(Entity::ID id, bool active) {
		detail::WriteLock l(_entitiesMutex);
		_entities[id].active = active;
		_entities[id].shouldActivateAfterInit = active;
	}

	struct ComponentIDSave {
		size_t id;
		putils::string<KENGINE_MAX_COMPONENT_NAME_LENGTH> name;
	};

	void EntityManager::load(const char * directory) {
		{
			detail::WriteLock l(_archetypesMutex);
			_archetypes.clear();
		}

		{
			detail::WriteLock l(_toReuseMutex);
			_toReuse.clear();
		}

		for (auto & e : getEntities())
			SystemManager::removeEntity(e);

		{
			detail::ReadLock l(_components.mutex);
			for (const auto &[_, meta] : _components.map)
				meta->load(directory);
		}

		size_t idMap[KENGINE_COMPONENT_COUNT]; // index = new, value = old
		for (auto & i : idMap)
			i = (size_t)-1;
		{
			detail::ReadLock l(_components.mutex);

			std::ifstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/components.bin", directory), std::ifstream::binary);
			assert(f);
			size_t size;
			f.read((char *)&size, sizeof(size));
			for (size_t i = 0; i < size; ++i) {
				ComponentIDSave save;
				f.read((char *)&save, sizeof(save));
				assert(f.gcount() == sizeof(save));

				for (const auto & [_, meta] : _components.map)
					if (meta->funcs.name == save.name) {
						idMap[meta->id] = save.id;
						break;
					}
			}
		}

		std::ifstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/entities.bin", directory), std::ifstream::binary);
		assert(f);
		size_t size;
		f.read((char *)&size, sizeof(size));

		{
			detail::WriteLock l(_entitiesMutex);
			_entities.resize(size);
			f.read((char *)_entities.data(), size * sizeof(_entities[0]));
		}

		for (auto & e : getEntities()) {
				Entity::Mask tmp = 0;
				for (size_t i = 0; i < KENGINE_COMPONENT_COUNT; ++i) {
					const auto oldId = idMap[i];
					tmp[i] = oldId == (size_t)-1 ? false : e.componentMask[oldId];
				}
			updateMask(e.id, tmp, true);
		}

		{
			detail::ReadLock l(_entitiesMutex);
			size_t id = 0;
			for (const auto & e : _entities) {
				if (e.mask == 0) {
					detail::WriteLock l(_toReuseMutex);
					_toReuse.emplace_back(id);
			}
				++id;
			}
		}

		for (auto & e : getEntities())
			SystemManager::registerEntity(e);

		SystemManager::load(directory);
	}

	void EntityManager::save(const char * directory) const {
		SystemManager::save(directory);

		putils::vector<bool, KENGINE_COMPONENT_COUNT> serializable;

		{
			detail::ReadLock l(_components.mutex);
			serializable.resize(_components.map.size());
			for (const auto &[_, meta] : _components.map)
				serializable[meta->id] = meta->save(directory);

			// Save Component IDs
			std::ofstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/components.bin", directory), std::ofstream::binary);
			const size_t size = _components.map.size();
			f.write((const char *)&size, sizeof(size));
			for (const auto &[_, meta] : _components.map) {
				ComponentIDSave save;
				save.id = meta->id;
				save.name = meta->funcs.name;
				f.write((const char *)&save, sizeof(save));
			}
		}

		std::ofstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/entities.bin", directory), std::ofstream::binary);
		assert(f);

		{
			detail::ReadLock l(_entitiesMutex);
			const auto size = _entities.size();
			f.write((const char *)&size, sizeof(size));
			for (EntityMetadata e : _entities) {
				for (size_t i = 0; i < serializable.size(); ++i)
					e.mask[i] = e.mask[i] && serializable[i];
				f.write((const char *)&e, sizeof(e));
			}
		}
	}

	Entity EntityManager::alloc() {
		{
			detail::ReadLock l(_toReuseMutex);
			if (_toReuse.empty()) {
				detail::WriteLock l(_entitiesMutex);
				const auto id = _entities.size();
				_entities.push_back({ false, 0 });
				return Entity(id, 0, this);
			}
		}

		Entity::ID id;
		{
			detail::WriteLock l(_toReuseMutex);
			if (!_toReuseSorted) {
				std::sort(_toReuse.begin(), _toReuse.end(), std::greater<Entity::ID>());
				_toReuseSorted = true;
			}
			id = _toReuse.back();
			_toReuse.pop_back();
		}

#ifndef NDEBUG
		{
			detail::ReadLock l(_archetypesMutex);
			for (const auto & archetype : _archetypes) {
				detail::ReadLock l(archetype.mutex);
				assert(std::find(archetype.entities.begin(), archetype.entities.end(), id) == archetype.entities.end());
			}
		}

		{
			detail::ReadLock l(_entitiesMutex);
			assert(id < _entities.size());
		}
#endif

		return Entity(id, 0, this);
	}

	void EntityManager::addComponent(Entity::ID id, size_t component) {
		updateHasComponent(id, component, true);
	}

	void EntityManager::removeComponent(Entity::ID id, size_t component) {
		updateHasComponent(id, component, false);
	}

	void EntityManager::updateHasComponent(Entity::ID id, size_t component, bool newHasComponent) {
		{
			detail::WriteLock l(_updatesMutex);
			for (auto & update : _updates)
				if (update.id == id) {
					std::unique_lock<std::mutex> l(update.mutex);
					update.newMask[component] = newHasComponent;
					return;
				}
		}

		Entity::Mask currentMask;
		{
			detail::ReadLock l(_entitiesMutex);
			currentMask = _entities[id].mask;
		}

		auto updatedMask = currentMask;
		updatedMask[component] = newHasComponent;
		updateMask(id, updatedMask);
	}

	void EntityManager::updateMask(Entity::ID id, Entity::Mask newMask, bool ignoreOldMask) {
		detail::WriteLock l(_updatesMutex);
		if (_updatesLocked == 0)
			doUpdateMask(id, newMask, ignoreOldMask);
		else {
			Update update;
			update.id = id;
			update.newMask = newMask;
			update.ignoreOldMask = ignoreOldMask;
			_updates.push_back(std::move(update));
		}
	}

	void EntityManager::doAllUpdates() {
		// _updatesMutex already locked
		for (const auto & update : _updates)
			doUpdateMask(update.id, update.newMask, update.ignoreOldMask);
		_updates.clear();

		for (const auto removal : _removals)
			doRemove(removal.id);
		_removals.clear();
	}

	void EntityManager::doUpdateMask(Entity::ID id, Entity::Mask newMask, bool ignoreOldMask) {
		// _updatesMutex already locked
		const auto oldMask = ignoreOldMask ? 0 : _entities[id].mask;
		assert(newMask != oldMask);

		bool removeDone = oldMask == 0;
		bool addDone = newMask == 0;

		{
			detail::WriteLock l(_archetypesMutex);
			for (auto & collection : _archetypes) {
				if (removeDone && addDone)
					break;

				if (collection.mask == oldMask) {
					const auto size = collection.entities.size();
					if (size > 1) {
						const auto it = std::find(collection.entities.begin(), collection.entities.end(), id);
						std::iter_swap(it, collection.entities.begin() + size - 1);
					}
					collection.entities.pop_back();
					collection.sorted = false;
					removeDone = true;
				}

				if (collection.mask == newMask) {
					collection.entities.emplace_back(id);
					collection.sorted = false;
					addDone = true;
				}
			}

			if (!addDone)
				_archetypes.emplace_back(newMask, id);
		}

		detail::WriteLock l(_entitiesMutex);
		_entities[id].mask = newMask;
	}

	void EntityManager::doRemove(Entity::ID id) {
		Entity::Mask mask;
		{
			detail::ReadLock entities(_entitiesMutex);
			mask = _entities[id].mask;
		}

		SystemManager::removeEntity(EntityView(id, mask));

		{
			detail::ReadLock entities(_entitiesMutex);
			mask = _entities[id].mask;
		}

		{
			detail::ReadLock archetypes(_archetypesMutex);
			for (auto & collection : _archetypes) {
				if (collection.mask == mask) {
					detail::WriteLock archetype(collection.mutex);
					const auto tmp = std::find(collection.entities.begin(), collection.entities.end(), id);
					if (collection.entities.size() > 1) {
						std::swap(*tmp, collection.entities.back());
						collection.sorted = false;
					}
					collection.entities.pop_back();
					break;
				}
			}
		}

		{
			detail::WriteLock entities(_entitiesMutex);
			_entities[id].mask = 0;
			_entities[id].active = false;
			_entities[id].shouldActivateAfterInit = true;
		}

		detail::WriteLock l(_toReuseMutex);
		_toReuse.emplace_back(id);
		_toReuseSorted = false;
	}

	/*
	** Collection
	*/

	EntityManager::EntityCollection EntityManager::getEntities() {
		return EntityCollection{ *this };
	}

	EntityManager::EntityCollection::EntityIterator & EntityManager::EntityCollection::EntityIterator::operator++() {
		++index;
		detail::ReadLock l(em._entitiesMutex);
		while (index < em._entities.size() && (em._entities[index].mask == 0 || !em._entities[index].active))
			++index;
		return *this;
	}

	bool EntityManager::EntityCollection::EntityIterator::operator!=(const EntityIterator & rhs) const {
		// Use `<` as it will only be compared with `end()`, and there is a risk that new entities have been added since `end()` was called
		return index < rhs.index;
	}

	Entity EntityManager::EntityCollection::EntityIterator::operator*() const {
		detail::ReadLock l(em._entitiesMutex);
		return Entity(index, em._entities[index].mask, &em);
	}

	EntityManager::EntityCollection::EntityIterator EntityManager::EntityCollection::begin() const {
		size_t i = 0;
		detail::ReadLock l(em._entitiesMutex);
		while (i < em._entities.size() && (em._entities[i].mask == 0 || !em._entities[i].active))
			++i;
		return EntityIterator{ i, em };
	}

	EntityManager::EntityCollection::EntityIterator EntityManager::EntityCollection::end() const {
		detail::ReadLock l(em._entitiesMutex);
		return EntityIterator{ em._entities.size(), em };
	}

	EntityManager::EntityCollection::EntityCollection(EntityManager & em) : em(em) {
		detail::WriteLock l(em._updatesMutex);
		++em._updatesLocked;
	}

	EntityManager::EntityCollection::~EntityCollection() {
		detail::WriteLock l(em._updatesMutex);
		assert(em._updatesLocked != 0);
		--em._updatesLocked;
		if (em._updatesLocked == 0)
			em.doAllUpdates();
	}
}<commit_msg>filesystem checks in save + load<commit_after>#include <filesystem>
#include "EntityManager.hpp"

#ifndef KENGINE_MAX_SAVE_PATH_LENGTH
# define KENGINE_MAX_SAVE_PATH_LENGTH 64
#endif

#ifndef KENGINE_MAX_COMPONENT_NAME_LENGTH
# define KENGINE_MAX_COMPONENT_NAME_LENGTH 64
#endif

namespace kengine {
	Entity EntityManager::getEntity(Entity::ID id) {
		detail::ReadLock l(_entitiesMutex);
		return Entity(id, _entities[id].mask, this);
	}

	EntityView EntityManager::getEntity(Entity::ID id) const {
		detail::ReadLock l(_entitiesMutex);
		return EntityView(id, _entities[id].mask);
	}

	void EntityManager::removeEntity(EntityView e) {
		removeEntity(e.id);
	}

	void EntityManager::removeEntity(Entity::ID id) {
		detail::WriteLock l(_updatesMutex);
		if (_updatesLocked) {
			_removals.push_back({ id });
		}
		else
			doRemove(id);
	}

	void EntityManager::setEntityActive(EntityView e, bool active) {
		setEntityActive(e.id, active);
	}

	void EntityManager::setEntityActive(Entity::ID id, bool active) {
		detail::WriteLock l(_entitiesMutex);
		_entities[id].active = active;
		_entities[id].shouldActivateAfterInit = active;
	}

	struct ComponentIDSave {
		size_t id;
		putils::string<KENGINE_MAX_COMPONENT_NAME_LENGTH> name;
	};

	void EntityManager::load(const char * directory) {
		const bool good = std::filesystem::exists(directory) && std::filesystem::is_directory(directory);
		assert(good);
		if (!good)
			return;

		{
			detail::WriteLock l(_archetypesMutex);
			_archetypes.clear();
		}

		{
			detail::WriteLock l(_toReuseMutex);
			_toReuse.clear();
		}

		for (auto & e : getEntities())
			SystemManager::removeEntity(e);

		{
			detail::ReadLock l(_components.mutex);
			for (const auto &[_, meta] : _components.map)
				meta->load(directory);
		}

		size_t idMap[KENGINE_COMPONENT_COUNT]; // index = new, value = old
		for (auto & i : idMap)
			i = (size_t)-1;
		{
			detail::ReadLock l(_components.mutex);

			std::ifstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/components.bin", directory), std::ifstream::binary);
			assert(f);
			size_t size;
			f.read((char *)&size, sizeof(size));
			for (size_t i = 0; i < size; ++i) {
				ComponentIDSave save;
				f.read((char *)&save, sizeof(save));
				assert(f.gcount() == sizeof(save));

				for (const auto & [_, meta] : _components.map)
					if (meta->funcs.name == save.name) {
						idMap[meta->id] = save.id;
						break;
					}
			}
		}

		std::ifstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/entities.bin", directory), std::ifstream::binary);
		assert(f);
		size_t size;
		f.read((char *)&size, sizeof(size));

		{
			detail::WriteLock l(_entitiesMutex);
			_entities.resize(size);
			f.read((char *)_entities.data(), size * sizeof(_entities[0]));
		}

		for (auto & e : getEntities()) {
			Entity::Mask tmp = 0;
			for (size_t i = 0; i < KENGINE_COMPONENT_COUNT; ++i) {
				const auto oldId = idMap[i];
				tmp[i] = oldId == (size_t)-1 ? false : e.componentMask[oldId];
			}
			updateMask(e.id, tmp, true);
		}

		{
			detail::ReadLock l(_entitiesMutex);
			size_t id = 0;
			for (const auto & e : _entities) {
				if (e.mask == 0) {
					detail::WriteLock l(_toReuseMutex);
					_toReuse.emplace_back(id);
				}
				++id;
			}
		}

		for (auto & e : getEntities())
			SystemManager::registerEntity(e);

		SystemManager::load(directory);
	}

	void EntityManager::save(const char * directory) const {
		std::filesystem::create_directories(directory);
		const auto good = std::filesystem::exists(directory) && std::filesystem::is_directory(directory);
		assert(good);
		if (!good)
			return;

		SystemManager::save(directory);

		putils::vector<bool, KENGINE_COMPONENT_COUNT> serializable;

		{
			detail::ReadLock l(_components.mutex);
			serializable.resize(_components.map.size());
			for (const auto &[_, meta] : _components.map)
				serializable[meta->id] = meta->save(directory);

			// Save Component IDs
			std::ofstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/components.bin", directory), std::ofstream::binary);
			const size_t size = _components.map.size();
			f.write((const char *)&size, sizeof(size));
			for (const auto &[_, meta] : _components.map) {
				ComponentIDSave save;
				save.id = meta->id;
				save.name = meta->funcs.name;
				f.write((const char *)&save, sizeof(save));
			}
		}

		std::ofstream f(putils::string<KENGINE_MAX_SAVE_PATH_LENGTH>("%s/entities.bin", directory), std::ofstream::binary);
		assert(f);

		{
			detail::ReadLock l(_entitiesMutex);
			const auto size = _entities.size();
			f.write((const char *)&size, sizeof(size));
			for (EntityMetadata e : _entities) {
				for (size_t i = 0; i < serializable.size(); ++i)
					e.mask[i] = e.mask[i] && serializable[i];
				f.write((const char *)&e, sizeof(e));
			}
		}
	}

	Entity EntityManager::alloc() {
		{
			detail::ReadLock l(_toReuseMutex);
			if (_toReuse.empty()) {
				detail::WriteLock l(_entitiesMutex);
				const auto id = _entities.size();
				_entities.push_back({ false, 0 });
				return Entity(id, 0, this);
			}
		}

		Entity::ID id;
		{
			detail::WriteLock l(_toReuseMutex);
			if (!_toReuseSorted) {
				std::sort(_toReuse.begin(), _toReuse.end(), std::greater<Entity::ID>());
				_toReuseSorted = true;
			}
			id = _toReuse.back();
			_toReuse.pop_back();
		}

#ifndef NDEBUG
		{
			detail::ReadLock l(_archetypesMutex);
			for (const auto & archetype : _archetypes) {
				detail::ReadLock l(archetype.mutex);
				assert(std::find(archetype.entities.begin(), archetype.entities.end(), id) == archetype.entities.end());
			}
		}

		{
			detail::ReadLock l(_entitiesMutex);
			assert(id < _entities.size());
		}
#endif

		return Entity(id, 0, this);
	}

	void EntityManager::addComponent(Entity::ID id, size_t component) {
		updateHasComponent(id, component, true);
	}

	void EntityManager::removeComponent(Entity::ID id, size_t component) {
		updateHasComponent(id, component, false);
	}

	void EntityManager::updateHasComponent(Entity::ID id, size_t component, bool newHasComponent) {
		{
			detail::WriteLock l(_updatesMutex);
			for (auto & update : _updates)
				if (update.id == id) {
					std::unique_lock<std::mutex> l(update.mutex);
					update.newMask[component] = newHasComponent;
					return;
				}
		}

		Entity::Mask currentMask;
		{
			detail::ReadLock l(_entitiesMutex);
			currentMask = _entities[id].mask;
		}

		auto updatedMask = currentMask;
		updatedMask[component] = newHasComponent;
		updateMask(id, updatedMask);
	}

	void EntityManager::updateMask(Entity::ID id, Entity::Mask newMask, bool ignoreOldMask) {
		detail::WriteLock l(_updatesMutex);
		if (_updatesLocked == 0)
			doUpdateMask(id, newMask, ignoreOldMask);
		else {
			Update update;
			update.id = id;
			update.newMask = newMask;
			update.ignoreOldMask = ignoreOldMask;
			_updates.push_back(std::move(update));
		}
	}

	void EntityManager::doAllUpdates() {
		// _updatesMutex already locked
		for (const auto & update : _updates)
			doUpdateMask(update.id, update.newMask, update.ignoreOldMask);
		_updates.clear();

		for (const auto removal : _removals)
			doRemove(removal.id);
		_removals.clear();
	}

	void EntityManager::doUpdateMask(Entity::ID id, Entity::Mask newMask, bool ignoreOldMask) {
		// _updatesMutex already locked
		const auto oldMask = ignoreOldMask ? 0 : _entities[id].mask;
		assert(newMask != oldMask);

		bool removeDone = oldMask == 0;
		bool addDone = newMask == 0;

		{
			detail::WriteLock l(_archetypesMutex);
			for (auto & collection : _archetypes) {
				if (removeDone && addDone)
					break;

				if (collection.mask == oldMask) {
					const auto size = collection.entities.size();
					if (size > 1) {
						const auto it = std::find(collection.entities.begin(), collection.entities.end(), id);
						std::iter_swap(it, collection.entities.begin() + size - 1);
					}
					collection.entities.pop_back();
					collection.sorted = false;
					removeDone = true;
				}

				if (collection.mask == newMask) {
					collection.entities.emplace_back(id);
					collection.sorted = false;
					addDone = true;
				}
			}

			if (!addDone)
				_archetypes.emplace_back(newMask, id);
		}

		detail::WriteLock l(_entitiesMutex);
		_entities[id].mask = newMask;
	}

	void EntityManager::doRemove(Entity::ID id) {
		Entity::Mask mask;
		{
			detail::ReadLock entities(_entitiesMutex);
			mask = _entities[id].mask;
		}

		SystemManager::removeEntity(EntityView(id, mask));

		{
			detail::ReadLock entities(_entitiesMutex);
			mask = _entities[id].mask;
		}

		{
			detail::ReadLock archetypes(_archetypesMutex);
			for (auto & collection : _archetypes) {
				if (collection.mask == mask) {
					detail::WriteLock archetype(collection.mutex);
					const auto tmp = std::find(collection.entities.begin(), collection.entities.end(), id);
					if (collection.entities.size() > 1) {
						std::swap(*tmp, collection.entities.back());
						collection.sorted = false;
					}
					collection.entities.pop_back();
					break;
				}
			}
		}

		{
			detail::WriteLock entities(_entitiesMutex);
			_entities[id].mask = 0;
			_entities[id].active = false;
			_entities[id].shouldActivateAfterInit = true;
		}

		detail::WriteLock l(_toReuseMutex);
		_toReuse.emplace_back(id);
		_toReuseSorted = false;
	}

	/*
	** Collection
	*/

	EntityManager::EntityCollection EntityManager::getEntities() {
		return EntityCollection{ *this };
	}

	EntityManager::EntityCollection::EntityIterator & EntityManager::EntityCollection::EntityIterator::operator++() {
		++index;
		detail::ReadLock l(em._entitiesMutex);
		while (index < em._entities.size() && (em._entities[index].mask == 0 || !em._entities[index].active))
			++index;
		return *this;
	}

	bool EntityManager::EntityCollection::EntityIterator::operator!=(const EntityIterator & rhs) const {
		// Use `<` as it will only be compared with `end()`, and there is a risk that new entities have been added since `end()` was called
		return index < rhs.index;
	}

	Entity EntityManager::EntityCollection::EntityIterator::operator*() const {
		detail::ReadLock l(em._entitiesMutex);
		return Entity(index, em._entities[index].mask, &em);
	}

	EntityManager::EntityCollection::EntityIterator EntityManager::EntityCollection::begin() const {
		size_t i = 0;
		detail::ReadLock l(em._entitiesMutex);
		while (i < em._entities.size() && (em._entities[i].mask == 0 || !em._entities[i].active))
			++i;
		return EntityIterator{ i, em };
	}

	EntityManager::EntityCollection::EntityIterator EntityManager::EntityCollection::end() const {
		detail::ReadLock l(em._entitiesMutex);
		return EntityIterator{ em._entities.size(), em };
	}

	EntityManager::EntityCollection::EntityCollection(EntityManager & em) : em(em) {
		detail::WriteLock l(em._updatesMutex);
		++em._updatesLocked;
	}

	EntityManager::EntityCollection::~EntityCollection() {
		detail::WriteLock l(em._updatesMutex);
		assert(em._updatesLocked != 0);
		--em._updatesLocked;
		if (em._updatesLocked == 0)
			em.doAllUpdates();
	}
}<|endoftext|>


<commit_before>/*
Copyright (c) 2009 Yahoo! Inc.  All rights reserved.  The copyrights
embodied in the content of this file are licensed under the BSD
(revised) open source license
 */
#include<math.h>
#include<iostream>
#include<stdlib.h>
using namespace std;

#include "loss_functions.h"
#include "global_data.h"

class squaredloss : public loss_function {
public:
  squaredloss() {

  }

  float getLoss(float prediction, float label) {
    if (prediction <= global.max_label && prediction >= global.min_label)
      {
	float example_loss = (prediction - label) * (prediction - label);
	return example_loss;
      }
    else if (prediction < global.min_label)
      if (label == global.min_label)
	return 0.;
      else
	return (label - global.min_label) * (label - global.min_label)
	  + 2. * (label-global.min_label) * (global.min_label - prediction);
    else
      if (label == global.max_label)
	return 0.;
      else
	return (global.max_label - label) * (global.max_label - label)
	  + 2. * (global.max_label - label) * (prediction - global.max_label);
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {

    if (eta_t < 1e-6){
      /* When exp(-eta_t)~= 1 we replace 1-exp(-eta_t)
       * with its first order Taylor expansion around 0
       * to avoid catastrophic cancellation.
       */
      return (label - prediction)*eta_t/norm;
    }
    return (label - prediction)*(1-exp(-eta_t))/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    float t = 0.5*(global.min_label+global.max_label);
    float alternative = (prediction > t) ? global.min_label : global.max_label;
    return log((alternative-prediction)/(alternative-t))/eta_t;
  }

  float getSquareGrad(float prediction, float label) {
    return (prediction - label) * (prediction - label);
  }
  float first_derivative(float prediction, float label)
  {
    if (prediction < global.min_label)
      prediction = global.min_label;
    else if (prediction > global.max_label)
      prediction = global.max_label;
    return 2. * (prediction-label);
  }
  float second_derivative(float prediction, float label)
  {
    if (prediction <= global.max_label && prediction >= global.min_label)
      return 2.;
    else if (prediction < global.min_label)
      return 2. * (label - global.min_label);
    else
      return 2. * (global.max_label - label);
  }
};

class classic_squaredloss : public loss_function {
public:
  classic_squaredloss() {

  }

  float getLoss(float prediction, float label) {
    float example_loss = (prediction - label) * (prediction - label);
    return example_loss;
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {
    return eta_t*(label - prediction)/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    float t = 0.5*(global.min_label+global.max_label);
    float alternative = (prediction > t) ? global.min_label : global.max_label;
    return (t-prediction)/((alternative-prediction)*eta_t);
  }

  float getSquareGrad(float prediction, float label) {
    return (prediction - label) * (prediction - label);
  }
  float first_derivative(float prediction, float label)
  {
    return 2. * (prediction-label);
  }
  float second_derivative(float prediction, float label)
  {
    return 2.;
  }
};

class hingeloss : public loss_function {
public:
  hingeloss() {

  }

  float getLoss(float prediction, float label) {
    float e = 1 - label*prediction;
    return (e > 0) ? e : 0;
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {
    if(label*prediction >= label*label) return 0;
    float err=(label*label-label*prediction)/(label*label);
    float normal= eta_t;
    return label * (normal < err ? normal : err)/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    return fabs(prediction)/eta_t;
  }

  float getSquareGrad(float prediction, float label) {
    return first_derivative(prediction,label);
  }

  float first_derivative(float prediction, float label)
  {
    return (label*prediction >= label*label) ? 0 : -label;
  }

  float second_derivative(float prediction, float label)
  {
    return 0.;
  }
};

class logloss : public loss_function {
public:
  logloss() {

  }

  float getLoss(float prediction, float label) {
    return log(1 + exp(-label * prediction));
  }

  float getUpdate(float prediction, float label, float eta_t, float norm) {
    float w,x;
    float d = exp(label * prediction);
    if(eta_t < 1e-6){
      /* As with squared loss, for small eta_t we replace the update
       * with its first order Taylor expansion to avoid numerical problems
       */
      return label*eta_t/((1+d)*norm);
    }
    x = eta_t + label*prediction + d;
    w = wexpmx(x);
    return -(label*w+prediction)/norm;
  }

  inline float wexpmx(float x){
    /* This piece of code is approximating W(exp(x))-x.
     * W is the Lambert W function: W(z)*exp(W(z))=z.
     * The absolute error of this approximation is less than 9e-5.
     * Faster/better approximations can be substituted here.
     */
    double w = x>=1. ? 0.86*x+0.01 : exp(0.8*x-0.65); //initial guess
    double r = x>=1. ? x-log(w)-w : 0.2*x+0.65-w; //residual
    double t = 1.+w;
    double u = 2.*t*(t+2.*r/3.); //magic
    return w*(1.+r/t*(u-r)/(u-2.*r))-x; //more magic
  }

  float getRevertingWeight(float prediction, float eta_t){
    float z = -fabs(prediction);
    return (1-z-exp(z))/eta_t;
  }

  float first_derivative(float prediction, float label)
  {
    float v = - label/(1+exp(label * prediction));
    return v;
  }

  float getSquareGrad(float prediction, float label) {
    float d = first_derivative(prediction,label);
    return d*d;
  }

  float second_derivative(float prediction, float label)
  {
    float p = 1 / (1+exp(label*prediction));

    return p*(1-p);
  }
};

class quantileloss : public loss_function {
public:
  quantileloss(double &tau_) : tau(tau_) {
  }

  float getLoss(float prediction, float label) {
    float e = label - prediction;
    if(e > 0) {
      return tau * e;
    } else {
      return -(1 - tau) * e;
    }

  }

  float getUpdate(float prediction, float label, float eta_t, float norm) {
    float err = label - prediction;
    if(err == 0) return 0;
    float normal = eta_t;//base update size
    if(err > 0) {
      normal = tau*normal;
      return tau*(normal < err ? normal : err) / norm;
    } else {
      normal = -(1-tau) * normal;
      return ( normal < - err ?  normal : err) / norm;
    }
  }

  float getRevertingWeight(float prediction, float eta_t){
    float v,t;
    t = 0.5*(global.min_label+global.max_label);
    if(prediction > t)
      v = -(1-tau);
     else
      v = tau;
    return (t - prediction)/(eta_t*v);
  }

  float first_derivative(float prediction, float label)
  {
    float e = label - prediction;
    if(e == 0) return 0;
    return e > 0 ? -tau : (1-tau);
  }

  float getSquareGrad(float prediction, float label) {
    float fd = first_derivative(prediction,label);
    return fd*fd;
  }

  float second_derivative(float prediction, float label)
  {
    return 0.;
  }

  double tau;
};

loss_function* getLossFunction(string funcName, double function_parameter) {
  if(funcName.compare("squared") == 0) {
    return new squaredloss();
  } else if(funcName.compare("classic") == 0){
    return new classic_squaredloss();
  } else if(funcName.compare("hinge") == 0) {
    return new hingeloss();
  } else if(funcName.compare("logistic") == 0) {
    if (set_minmax != noop_mm)
      {
	global.min_label = -100;
	global.max_label = 100;
      }
    return new logloss();
  } else if(funcName.compare("quantile") == 0 || funcName.compare("pinball") == 0 || funcName.compare("absolute") == 0) {
    return new quantileloss(function_parameter);
  } else {
    cout << "Invalid loss function name: \'" << funcName << "\' Bailing!" << endl;
    exit(1);
  }
  cout << "end getLossFunction" << endl;
}
<commit_msg>little curvature update from Olivier<commit_after>/*
Copyright (c) 2009 Yahoo! Inc.  All rights reserved.  The copyrights
embodied in the content of this file are licensed under the BSD
(revised) open source license
 */
#include<math.h>
#include<iostream>
#include<stdlib.h>
using namespace std;

#include "loss_functions.h"
#include "global_data.h"

class squaredloss : public loss_function {
public:
  squaredloss() {

  }

  float getLoss(float prediction, float label) {
    if (prediction <= global.max_label && prediction >= global.min_label)
      {
	float example_loss = (prediction - label) * (prediction - label);
	return example_loss;
      }
    else if (prediction < global.min_label)
      if (label == global.min_label)
	return 0.;
      else
	return (label - global.min_label) * (label - global.min_label)
	  + 2. * (label-global.min_label) * (global.min_label - prediction);
    else
      if (label == global.max_label)
	return 0.;
      else
	return (global.max_label - label) * (global.max_label - label)
	  + 2. * (global.max_label - label) * (prediction - global.max_label);
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {

    if (eta_t < 1e-6){
      /* When exp(-eta_t)~= 1 we replace 1-exp(-eta_t)
       * with its first order Taylor expansion around 0
       * to avoid catastrophic cancellation.
       */
      return (label - prediction)*eta_t/norm;
    }
    return (label - prediction)*(1-exp(-eta_t))/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    float t = 0.5*(global.min_label+global.max_label);
    float alternative = (prediction > t) ? global.min_label : global.max_label;
    return log((alternative-prediction)/(alternative-t))/eta_t;
  }

  float getSquareGrad(float prediction, float label) {
    return (prediction - label) * (prediction - label);
  }
  float first_derivative(float prediction, float label)
  {
    if (prediction < global.min_label)
      prediction = global.min_label;
    else if (prediction > global.max_label)
      prediction = global.max_label;
    return 2. * (prediction-label);
  }
  float second_derivative(float prediction, float label)
  {
    if (prediction <= global.max_label && prediction >= global.min_label)
      return 2.;
    else
      return 0.;
  }
};

class classic_squaredloss : public loss_function {
public:
  classic_squaredloss() {

  }

  float getLoss(float prediction, float label) {
    float example_loss = (prediction - label) * (prediction - label);
    return example_loss;
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {
    return eta_t*(label - prediction)/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    float t = 0.5*(global.min_label+global.max_label);
    float alternative = (prediction > t) ? global.min_label : global.max_label;
    return (t-prediction)/((alternative-prediction)*eta_t);
  }

  float getSquareGrad(float prediction, float label) {
    return (prediction - label) * (prediction - label);
  }
  float first_derivative(float prediction, float label)
  {
    return 2. * (prediction-label);
  }
  float second_derivative(float prediction, float label)
  {
    return 2.;
  }
};

class hingeloss : public loss_function {
public:
  hingeloss() {

  }

  float getLoss(float prediction, float label) {
    float e = 1 - label*prediction;
    return (e > 0) ? e : 0;
  }

  float getUpdate(float prediction, float label,float eta_t, float norm) {
    if(label*prediction >= label*label) return 0;
    float err=(label*label-label*prediction)/(label*label);
    float normal= eta_t;
    return label * (normal < err ? normal : err)/norm;
  }

  float getRevertingWeight(float prediction, float eta_t){
    return fabs(prediction)/eta_t;
  }

  float getSquareGrad(float prediction, float label) {
    return first_derivative(prediction,label);
  }

  float first_derivative(float prediction, float label)
  {
    return (label*prediction >= label*label) ? 0 : -label;
  }

  float second_derivative(float prediction, float label)
  {
    return 0.;
  }
};

class logloss : public loss_function {
public:
  logloss() {

  }

  float getLoss(float prediction, float label) {
    return log(1 + exp(-label * prediction));
  }

  float getUpdate(float prediction, float label, float eta_t, float norm) {
    float w,x;
    float d = exp(label * prediction);
    if(eta_t < 1e-6){
      /* As with squared loss, for small eta_t we replace the update
       * with its first order Taylor expansion to avoid numerical problems
       */
      return label*eta_t/((1+d)*norm);
    }
    x = eta_t + label*prediction + d;
    w = wexpmx(x);
    return -(label*w+prediction)/norm;
  }

  inline float wexpmx(float x){
    /* This piece of code is approximating W(exp(x))-x.
     * W is the Lambert W function: W(z)*exp(W(z))=z.
     * The absolute error of this approximation is less than 9e-5.
     * Faster/better approximations can be substituted here.
     */
    double w = x>=1. ? 0.86*x+0.01 : exp(0.8*x-0.65); //initial guess
    double r = x>=1. ? x-log(w)-w : 0.2*x+0.65-w; //residual
    double t = 1.+w;
    double u = 2.*t*(t+2.*r/3.); //magic
    return w*(1.+r/t*(u-r)/(u-2.*r))-x; //more magic
  }

  float getRevertingWeight(float prediction, float eta_t){
    float z = -fabs(prediction);
    return (1-z-exp(z))/eta_t;
  }

  float first_derivative(float prediction, float label)
  {
    float v = - label/(1+exp(label * prediction));
    return v;
  }

  float getSquareGrad(float prediction, float label) {
    float d = first_derivative(prediction,label);
    return d*d;
  }

  float second_derivative(float prediction, float label)
  {
    float p = 1 / (1+exp(label*prediction));

    return p*(1-p);
  }
};

class quantileloss : public loss_function {
public:
  quantileloss(double &tau_) : tau(tau_) {
  }

  float getLoss(float prediction, float label) {
    float e = label - prediction;
    if(e > 0) {
      return tau * e;
    } else {
      return -(1 - tau) * e;
    }

  }

  float getUpdate(float prediction, float label, float eta_t, float norm) {
    float err = label - prediction;
    if(err == 0) return 0;
    float normal = eta_t;//base update size
    if(err > 0) {
      normal = tau*normal;
      return tau*(normal < err ? normal : err) / norm;
    } else {
      normal = -(1-tau) * normal;
      return ( normal < - err ?  normal : err) / norm;
    }
  }

  float getRevertingWeight(float prediction, float eta_t){
    float v,t;
    t = 0.5*(global.min_label+global.max_label);
    if(prediction > t)
      v = -(1-tau);
     else
      v = tau;
    return (t - prediction)/(eta_t*v);
  }

  float first_derivative(float prediction, float label)
  {
    float e = label - prediction;
    if(e == 0) return 0;
    return e > 0 ? -tau : (1-tau);
  }

  float getSquareGrad(float prediction, float label) {
    float fd = first_derivative(prediction,label);
    return fd*fd;
  }

  float second_derivative(float prediction, float label)
  {
    return 0.;
  }

  double tau;
};

loss_function* getLossFunction(string funcName, double function_parameter) {
  if(funcName.compare("squared") == 0) {
    return new squaredloss();
  } else if(funcName.compare("classic") == 0){
    return new classic_squaredloss();
  } else if(funcName.compare("hinge") == 0) {
    return new hingeloss();
  } else if(funcName.compare("logistic") == 0) {
    if (set_minmax != noop_mm)
      {
	global.min_label = -100;
	global.max_label = 100;
      }
    return new logloss();
  } else if(funcName.compare("quantile") == 0 || funcName.compare("pinball") == 0 || funcName.compare("absolute") == 0) {
    return new quantileloss(function_parameter);
  } else {
    cout << "Invalid loss function name: \'" << funcName << "\' Bailing!" << endl;
    exit(1);
  }
  cout << "end getLossFunction" << endl;
}
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

#include "rs_sdk.h"
#include "samples_time_sync_zr300.h"
#include "samples_time_sync_ds5.h"
#include "rs_sdk_version.h"

namespace rs {
    namespace utils {
        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(
                int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency,
                        unsigned int not_matched_frames_buffer_size)
        {
            if (device_name != nullptr)
            {
                std::string str(device_name);
                if ( str.find("ZR300") != std::string::npos )
                        return new samples_time_sync_zr300(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);
                /*if ( str.find("RS400") != std::string::npos )
                        return new samples_time_sync_ds5(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);*/

            }

            throw std::invalid_argument("Unsupported device or missing device name.");
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, max_input_latency, 0);
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, 100, 0);
        }
    }
}

<commit_msg>PR 977: Change default timeout in samples time sync utility to 150 ms<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

#include "rs_sdk.h"
#include "samples_time_sync_zr300.h"
#include "samples_time_sync_ds5.h"
#include "rs_sdk_version.h"

namespace rs {
    namespace utils {
        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(
                int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency,
                        unsigned int not_matched_frames_buffer_size)
        {
            if (device_name != nullptr)
            {
                std::string str(device_name);
                if ( str.find("ZR300") != std::string::npos )
                        return new samples_time_sync_zr300(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);
                /*if ( str.find("RS400") != std::string::npos )
                        return new samples_time_sync_ds5(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);*/

            }

            throw std::invalid_argument("Unsupported device or missing device name.");
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, max_input_latency, 0);
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, 150, 0);
        }
    }
}

<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

#include "rs_sdk.h"
#include "samples_time_sync_zr300.h"
#include "samples_time_sync_ds5.h"
#include "rs_sdk_version.h"
#include "samples_time_sync_external_camera.h"

namespace rs {
    namespace utils {
        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(
                int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency,
                        unsigned int not_matched_frames_buffer_size)
        {
            if (device_name != nullptr)
            {
                std::string str(device_name);
                if ( str.find("ZR300") != std::string::npos )
                        return new samples_time_sync_zr300(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);

                if ( str.compare(external_device_name) == 0 )
                {
                    //External camera synchronization requires that a single buffer is used for the images arrays
                    const int SINGLE_BUFFER = 1;
                    return new samples_time_sync_external_camera(streams_fps,
                                                                 motions_fps, SINGLE_BUFFER,
                                                                 not_matched_frames_buffer_size);
                }
                /*if ( str.find("RS400") != std::string::npos )
                        return new samples_time_sync_ds5(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);*/

            }

            throw std::invalid_argument("Unsupported device or missing device name.");
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, max_input_latency, 0);
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, 100, 0);
        }
    }
}

<commit_msg>PR 978: Change default timeout in sampkes time sync utility to 150 ms<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

#include "rs_sdk.h"
#include "samples_time_sync_zr300.h"
#include "samples_time_sync_ds5.h"
#include "rs_sdk_version.h"
#include "samples_time_sync_external_camera.h"

namespace rs {
    namespace utils {
        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(
                int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency,
                        unsigned int not_matched_frames_buffer_size)
        {
            if (device_name != nullptr)
            {
                std::string str(device_name);
                if ( str.find("ZR300") != std::string::npos )
                        return new samples_time_sync_zr300(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);

                if ( str.compare(external_device_name) == 0 )
                {
                    //External camera synchronization requires that a single buffer is used for the images arrays
                    const int SINGLE_BUFFER = 1;
                    return new samples_time_sync_external_camera(streams_fps,
                                                                 motions_fps, SINGLE_BUFFER,
                                                                 not_matched_frames_buffer_size);
                }
                /*if ( str.find("RS400") != std::string::npos )
                        return new samples_time_sync_ds5(streams_fps, motions_fps, max_input_latency, not_matched_frames_buffer_size);*/

            }

            throw std::invalid_argument("Unsupported device or missing device name.");
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name, unsigned int max_input_latency)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, max_input_latency, 0);
        }

        samples_time_sync_interface *
        samples_time_sync_interface::create_instance(int streams_fps[], int motions_fps[], const char* device_name)
        {
            return samples_time_sync_interface::create_instance(streams_fps, motions_fps, device_name, 150, 0);
        }
    }
}

<|endoftext|>


<commit_before>/*************************************************************************
*                                                                       *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
* All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
*                                                                       *
* This library is free software; you can redistribute it and/or         *
* modify it under the terms of EITHER:                                  *
*   (1) The GNU Lesser General Public License as published by the Free  *
*       Software Foundation; either version 2.1 of the License, or (at  *
*       your option) any later version. The text of the GNU Lesser      *
*       General Public License is included with this library in the     *
*       file LICENSE.TXT.                                               *
*   (2) The BSD-style license that is included with this library in     *
*       the file LICENSE-BSD.TXT.                                       *
*                                                                       *
* This library is distributed in the hope that it will be useful,       *
* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
* LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
*                                                                       *
*************************************************************************/

/*
 * Cylinder-Plane collider by Christoph Beyer ( boernerb@web.de )
 *
 * This testing basically comes down to testing the intersection
 * of the cylinder caps (discs) with the plane.
 *
 */

#include <ode/collision.h>
#include <ode/matrix.h>
#include <ode/rotation.h>
#include <ode/odemath.h>
#include <ode/objects.h>

#include "collision_kernel.h"	// for dxGeom

int dCollideCylinderPlane(dxGeom *Cylinder, dxGeom *Plane, int flags, dContactGeom *contact, int skip)
{
	dIASSERT (skip >= (int)sizeof(dContactGeom));
	dIASSERT (Cylinder->type == dCylinderClass);
	dIASSERT (Plane->type == dPlaneClass);
	dIASSERT ((flags & NUMC_MASK) >= 1);

	unsigned char* pContactData = (unsigned char*)contact;
	int GeomCount = 0; // count of used contactgeoms

#ifdef dSINGLE
	const dReal toleranz = 0.0001f;
#endif
#ifdef dDOUBLE
	const dReal toleranz = 0.0000001;
#endif

	// Get the properties of the cylinder (length+radius)
	dReal radius, length;
	dGeomCylinderGetParams(Cylinder, &radius, &length);
	dVector3 &cylpos = Cylinder->final_posr->pos;
	// and the plane
	dVector4 planevec;
	dGeomPlaneGetParams(Plane, planevec);
	dVector3 PlaneNormal = {planevec[0],planevec[1],planevec[2]};
	dVector3 PlanePos = {planevec[0] * planevec[3],planevec[1] * planevec[3],planevec[2] * planevec[3]};

	dVector3 G1Pos1, G1Pos2, vDir1;
	vDir1[0] = Cylinder->final_posr->R[2];
	vDir1[1] = Cylinder->final_posr->R[6];
	vDir1[2] = Cylinder->final_posr->R[10];

	dReal s;
	s = length * dReal(0.5);
	G1Pos2[0] = vDir1[0] * s + cylpos[0];
	G1Pos2[1] = vDir1[1] * s + cylpos[1];
	G1Pos2[2] = vDir1[2] * s + cylpos[2];

	G1Pos1[0] = vDir1[0] * -s + cylpos[0];
	G1Pos1[1] = vDir1[1] * -s + cylpos[1];
	G1Pos1[2] = vDir1[2] * -s + cylpos[2];

	dVector3 C;

	// parallel-check
	s = vDir1[0] * PlaneNormal[0] + vDir1[1] * PlaneNormal[1] + vDir1[2] * PlaneNormal[2];
	if(s < 0)
		s += dReal(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel
	else
		s -= dReal(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel
	if(s < toleranz && s > (-toleranz))
	{
		// discs are parallel to the plane

		// 1.compute if, and where contacts are
		dVector3 P;
		s = planevec[3] - planevec[0] * G1Pos1[0] - planevec[1] * G1Pos1[1] - planevec[2] * G1Pos1[2];
		dReal t;
		t = planevec[3] - planevec[0] * G1Pos2[0] - planevec[1] * G1Pos2[1] - planevec[2] * G1Pos2[2];
		if(s >= t) // s == t does never happen,
		{
			if(s >= 0)
			{
				// 1. Disc
				P[0] = G1Pos1[0];
				P[1] = G1Pos1[1];
				P[2] = G1Pos1[2];
			}
			else
				return GeomCount; // no contacts
		}
		else
		{
			if(t >= 0)
			{
				// 2. Disc
				P[0] = G1Pos2[0];
				P[1] = G1Pos2[1];
				P[2] = G1Pos2[2];
			}
			else
				return GeomCount; // no contacts
		}

		// 2. generate a coordinate-system on the disc
		dVector3 V1, V2;
		if(vDir1[0] < toleranz && vDir1[0] > (-toleranz))
		{
			// not x-axis
			V1[0] = vDir1[0] + dReal(1.0); // random value
			V1[1] = vDir1[1];
			V1[2] = vDir1[2];
		}
		else
		{
			// maybe x-axis
			V1[0] = vDir1[0];
			V1[1] = vDir1[1] + dReal(1.0); // random value
			V1[2] = vDir1[2];
		}
		// V1 is now another direction than vDir1
		// Cross-product
	    V2[0] = V1[1] * vDir1[2] - V1[2] * vDir1[1];
		V2[1] = V1[2] * vDir1[0] - V1[0] * vDir1[2];
		V2[2] = V1[0] * vDir1[1] - V1[1] * vDir1[0];
		// make unit V2
		t = dReal(sqrt(V2[0] * V2[0] + V2[1] * V2[1] + V2[2] * V2[2]));
		t = radius / t;
		V2[0] *= t;
		V2[1] *= t;
		V2[2] *= t;
		// cross again
	    V1[0] = V2[1] * vDir1[2] - V2[2] * vDir1[1];
		V1[1] = V2[2] * vDir1[0] - V2[0] * vDir1[2];
		V1[2] = V2[0] * vDir1[1] - V2[1] * vDir1[0];
		// |V2| is 'radius' and vDir1 unit, so |V1| is 'radius'
		// V1 = first axis
		// V2 = second axis

		// 3. generate contactpoints

		// Potential contact 1
		contact->pos[0] = P[0] + V1[0];
		contact->pos[1] = P[1] + V1[1];
		contact->pos[2] = P[2] + V1[2];
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth > 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 2
		contact->pos[0] = P[0] - V1[0];
		contact->pos[1] = P[1] - V1[1];
		contact->pos[2] = P[2] - V1[2];
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth > 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 3
		contact->pos[0] = P[0] + V2[0];
		contact->pos[1] = P[1] + V2[1];
		contact->pos[2] = P[2] + V2[2];
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth > 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 4
		contact->pos[0] = P[0] - V2[0];
		contact->pos[1] = P[1] - V2[1];
		contact->pos[2] = P[2] - V2[2];
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth > 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}
	}
	else
	{
		dReal t = -((-PlaneNormal[0]) * vDir1[0] + (-PlaneNormal[1]) * vDir1[1] + (-PlaneNormal[2]) * vDir1[2]);
		C[0] = vDir1[0] * t - PlaneNormal[0];
		C[1] = vDir1[1] * t - PlaneNormal[1];
		C[2] = vDir1[2] * t - PlaneNormal[2];
		s = dReal(sqrt(C[0] * C[0] + C[1] * C[1] + C[2] * C[2]));
		// move C onto the circle
		s = radius / s;
		C[0] *= s;
		C[1] *= s;
		C[2] *= s;

		// deepest point of disc 1
		contact->pos[0] = C[0] + G1Pos1[0];
		contact->pos[1] = C[1] + G1Pos1[1];
		contact->pos[2] = C[2] + G1Pos1[2];

		// depth of the deepest point
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth >= 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// C is still computed

		// deepest point of disc 2
		contact->pos[0] = C[0] + G1Pos2[0];
		contact->pos[1] = C[1] + G1Pos2[1];
		contact->pos[2] = C[2] + G1Pos2[2];

		// depth of the deepest point
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth >= 0)
		{
			contact->normal[0] = PlaneNormal[0];
			contact->normal[1] = PlaneNormal[1];
			contact->normal[2] = PlaneNormal[2];
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}
	}
	return GeomCount;
}
<commit_msg>Cosmetic: changed some inlined code to ODE utility function calls<commit_after>/*************************************************************************
*                                                                       *
* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
* All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
*                                                                       *
* This library is free software; you can redistribute it and/or         *
* modify it under the terms of EITHER:                                  *
*   (1) The GNU Lesser General Public License as published by the Free  *
*       Software Foundation; either version 2.1 of the License, or (at  *
*       your option) any later version. The text of the GNU Lesser      *
*       General Public License is included with this library in the     *
*       file LICENSE.TXT.                                               *
*   (2) The BSD-style license that is included with this library in     *
*       the file LICENSE-BSD.TXT.                                       *
*                                                                       *
* This library is distributed in the hope that it will be useful,       *
* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
* LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
*                                                                       *
*************************************************************************/

/*
 * Cylinder-Plane collider by Christoph Beyer ( boernerb@web.de )
 *
 * This testing basically comes down to testing the intersection
 * of the cylinder caps (discs) with the plane.
 *
 */

#include <ode/collision.h>
#include <ode/matrix.h>
#include <ode/rotation.h>
#include <ode/odemath.h>
#include <ode/objects.h>

#include "collision_kernel.h"	// for dxGeom
#include "collision_util.h"

int dCollideCylinderPlane(dxGeom *Cylinder, dxGeom *Plane, int flags, dContactGeom *contact, int skip)
{
	dIASSERT (skip >= (int)sizeof(dContactGeom));
	dIASSERT (Cylinder->type == dCylinderClass);
	dIASSERT (Plane->type == dPlaneClass);
	dIASSERT ((flags & NUMC_MASK) >= 1);

	unsigned char* pContactData = (unsigned char*)contact;
	int GeomCount = 0; // count of used contactgeoms

#ifdef dSINGLE
	const dReal toleranz = 0.0001f;
#endif
#ifdef dDOUBLE
	const dReal toleranz = 0.0000001;
#endif

	// Get the properties of the cylinder (length+radius)
	dReal radius, length;
	dGeomCylinderGetParams(Cylinder, &radius, &length);
	dVector3 &cylpos = Cylinder->final_posr->pos;
	// and the plane
	dVector4 planevec;
	dGeomPlaneGetParams(Plane, planevec);
	dVector3 PlaneNormal = {planevec[0],planevec[1],planevec[2]};
	dVector3 PlanePos = {planevec[0] * planevec[3],planevec[1] * planevec[3],planevec[2] * planevec[3]};

	dVector3 G1Pos1, G1Pos2, vDir1;
	vDir1[0] = Cylinder->final_posr->R[2];
	vDir1[1] = Cylinder->final_posr->R[6];
	vDir1[2] = Cylinder->final_posr->R[10];

	dReal s;
	s = length * dReal(0.5);
	G1Pos2[0] = vDir1[0] * s + cylpos[0];
	G1Pos2[1] = vDir1[1] * s + cylpos[1];
	G1Pos2[2] = vDir1[2] * s + cylpos[2];

	G1Pos1[0] = vDir1[0] * -s + cylpos[0];
	G1Pos1[1] = vDir1[1] * -s + cylpos[1];
	G1Pos1[2] = vDir1[2] * -s + cylpos[2];

	dVector3 C;

	// parallel-check
	s = vDir1[0] * PlaneNormal[0] + vDir1[1] * PlaneNormal[1] + vDir1[2] * PlaneNormal[2];
	if(s < 0)
		s += dReal(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel
	else
		s -= dReal(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel
	if(s < toleranz && s > (-toleranz))
	{
		// discs are parallel to the plane

		// 1.compute if, and where contacts are
		dVector3 P;
		s = planevec[3] - dVector3Dot(planevec, G1Pos1);
		dReal t;
		t = planevec[3] - dVector3Dot(planevec, G1Pos2);
		if(s >= t) // s == t does never happen,
		{
			if(s >= 0)
			{
				// 1. Disc
				dVector3Copy(G1Pos1, P);
			}
			else
				return GeomCount; // no contacts
		}
		else
		{
			if(t >= 0)
			{
				// 2. Disc
				dVector3Copy(G1Pos2, P);
			}
			else
				return GeomCount; // no contacts
		}

		// 2. generate a coordinate-system on the disc
		dVector3 V1, V2;
		if(vDir1[0] < toleranz && vDir1[0] > (-toleranz))
		{
			// not x-axis
			V1[0] = vDir1[0] + dReal(1.0); // random value
			V1[1] = vDir1[1];
			V1[2] = vDir1[2];
		}
		else
		{
			// maybe x-axis
			V1[0] = vDir1[0];
			V1[1] = vDir1[1] + dReal(1.0); // random value
			V1[2] = vDir1[2];
		}
		// V1 is now another direction than vDir1
		// Cross-product
	    dVector3Cross(V1, vDir1, V2);
		// make unit V2
		t = dVector3Length(V2);
		t = radius / t;
		dVector3Scale(V2, t);
		// cross again
		dVector3Cross(V2, vDir1, V1);
		// |V2| is 'radius' and vDir1 unit, so |V1| is 'radius'
		// V1 = first axis
		// V2 = second axis

		// 3. generate contactpoints

		// Potential contact 1
		dVector3Add(P, V1, contact->pos);
		contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos);
		if(contact->depth > 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 2
		dVector3Subtract(P, V1, contact->pos);
		contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos);
		if(contact->depth > 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 3
		dVector3Add(P, V2, contact->pos);
		contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos);
		if(contact->depth > 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// Potential contact 4
		dVector3Subtract(P, V2, contact->pos);
		contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos);
		if(contact->depth > 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}
	}
	else
	{
		dReal t = dVector3Dot(PlaneNormal, vDir1);
		C[0] = vDir1[0] * t - PlaneNormal[0];
		C[1] = vDir1[1] * t - PlaneNormal[1];
		C[2] = vDir1[2] * t - PlaneNormal[2];
		s = dVector3Length(C);
		// move C onto the circle
		s = radius / s;
		dVector3Scale(C, s);

		// deepest point of disc 1
		dVector3Add(C, G1Pos1, contact->pos);

		// depth of the deepest point
		contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos);
		if(contact->depth >= 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}

		// C is still computed

		// deepest point of disc 2
		dVector3Add(C, G1Pos2, contact->pos);

		// depth of the deepest point
		contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2];
		if(contact->depth >= 0)
		{
			dVector3Copy(PlaneNormal, contact->normal);
			contact->g1 = Cylinder;
			contact->g2 = Plane;
			GeomCount++;
			if( GeomCount >= (flags & NUMC_MASK))
				return GeomCount; // enough contactgeoms
			pContactData += skip;
			contact = (dContactGeom*)pContactData;
		}
	}
	return GeomCount;
}
<|endoftext|>


<commit_before>/*
    Title:      Validate addresses in objects.

    Copyright (c) 2006
        David C.J. Matthews

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
#ifdef _WIN32_WCE
#include "winceconfig.h"
#else
#ifdef WIN32
#include "winconfig.h"
#else
#include "config.h"
#endif
#endif

#ifdef HAVE_ASSERT_H
#include <assert.h>
#define ASSERT(x)   assert(x)
#else
#define ASSERT(x)
#endif

#include "globals.h"
#include "memory.h"
#include "diagnostics.h"
#include "machine_dep.h"
#include "scanaddrs.h"
#include "memmgr.h"

#define INRANGE(val,start,end)\
  (start <= val && val < end)

static void CheckAddress(const void *pt)
{
    if (gMem.SpaceForAddress(pt) == 0)
        Crash ("Bad pointer 0x%08x found", pt);
}

void DoCheck (const PolyWord pt)
{
    if (pt == PolyWord::FromUnsigned(0)) return;

    if (pt.IsTagged()) return;

    /* Test corrected 20/2/95 - the stack contains code pointers
     (for return addresses) as well as simple data pointers */
    ASSERT (pt.IsCodePtr() || pt.IsDataPtr());
    CheckAddress(pt.AsAddress());
}

class ScanCheckAddress: public ScanAddress
{
public:
    virtual PolyObject *ScanObjectAddress(PolyObject *pt) { DoCheck(pt); return pt; }
};

void DoCheckObject (const PolyObject *base, POLYUNSIGNED L)
{

    PolyWord *pt  = (PolyWord*)base;
    CheckAddress(pt-1);

    ASSERT (OBJ_IS_LENGTH(L));

    POLYUNSIGNED n   = OBJ_OBJECT_LENGTH(L);
    if (n == 0) return;

    ASSERT (n > 0);

    PolyWord *end = pt + n;

    CheckAddress (end-1);

    byte flags = GetTypeBits(L);  /* discards GC flag and mutable bit */

    if ((flags & ~F_NEGATIVE_BIT) == F_BYTE_BIT) /* possibly signed byte object */
        return; /* Nothing more to do */

    if (flags == F_STACK_BIT)
    {
        StackObject *stack = (StackObject *) base;
        POLYUNSIGNED     skip  = stack->p_sp - (PolyWord*)base;

        ASSERT (INRANGE(stack->p_sp, (PolyWord*)base, (PolyWord*)end));
        ASSERT (INRANGE(stack->p_hr, (PolyWord*)base, (PolyWord*)end));

        /* Skip to the start of the stack. */
        ASSERT (skip < n);

        pt += skip;
        n  -= skip;
    }
    else if (flags == F_CODE_BIT) /* code object */
    {
        ScanCheckAddress checkAddr;
        /* We flush the instruction cache here in case we change any of the
          instructions when we update addresses. */
        machineDependent->FlushInstructionCache(pt, (n + 1) * sizeof(PolyWord));
        machineDependent->ScanConstantsWithinCode((PolyObject *)base, (PolyObject *)base, n, &checkAddr);
        /* Skip to the constants. */
        base->GetConstSegmentForCode(n, pt, n);
    }
    else ASSERT (flags == 0); /* ordinary word object */

    while (n--) DoCheck (*pt++);
}

void DoCheckPointer (const PolyWord pt)
{
    if (pt == PolyWord::FromUnsigned(0)) return;

    if (OBJ_IS_AN_INTEGER(pt)) return;

    if (gMem.IsIOPointer(pt.AsAddress())) return;

    DoCheck (pt);

    if (pt.IsDataPtr())
    {
        PolyObject *obj = pt.AsObjPtr();
        DoCheckObject (obj, obj->LengthWord());
    }
}

void DoCheckRegion(PolyWord *region, POLYUNSIGNED length)
{
    ScanCheckAddress memCheck;
    memCheck.ScanAddressesInRegion(region, length);
}

// Check all the objects in the memory.  Used to check the garbage collector
//
void DoCheckMemory()
{
    ScanCheckAddress memCheck;
    // Scan the local mutable area.  This is where new objects are created.
    // The immutable areas are only modified by the GC.
    for (unsigned i = 0; i < gMem.nlSpaces; i++)
    {
        LocalMemSpace *space = gMem.lSpaces[i];
        if (space->isMutable)
            memCheck.ScanAddressesInRegion(space->pointer, space->top-space->pointer);
    }
//    memCheck.ScanAddressesInRegion(A.M.pointer, A.M.top-A.M.pointer);
//    memCheck.ScanAddressesInRegion(A.I.pointer, A.I.top-A.I.pointer);
    gMem.OpOldMutables(&memCheck);
}
<commit_msg>Remove commented out lines.<commit_after>/*
    Title:      Validate addresses in objects.

    Copyright (c) 2006
        David C.J. Matthews

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
#ifdef _WIN32_WCE
#include "winceconfig.h"
#else
#ifdef WIN32
#include "winconfig.h"
#else
#include "config.h"
#endif
#endif

#ifdef HAVE_ASSERT_H
#include <assert.h>
#define ASSERT(x)   assert(x)
#else
#define ASSERT(x)
#endif

#include "globals.h"
#include "memory.h"
#include "diagnostics.h"
#include "machine_dep.h"
#include "scanaddrs.h"
#include "memmgr.h"

#define INRANGE(val,start,end)\
  (start <= val && val < end)

static void CheckAddress(const void *pt)
{
    if (gMem.SpaceForAddress(pt) == 0)
        Crash ("Bad pointer 0x%08x found", pt);
}

void DoCheck (const PolyWord pt)
{
    if (pt == PolyWord::FromUnsigned(0)) return;

    if (pt.IsTagged()) return;

    /* Test corrected 20/2/95 - the stack contains code pointers
     (for return addresses) as well as simple data pointers */
    ASSERT (pt.IsCodePtr() || pt.IsDataPtr());
    CheckAddress(pt.AsAddress());
}

class ScanCheckAddress: public ScanAddress
{
public:
    virtual PolyObject *ScanObjectAddress(PolyObject *pt) { DoCheck(pt); return pt; }
};

void DoCheckObject (const PolyObject *base, POLYUNSIGNED L)
{

    PolyWord *pt  = (PolyWord*)base;
    CheckAddress(pt-1);

    ASSERT (OBJ_IS_LENGTH(L));

    POLYUNSIGNED n   = OBJ_OBJECT_LENGTH(L);
    if (n == 0) return;

    ASSERT (n > 0);

    PolyWord *end = pt + n;

    CheckAddress (end-1);

    byte flags = GetTypeBits(L);  /* discards GC flag and mutable bit */

    if ((flags & ~F_NEGATIVE_BIT) == F_BYTE_BIT) /* possibly signed byte object */
        return; /* Nothing more to do */

    if (flags == F_STACK_BIT)
    {
        StackObject *stack = (StackObject *) base;
        POLYUNSIGNED     skip  = stack->p_sp - (PolyWord*)base;

        ASSERT (INRANGE(stack->p_sp, (PolyWord*)base, (PolyWord*)end));
        ASSERT (INRANGE(stack->p_hr, (PolyWord*)base, (PolyWord*)end));

        /* Skip to the start of the stack. */
        ASSERT (skip < n);

        pt += skip;
        n  -= skip;
    }
    else if (flags == F_CODE_BIT) /* code object */
    {
        ScanCheckAddress checkAddr;
        /* We flush the instruction cache here in case we change any of the
          instructions when we update addresses. */
        machineDependent->FlushInstructionCache(pt, (n + 1) * sizeof(PolyWord));
        machineDependent->ScanConstantsWithinCode((PolyObject *)base, (PolyObject *)base, n, &checkAddr);
        /* Skip to the constants. */
        base->GetConstSegmentForCode(n, pt, n);
    }
    else ASSERT (flags == 0); /* ordinary word object */

    while (n--) DoCheck (*pt++);
}

void DoCheckPointer (const PolyWord pt)
{
    if (pt == PolyWord::FromUnsigned(0)) return;

    if (OBJ_IS_AN_INTEGER(pt)) return;

    if (gMem.IsIOPointer(pt.AsAddress())) return;

    DoCheck (pt);

    if (pt.IsDataPtr())
    {
        PolyObject *obj = pt.AsObjPtr();
        DoCheckObject (obj, obj->LengthWord());
    }
}

void DoCheckRegion(PolyWord *region, POLYUNSIGNED length)
{
    ScanCheckAddress memCheck;
    memCheck.ScanAddressesInRegion(region, length);
}

// Check all the objects in the memory.  Used to check the garbage collector
//
void DoCheckMemory()
{
    ScanCheckAddress memCheck;
    // Scan the local mutable area.  This is where new objects are created.
    // The immutable areas are only modified by the GC.
    for (unsigned i = 0; i < gMem.nlSpaces; i++)
    {
        LocalMemSpace *space = gMem.lSpaces[i];
        if (space->isMutable)
            memCheck.ScanAddressesInRegion(space->pointer, space->top-space->pointer);
    }
    gMem.OpOldMutables(&memCheck);
}
<|endoftext|>


<commit_before>AliGenerator*  CreateGenerator();

void fastGen(Int_t nev = 1, char* filename = "galice.root")
{
//
//                        Construction
//
//  Output file
    TFile*  file         = new TFile(filename, "recreate");
//  Create stack
    AliStack* stack      = new AliStack(10000);
    stack->MakeTree(0, filename);

//  Create Header
    AliHeader* header    = new AliHeader();
//  Create Header Tree
    TTree* treeE         = new TTree("TE","Headers");
    treeE->Branch("Header", "AliHeader", &header, 4000, 0);
    treeE->Write();
//
//  Create and Initialize Generator
    AliGenerator *gener = CreateGenerator();
    gener->Init();
    gener->SetStack(stack);

//
//                        Event Loop
//
    Int_t iev;

    for (iev = 0; iev < nev; iev++) {

	printf("\n \n Event number %d \n \n", iev);

//  Initialize event
	header->Reset(0,iev);
	stack->Reset();
	stack->BeginEvent(iev);

//  Generate event
	gener->Generate();
//  Analysis
	Int_t npart = stack->GetNprimary();
	printf("Analyse %d Particles\n", npart);
	for (Int_t part=0; part<npart; part++) {
	    TParticle *MPart = stack->Particle(part);
	    Int_t mpart  = MPart->GetPdgCode();
	    printf("Particle %d\n", mpart);
	}

//  Finish event
	header->SetNprimary(stack->GetNprimary());
	header->SetNtrack(stack->GetNtrack());
//      I/O
//
	stack->FinishEvent();
	header->SetStack(stack);
	treeE->Fill();
	(stack->TreeK())->Write(0,TObject::kOverwrite);
    } // event loop
//
//                         Termination
//  Generator
    gener->FinishRun();
//  Header
    treeE->Write(0,TObject::kOverwrite);
    delete treeE;   treeE = 0;
//  Stack
    stack->FinishRun();
//  Write file
    gener->Write();
    file->Write();
}

AliGenerator*  CreateGenerator()
{
    gener = new AliGenPythia(1);
//
//
//   vertex position and smearing
    gener->SetVertexSmear(kPerEvent);
//   structure function
    gener->SetStrucFunc(kGRVHO);
//   charm, beauty, charm_unforced, beauty_unforced, jpsi, jpsi_chi, mb
    gener->SetProcess(kPyJets);
//   Centre of mass energy
    gener->SetEnergyCMS(5500.);
//   Pt transfer of the hard scattering
    gener->SetPtHard(50.,50.2);
//   Initialize generator
    return gener;
}

<commit_msg>Updates for newio.<commit_after>AliGenerator*  CreateGenerator();

void fastGen(Int_t nev = 1, char* filename = "galice.root")
{
//  Runloader

    AliRunLoader* rl = AliRunLoader::Open("galice.root","FASTRUN","recreate");

    rl->SetCompressionLevel(2);
    rl->SetNumberOfEventsPerFile(nev);
    rl->LoadKinematics("RECREATE");
    rl->MakeTree("E");
    gAlice->SetRunLoader(rl);

//  Create stack
    rl->MakeStack();
    AliStack* stack      = rl->Stack();

//  Header
    AliHeader* header = rl->GetHeader();
//
//  Create and Initialize Generator
    AliGenerator *gener = CreateGenerator();
    gener->Init();
    gener->SetStack(stack);

//
//                        Event Loop
//
    Int_t iev;

    for (iev = 0; iev < nev; iev++) {

	printf("\n \n Event number %d \n \n", iev);

//  Initialize event
	header->Reset(0,iev);
	rl->SetEventNumber(iev);
	stack->Reset();
	rl->MakeTree("K");
//	stack->ConnectTree();

//  Generate event
	gener->Generate();
//  Analysis
	Int_t npart = stack->GetNprimary();
	printf("Analyse %d Particles\n", npart);
	for (Int_t part=0; part<npart; part++) {
	    TParticle *MPart = stack->Particle(part);
	    Int_t mpart  = MPart->GetPdgCode();
	    printf("Particle %d\n", mpart);
	}

//  Finish event
	header->SetNprimary(stack->GetNprimary());
	header->SetNtrack(stack->GetNtrack());
//      I/O
//
	stack->FinishEvent();
	header->SetStack(stack);
	rl->WriteKinematics("OVERWRITE");
    } // event loop
//
//                         Termination
//  Generator
    gener->FinishRun();
//  Stack
    stack->FinishRun();
//  Write file
    gener->Write();
    rl->WriteHeader("OVERWRITE");
}

AliGenerator*  CreateGenerator()
{
    gener = new AliGenPythia(1);
//
//
//   vertex position and smearing
    gener->SetVertexSmear(kPerEvent);
//   structure function
    gener->SetStrucFunc(kGRVHO);
//   charm, beauty, charm_unforced, beauty_unforced, jpsi, jpsi_chi, mb
    gener->SetProcess(kPyJets);
//   Centre of mass energy
    gener->SetEnergyCMS(5500.);
//   Pt transfer of the hard scattering
    gener->SetPtHard(50.,50.2);
//   Initialize generator
    return gener;
}

<|endoftext|>


<commit_before>/** $Id:  $
  * \file
  * \author  $Author:  $
  * \version $Revision:  $
  * \package ISM-LabPowerSupply
  *
  *
  *
  * (C) 2015 by André Heßling
  */

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/
#include "hw_config.h"
#include "systimer.h"
#include <stdio.h>
#include <string.h>
#include "driver/spiF0.hpp"
#include "modules/HMI_USB.hpp"
#include "modules/OutputControl.hpp"
#include "modules/InputSense.hpp"
#include "modules/NVRAM.hpp"
#include "modules/HMI_Front.hpp"

#ifdef SEMIHOST
#include <stdio.h>
extern void  initialise_monitor_handles(void);
#endif

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Variables                                                                  **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Functions                                                                  **
**                                                                            **
\*----------------------------------------------------------------------------*/

int main(void)
{
  mstimer_init();
  ustimer_init();

  // Wait some time for LCD to power up
  delay_ms(100);

  RCC->AHBENR |= RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD;

  // low level hardware modules
  SPI spiDisplay(DISPLAY_SPI);

  // modules
  NVRAM nvRAM;
  SystemState systemState(&nvRAM);
  SystemCommand systemCommand;
  OutputControl outputControl;
  InputSense inputSense;
  HMI_USB hmiUSB(&nvRAM);
  HMI_Front hmiFront(&spiDisplay);

  for (;;)
  {
    // Module: Input sense (get actual system state)
    inputSense.execute(systemCommand, systemState);

    // Module: USB interface
    hmiUSB.execute(systemState, systemCommand);

    // Module: HMI Front (display and rotary encoder)
    hmiFront.execute(systemState, systemCommand);

    // Module: Output control
    outputControl.execute(systemState, systemCommand);
  }

  return 0;
}
<commit_msg>fix: SystemCommand did not load NVRAM settings<commit_after>/** $Id:  $
  * \file
  * \author  $Author:  $
  * \version $Revision:  $
  * \package ISM-LabPowerSupply
  *
  *
  *
  * (C) 2015 by André Heßling
  */

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/
#include "hw_config.h"
#include "systimer.h"
#include <stdio.h>
#include <string.h>
#include "driver/spiF0.hpp"
#include "modules/HMI_USB.hpp"
#include "modules/OutputControl.hpp"
#include "modules/InputSense.hpp"
#include "modules/NVRAM.hpp"
#include "modules/HMI_Front.hpp"

#ifdef SEMIHOST
#include <stdio.h>
extern void  initialise_monitor_handles(void);
#endif

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Variables                                                                  **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Functions                                                                  **
**                                                                            **
\*----------------------------------------------------------------------------*/

int main(void)
{
  mstimer_init();
  ustimer_init();

  // Wait some time for LCD to power up
  delay_ms(100);

  RCC->AHBENR |= RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD;

  // low level hardware modules
  SPI spiDisplay(DISPLAY_SPI);

  // modules
  NVRAM nvRAM;
  SystemState systemState(&nvRAM);
  SystemCommand systemCommand(&nvRAM);
  OutputControl outputControl;
  InputSense inputSense;
  HMI_USB hmiUSB(&nvRAM);
  HMI_Front hmiFront(&spiDisplay);

  for (;;)
  {
    // Module: Input sense (get actual system state)
    inputSense.execute(systemCommand, systemState);

    // Module: USB interface
    hmiUSB.execute(systemState, systemCommand);

    // Module: HMI Front (display and rotary encoder)
    hmiFront.execute(systemState, systemCommand);

    // Module: Output control
    outputControl.execute(systemState, systemCommand);
  }

  return 0;
}
<|endoftext|>