<commit_before>#include <algorithm>
#include <vector>
#include <set>
#include <chrono>
#include <random>
#include "phevaluator/phevaluator.h"
#include "benchmark/benchmark.h"

using namespace phevaluator;

static void EvaluateAllFiveCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 48; a++) {
      for(int b = a + 1; b < 49; b++) {
        for(int c = b + 1; c < 50; c++) {
          for(int d = c + 1; d < 51; d++) {
            for(int e = d + 1; e < 52; e++) {
              EvaluateCards(a, b, c, d, e);
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllFiveCards);

static void EvaluateAllSixCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 47; a++) {
      for(int b = a + 1; b < 48; b++) {
        for(int c = b + 1; c < 49; c++) {
          for(int d = c + 1; d < 50; d++) {
            for(int e = d + 1; e < 51; e++) {
              for(int f = e + 1; f < 52; f++) {
                EvaluateCards(a, b, c, d, e, f);
              }
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllSixCards);

static void EvaluateAllSevenCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 46; a++) {
      for(int b = a + 1; b < 47; b++) {
        for(int c = b + 1; c < 48; c++) {
          for(int d = c + 1; d < 49; d++) {
            for(int e = d + 1; e < 50; e++) {
              for(int f = e + 1; f < 51; f++) {
                for(int g = f + 1; g < 52; g++) {
                  EvaluateCards(a, b, c, d, e, f, g);
                }
              }
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllSevenCards);

static unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
static std::default_random_engine generator(seed);
static std::uniform_int_distribution<int> distribution(0, 51);

static std::vector<int> RandomCardSample(int size) {
  std::vector<int> ret;
  std::set<int> sample;

  while (sample.size() < size) {
    int number = distribution(generator);
    if (sample.find(number) == sample.end()) {
      ret.push_back(number);
      sample.insert(number);
    }
  }

  return ret;
}

const int SIZE = 10;

static void EvaluateRandomFiveCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(5));
  }
  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4]);
    }
  }
}
BENCHMARK(EvaluateRandomFiveCards);

static void EvaluateRandomSixCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(6));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4],
                    hands[i][5]);
    }
  }
}
BENCHMARK(EvaluateRandomSixCards);

static void EvaluateRandomSevenCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(7));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4],
                    hands[i][5],
                    hands[i][6]);
    }
  }
}
BENCHMARK(EvaluateRandomSevenCards);

static void EvaluateRandomOmahaCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(9));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateOmahaCards(hands[i][0],
                         hands[i][1],
                         hands[i][2],
                         hands[i][3],
                         hands[i][4],
                         hands[i][5],
                         hands[i][6],
                         hands[i][7],
                         hands[i][8]);
    }
  }}
BENCHMARK(EvaluateRandomOmahaCards);

BENCHMARK_MAIN();

<commit_msg>Try 100 samples in the benchmark<commit_after>#include <algorithm>
#include <vector>
#include <set>
#include <chrono>
#include <random>
#include "phevaluator/phevaluator.h"
#include "benchmark/benchmark.h"

using namespace phevaluator;

static void EvaluateAllFiveCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 48; a++) {
      for(int b = a + 1; b < 49; b++) {
        for(int c = b + 1; c < 50; c++) {
          for(int d = c + 1; d < 51; d++) {
            for(int e = d + 1; e < 52; e++) {
              EvaluateCards(a, b, c, d, e);
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllFiveCards);

static void EvaluateAllSixCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 47; a++) {
      for(int b = a + 1; b < 48; b++) {
        for(int c = b + 1; c < 49; c++) {
          for(int d = c + 1; d < 50; d++) {
            for(int e = d + 1; e < 51; e++) {
              for(int f = e + 1; f < 52; f++) {
                EvaluateCards(a, b, c, d, e, f);
              }
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllSixCards);

static void EvaluateAllSevenCards(benchmark::State& state) {
  for (auto _ : state) {
    for(int a = 0; a < 46; a++) {
      for(int b = a + 1; b < 47; b++) {
        for(int c = b + 1; c < 48; c++) {
          for(int d = c + 1; d < 49; d++) {
            for(int e = d + 1; e < 50; e++) {
              for(int f = e + 1; f < 51; f++) {
                for(int g = f + 1; g < 52; g++) {
                  EvaluateCards(a, b, c, d, e, f, g);
                }
              }
            }
          }
        }
      }
    }
  }
}
BENCHMARK(EvaluateAllSevenCards);

static unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
static std::default_random_engine generator(seed);
static std::uniform_int_distribution<int> distribution(0, 51);

static std::vector<int> RandomCardSample(int size) {
  std::vector<int> ret;
  std::set<int> sample;

  while (sample.size() < size) {
    int number = distribution(generator);
    if (sample.find(number) == sample.end()) {
      ret.push_back(number);
      sample.insert(number);
    }
  }

  return ret;
}

const int SIZE = 100;

static void EvaluateRandomFiveCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(5));
  }
  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4]);
    }
  }
}
BENCHMARK(EvaluateRandomFiveCards);

static void EvaluateRandomSixCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(6));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4],
                    hands[i][5]);
    }
  }
}
BENCHMARK(EvaluateRandomSixCards);

static void EvaluateRandomSevenCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(7));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateCards(hands[i][0],
                    hands[i][1],
                    hands[i][2],
                    hands[i][3],
                    hands[i][4],
                    hands[i][5],
                    hands[i][6]);
    }
  }
}
BENCHMARK(EvaluateRandomSevenCards);

static void EvaluateRandomOmahaCards(benchmark::State& state) {
  std::vector<std::vector<int>> hands;

  for (int i = 0; i < SIZE; i++) {
    hands.push_back(RandomCardSample(9));
  }

  for (auto _ : state) {
    for (int i = 0; i < SIZE; i++) {
      EvaluateOmahaCards(hands[i][0],
                         hands[i][1],
                         hands[i][2],
                         hands[i][3],
                         hands[i][4],
                         hands[i][5],
                         hands[i][6],
                         hands[i][7],
                         hands[i][8]);
    }
  }}
BENCHMARK(EvaluateRandomOmahaCards);

BENCHMARK_MAIN();

<|endoftext|>


<commit_before>/*
 * Multiplatform Async Network Library
 * Copyright (c) 2007 Burlex
 *
 * Socket implementable class.
 *
 */

#include "Network.h"

initialiseSingleton(SocketGarbageCollector);

Socket::Socket(SOCKET fd, uint32 sendbuffersize, uint32 recvbuffersize) : m_readBufferSize(recvbuffersize),
	m_writeBufferSize(sendbuffersize), m_fd(fd), m_readByteCount(0), m_writeByteCount(0), m_connected(false),
	m_deleted(false)
{
	// Allocate Buffers
	m_readBuffer = (uint8*)malloc(recvbuffersize);
	m_writeBuffer = (uint8*)malloc(sendbuffersize);

	// IOCP Member Variables
#ifdef CONFIG_USE_IOCP
	m_writeLock = 0;
	m_completionPort = 0;
#else
	m_writeLock = 0;
#endif

	// Check for needed fd allocation.
	if(m_fd == 0)
		m_fd = SocketOps::CreateTCPFileDescriptor();
}

Socket::~Socket()
{
	// Deallocate buffers
	free(m_readBuffer);
	free(m_writeBuffer);

#ifdef CONFIG_USE_IOCP
	/*if(m_readEvent != NULL)
		delete m_readEvent;*/
#endif
}

bool Socket::Connect(const char * Address, uint32 Port)
{
	struct hostent * ci = gethostbyname(Address);
	if(ci == 0)
		return false;

	m_client.sin_family = ci->h_addrtype;
	m_client.sin_port = ntohs((u_short)Port);
	memcpy(&m_client.sin_addr.s_addr, ci->h_addr_list[0], ci->h_length);

	SocketOps::Blocking(m_fd);
	if(connect(m_fd, (const sockaddr*)&m_client, sizeof(m_client)) == -1)
		return false;

	// at this point the connection was established
#ifdef CONFIG_USE_IOCP
	m_completionPort = sSocketMgr.GetCompletionPort();
#endif
	_OnConnect();
	return true;
}

void Socket::Accept(sockaddr_in * address)
{
	memcpy(&m_client, address, sizeof(*address));
	_OnConnect();
}

void Socket::_OnConnect()
{
	// set common parameters on the file descriptor
	SocketOps::Nonblocking(m_fd);
	SocketOps::DisableBuffering(m_fd);
	SocketOps::SetRecvBufferSize(m_fd, m_writeBufferSize);
	SocketOps::SetSendBufferSize(m_fd, m_writeBufferSize);
	m_connected = true;

	// IOCP stuff
#ifdef CONFIG_USE_IOCP
	AssignToCompletionPort();
	SetupReadEvent();
#endif
	sSocketMgr.AddSocket(this);

	// Call virtual onconnect
	OnConnect();
}

bool Socket::Send(const uint8 * Bytes, uint32 Size)
{
	bool rv;

	// This is really just a wrapper for all the burst stuff.
	BurstBegin();
	rv = BurstSend(Bytes, Size);
	if(rv)
		BurstPush();
	BurstEnd();

	return rv;
}

bool Socket::BurstSend(const uint8 * Bytes, uint32 Size)
{
	// Check for buffer space.
	if((Size + m_writeByteCount) >= m_writeBufferSize)
		return false;

	// Copy into the buffer.
	memcpy(&m_writeBuffer[m_writeByteCount], Bytes, Size);
	m_writeByteCount += Size;

	return true;
}

void Socket::RemoveReadBufferBytes(uint32 size, bool lock)
{
	if(lock)
		m_readMutex.Acquire();

	if(m_readByteCount < size)
	{
		Disconnect();
		if(lock)
			m_readMutex.Release();

		return;
	}

	if(size == m_readByteCount)	 // complete erasure
		m_readByteCount = 0;
	else
	{
		memcpy(m_readBuffer, &m_readBuffer[size], m_readByteCount - size);
		m_readByteCount -= size;
	}

	if(lock)
		m_readMutex.Release();
}

void Socket::RemoveWriteBufferBytes(uint32 size, bool lock)
{
	if(lock)
		m_writeMutex.Acquire();

	if(m_writeByteCount < size)
	{
		Disconnect();
		if(lock)
			m_writeMutex.Release();

		return;
	}

	if(size == m_writeByteCount)	 // complete erasure
		m_writeByteCount = 0;
	else
	{
		//memcpy(m_writeBuffer, &m_writeBuffer[size], m_writeByteCount - size);
		memmove(m_writeBuffer, &m_writeBuffer[size], m_writeByteCount - size);
		m_writeByteCount -= size;
	}

	if(lock)
		m_writeMutex.Release();
}

string Socket::GetRemoteIP()
{
	// inet_ntoa may leak memory, so we'll do this our own way.
	char * ip = (char*)inet_ntoa(m_client.sin_addr);
	string ret = string(ip);
	//free(ip);
	return ret;
}

void Socket::Disconnect()
{
	m_connected = false;

	// remove from mgr
	sSocketMgr.RemoveSocket(this);

	SocketOps::CloseSocket(m_fd);

	// Call virtual ondisconnect
	OnDisconnect();

	if(!m_deleted) Delete();
}

void Socket::Delete()
{
	if(m_deleted) return;
	m_deleted = true;

	if(m_connected) Disconnect();
	sSocketGarbageCollector.QueueSocket(this);
}

void Socket::Read(uint32 size, uint8 * buffer)
{
	assert(size <= m_readByteCount);
	memcpy(buffer, m_readBuffer, size);
	RemoveReadBufferBytes(size, false);
}

<commit_msg>crash fix<commit_after>/*
 * Multiplatform Async Network Library
 * Copyright (c) 2007 Burlex
 *
 * Socket implementable class.
 *
 */

#include "Network.h"

initialiseSingleton(SocketGarbageCollector);

Socket::Socket(SOCKET fd, uint32 sendbuffersize, uint32 recvbuffersize) : m_readBufferSize(recvbuffersize),
	m_writeBufferSize(sendbuffersize), m_fd(fd), m_readByteCount(0), m_writeByteCount(0), m_connected(false),
	m_deleted(false)
{
	// Allocate Buffers
	m_readBuffer = (uint8*)malloc(recvbuffersize);
	m_writeBuffer = (uint8*)malloc(sendbuffersize);

	// IOCP Member Variables
#ifdef CONFIG_USE_IOCP
	m_writeLock = 0;
	m_completionPort = 0;
#else
	m_writeLock = 0;
#endif

	// Check for needed fd allocation.
	if(m_fd == 0)
		m_fd = SocketOps::CreateTCPFileDescriptor();
}

Socket::~Socket()
{
	// Deallocate buffers
	free(m_readBuffer);
	free(m_writeBuffer);

#ifdef CONFIG_USE_IOCP
	/*if(m_readEvent != NULL)
		delete m_readEvent;*/
#endif
}

bool Socket::Connect(const char * Address, uint32 Port)
{
	struct hostent * ci = gethostbyname(Address);
	if(ci == 0)
		return false;

	m_client.sin_family = ci->h_addrtype;
	m_client.sin_port = ntohs((u_short)Port);
	memcpy(&m_client.sin_addr.s_addr, ci->h_addr_list[0], ci->h_length);

	SocketOps::Blocking(m_fd);
	if(connect(m_fd, (const sockaddr*)&m_client, sizeof(m_client)) == -1)
		return false;

	// at this point the connection was established
#ifdef CONFIG_USE_IOCP
	m_completionPort = sSocketMgr.GetCompletionPort();
#endif
	_OnConnect();
	return true;
}

void Socket::Accept(sockaddr_in * address)
{
	memcpy(&m_client, address, sizeof(*address));
	_OnConnect();
}

void Socket::_OnConnect()
{
	// set common parameters on the file descriptor
	SocketOps::Nonblocking(m_fd);
	SocketOps::DisableBuffering(m_fd);
	SocketOps::SetRecvBufferSize(m_fd, m_writeBufferSize);
	SocketOps::SetSendBufferSize(m_fd, m_writeBufferSize);
	m_connected = true;

	// IOCP stuff
#ifdef CONFIG_USE_IOCP
	AssignToCompletionPort();
	SetupReadEvent();
#endif
	sSocketMgr.AddSocket(this);

	// Call virtual onconnect
	OnConnect();
}

bool Socket::Send(const uint8 * Bytes, uint32 Size)
{
	bool rv;

	// This is really just a wrapper for all the burst stuff.
	BurstBegin();
	rv = BurstSend(Bytes, Size);
	if(rv)
		BurstPush();
	BurstEnd();

	return rv;
}

bool Socket::BurstSend(const uint8 * Bytes, uint32 Size)
{
	// Check for buffer space.
	if((Size + m_writeByteCount) >= m_writeBufferSize)
		return false;

	// Copy into the buffer.
	memcpy(&m_writeBuffer[m_writeByteCount], Bytes, Size);
	m_writeByteCount += Size;

	return true;
}

void Socket::RemoveReadBufferBytes(uint32 size, bool lock)
{
	if(lock)
		m_readMutex.Acquire();

	if(m_readByteCount < size)
	{
		Disconnect();
		if(lock)
			m_readMutex.Release();

		return;
	}

	if(size == m_readByteCount)	 // complete erasure
		m_readByteCount = 0;
	else
	{
		memcpy(m_readBuffer, &m_readBuffer[size], m_readByteCount - size);
		m_readByteCount -= size;
	}

	if(lock)
		m_readMutex.Release();
}

void Socket::RemoveWriteBufferBytes(uint32 size, bool lock)
{
	if(lock)
		m_writeMutex.Acquire();

	if(m_writeByteCount < size)
	{
		Disconnect();
		if(lock)
			m_writeMutex.Release();

		return;
	}

	if(size == m_writeByteCount)	 // complete erasure
		m_writeByteCount = 0;
	else
	{
		//memcpy(m_writeBuffer, &m_writeBuffer[size], m_writeByteCount - size);
		memmove(m_writeBuffer, &m_writeBuffer[size], m_writeByteCount - size);
		m_writeByteCount -= size;
	}

	if(lock)
		m_writeMutex.Release();
}

string Socket::GetRemoteIP()
{
	char* ip = (char*)inet_ntoa( m_client.sin_addr );
	if( ip != NULL )
		return string( ip );
	else
		return string( "" );
}

void Socket::Disconnect()
{
	m_connected = false;

	// remove from mgr
	sSocketMgr.RemoveSocket(this);

	SocketOps::CloseSocket(m_fd);

	// Call virtual ondisconnect
	OnDisconnect();

	if(!m_deleted) Delete();
}

void Socket::Delete()
{
	if(m_deleted) return;
	m_deleted = true;

	if(m_connected) Disconnect();
	sSocketGarbageCollector.QueueSocket(this);
}

void Socket::Read(uint32 size, uint8 * buffer)
{
	assert(size <= m_readByteCount);
	memcpy(buffer, m_readBuffer, size);
	RemoveReadBufferBytes(size, false);
}

<|endoftext|>


<commit_before>//
// MessagePack for C++ memory pool
//
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//
#ifndef MSGPACK_ZONE_HPP
#define MSGPACK_ZONE_HPP

#include <cstdlib>
#include <memory>
#include <vector>

#include "cpp_config.hpp"

#ifndef MSGPACK_ZONE_CHUNK_SIZE
#define MSGPACK_ZONE_CHUNK_SIZE 8192
#endif

#ifndef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN sizeof(int)
#endif

namespace msgpack {

class zone {
private:
	struct finalizer {
		finalizer(void (*func)(void*), void* data):func_(func), data_(data) {}
		void operator()() { func_(data_); }
		void (*func_)(void*);
		void* data_;
	};
	struct finalizer_array {
		finalizer_array():tail_(nullptr), end_(nullptr), array_(nullptr) {}
		void call() {
			finalizer* fin = tail_;
			for(; fin != array_; --fin) (*(fin-1))();
		}
		~finalizer_array() {
			call();
			::free(array_);
		}
		void clear() {
			call();
			tail_ = array_;
		}
		void push(void (*func)(void* data), void* data)
		{
			finalizer* fin = tail_;

			if(fin == end_) {
				push_expand(func, data);
				return;
			}

			fin->func_ = func;
			fin->data_ = data;

			++tail_;
		}
		void push_expand(void (*func)(void*), void* data) {
			const size_t nused = end_ - array_;
			size_t nnext;
			if(nused == 0) {
				nnext = (sizeof(finalizer) < 72/2) ?
					72 / sizeof(finalizer) : 8;
			} else {
				nnext = nused * 2;
			}
			finalizer* tmp =
				static_cast<finalizer*>(::realloc(array_, sizeof(finalizer) * nnext));
			if(!tmp) {
				throw std::bad_alloc();
			}
			array_	= tmp;
			end_	= tmp + nnext;
			tail_	= tmp + nused;
			new (tail_) finalizer(func, data);

			++tail_;
		}
		finalizer* tail_;
		finalizer* end_;
		finalizer* array_;
	};
	struct chunk {
		chunk* next_;
	};
	struct chunk_list {
		chunk_list(size_t chunk_size)
		{
			chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
			if(!c) {
				throw std::bad_alloc();
			}

			head_ = c;
			free_ = chunk_size;
			ptr_  = reinterpret_cast<char*>(c) + sizeof(chunk);
			c->next_ = nullptr;
		}
		~chunk_list()
		{
			chunk* c = head_;
			while(true) {
				chunk* n = c->next_;
				::free(c);
				if(n) {
					c = n;
				} else {
					break;
				}
			}
		}
		void clear(size_t chunk_size)
		{
			chunk* c = head_;
			while(true) {
				chunk* n = c->next_;
				if(n) {
					::free(c);
					c = n;
				} else {
					head_ = c;
					break;
				}
			}
			head_->next_ = nullptr;
			free_ = chunk_size;
			ptr_  = reinterpret_cast<char*>(head_) + sizeof(chunk);
		}
		size_t free_;
		char* ptr_;
		chunk* head_;
	};
	size_t chunk_size_;
	chunk_list chunk_list_;
	finalizer_array finalizer_array_;

public:
	zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept;

public:
	static zone* create(size_t chunk_size);
	static void destroy(zone* zone);
	void* allocate_align(size_t size);
	void* allocate_no_align(size_t size);

	void push_finalizer(void (*func)(void*), void* data);

	template <typename T>
	void push_finalizer(msgpack::unique_ptr<T> obj);

	void clear();

	void swap(zone& o);

	template <typename T, typename... Args>
	T* allocate(Args... args);

private:
	void undo_allocate(size_t size);

	template <typename T>
	static void object_destructor(void* obj);

	void* allocate_expand(size_t size);
};

inline zone* zone::create(size_t chunk_size)
{
	zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size));
	if (!z) {
		return nullptr;
	}
	new (z) zone(chunk_size);
	return z;
}

inline void zone::destroy(zone* z)
{
	z->~zone();
	::free(z);
}

inline zone::zone(size_t chunk_size) noexcept:chunk_size_(chunk_size), chunk_list_(chunk_size_)
{
}

inline void* zone::allocate_align(size_t size)
{
	return allocate_no_align(
		((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
}

inline void* zone::allocate_no_align(size_t size)
{
	if(chunk_list_.free_ < size) {
		return allocate_expand(size);
	}

	char* ptr = chunk_list_.ptr_;
	chunk_list_.free_ -= size;
	chunk_list_.ptr_  += size;

	return ptr;
}

inline void* zone::allocate_expand(size_t size)
{
	chunk_list* const cl = &chunk_list_;

	size_t sz = chunk_size_;

	while(sz < size) {
		sz *= 2;
	}

	chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));

	char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);

	c->next_  = cl->head_;
	cl->head_ = c;
	cl->free_ = sz - size;
	cl->ptr_  = ptr + size;

	return ptr;
}

inline void zone::push_finalizer(void (*func)(void*), void* data)
{
	finalizer_array_.push(func, data);
}

template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{
	finalizer_array_.push(&zone::object_destructor<T>, obj.get());
	obj.release();
}

inline void zone::clear()
{
	finalizer_array_.clear();
	chunk_list_.clear(chunk_size_);
}

inline void zone::swap(zone& o)
{
	std::swap(*this, o);
}

template <typename T>
void zone::object_destructor(void* obj)
{
	reinterpret_cast<T*>(obj)->~T();
}

inline void zone::undo_allocate(size_t size)
{
	chunk_list_.ptr_  -= size;
	chunk_list_.free_ += size;
}

template <typename T, typename... Args>
T* zone::allocate(Args... args)
{
	void* x = allocate_align(sizeof(T));
	try {
		finalizer_array_.push(&zone::object_destructor<T>, x);
	} catch (...) {
		undo_allocate(sizeof(T));
		throw;
	}
	try {
		return new (x) T(args...);
	} catch (...) {
		--finalizer_array_.tail_;
		undo_allocate(sizeof(T));
		throw;
	}
}

}  // namespace msgpack

#endif /* msgpack/zone.hpp */
<commit_msg>Added null pointer check for C++ separated code.<commit_after>//
// MessagePack for C++ memory pool
//
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//
#ifndef MSGPACK_ZONE_HPP
#define MSGPACK_ZONE_HPP

#include <cstdlib>
#include <memory>
#include <vector>

#include "cpp_config.hpp"

#ifndef MSGPACK_ZONE_CHUNK_SIZE
#define MSGPACK_ZONE_CHUNK_SIZE 8192
#endif

#ifndef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN sizeof(int)
#endif

namespace msgpack {

class zone {
private:
	struct finalizer {
		finalizer(void (*func)(void*), void* data):func_(func), data_(data) {}
		void operator()() { func_(data_); }
		void (*func_)(void*);
		void* data_;
	};
	struct finalizer_array {
		finalizer_array():tail_(nullptr), end_(nullptr), array_(nullptr) {}
		void call() {
			finalizer* fin = tail_;
			for(; fin != array_; --fin) (*(fin-1))();
		}
		~finalizer_array() {
			call();
			::free(array_);
		}
		void clear() {
			call();
			tail_ = array_;
		}
		void push(void (*func)(void* data), void* data)
		{
			finalizer* fin = tail_;

			if(fin == end_) {
				push_expand(func, data);
				return;
			}

			fin->func_ = func;
			fin->data_ = data;

			++tail_;
		}
		void push_expand(void (*func)(void*), void* data) {
			const size_t nused = end_ - array_;
			size_t nnext;
			if(nused == 0) {
				nnext = (sizeof(finalizer) < 72/2) ?
					72 / sizeof(finalizer) : 8;
			} else {
				nnext = nused * 2;
			}
			finalizer* tmp =
				static_cast<finalizer*>(::realloc(array_, sizeof(finalizer) * nnext));
			if(!tmp) {
				throw std::bad_alloc();
			}
			array_	= tmp;
			end_	= tmp + nnext;
			tail_	= tmp + nused;
			new (tail_) finalizer(func, data);

			++tail_;
		}
		finalizer* tail_;
		finalizer* end_;
		finalizer* array_;
	};
	struct chunk {
		chunk* next_;
	};
	struct chunk_list {
		chunk_list(size_t chunk_size)
		{
			chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
			if(!c) {
				throw std::bad_alloc();
			}

			head_ = c;
			free_ = chunk_size;
			ptr_  = reinterpret_cast<char*>(c) + sizeof(chunk);
			c->next_ = nullptr;
		}
		~chunk_list()
		{
			chunk* c = head_;
			while(true) {
				chunk* n = c->next_;
				::free(c);
				if(n) {
					c = n;
				} else {
					break;
				}
			}
		}
		void clear(size_t chunk_size)
		{
			chunk* c = head_;
			while(true) {
				chunk* n = c->next_;
				if(n) {
					::free(c);
					c = n;
				} else {
					head_ = c;
					break;
				}
			}
			head_->next_ = nullptr;
			free_ = chunk_size;
			ptr_  = reinterpret_cast<char*>(head_) + sizeof(chunk);
		}
		size_t free_;
		char* ptr_;
		chunk* head_;
	};
	size_t chunk_size_;
	chunk_list chunk_list_;
	finalizer_array finalizer_array_;

public:
	zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept;

public:
	static zone* create(size_t chunk_size);
	static void destroy(zone* zone);
	void* allocate_align(size_t size);
	void* allocate_no_align(size_t size);

	void push_finalizer(void (*func)(void*), void* data);

	template <typename T>
	void push_finalizer(msgpack::unique_ptr<T> obj);

	void clear();

	void swap(zone& o);

	template <typename T, typename... Args>
	T* allocate(Args... args);

private:
	void undo_allocate(size_t size);

	template <typename T>
	static void object_destructor(void* obj);

	void* allocate_expand(size_t size);
};

inline zone* zone::create(size_t chunk_size)
{
	zone* z = static_cast<zone*>(::malloc(sizeof(zone) + chunk_size));
	if (!z) {
		return nullptr;
	}
	new (z) zone(chunk_size);
	return z;
}

inline void zone::destroy(zone* z)
{
	z->~zone();
	::free(z);
}

inline zone::zone(size_t chunk_size) noexcept:chunk_size_(chunk_size), chunk_list_(chunk_size_)
{
}

inline void* zone::allocate_align(size_t size)
{
	return allocate_no_align(
		((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
}

inline void* zone::allocate_no_align(size_t size)
{
	if(chunk_list_.free_ < size) {
		return allocate_expand(size);
	}

	char* ptr = chunk_list_.ptr_;
	chunk_list_.free_ -= size;
	chunk_list_.ptr_  += size;

	return ptr;
}

inline void* zone::allocate_expand(size_t size)
{
	chunk_list* const cl = &chunk_list_;

	size_t sz = chunk_size_;

	while(sz < size) {
		sz *= 2;
	}

	chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
	if (!c) return nullptr;

	char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
	if (!ptr) {
		::free(c);
		return nullptr;
	}

	c->next_  = cl->head_;
	cl->head_ = c;
	cl->free_ = sz - size;
	cl->ptr_  = ptr + size;

	return ptr;
}

inline void zone::push_finalizer(void (*func)(void*), void* data)
{
	finalizer_array_.push(func, data);
}

template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{
	finalizer_array_.push(&zone::object_destructor<T>, obj.get());
	obj.release();
}

inline void zone::clear()
{
	finalizer_array_.clear();
	chunk_list_.clear(chunk_size_);
}

inline void zone::swap(zone& o)
{
	std::swap(*this, o);
}

template <typename T>
void zone::object_destructor(void* obj)
{
	reinterpret_cast<T*>(obj)->~T();
}

inline void zone::undo_allocate(size_t size)
{
	chunk_list_.ptr_  -= size;
	chunk_list_.free_ += size;
}

template <typename T, typename... Args>
T* zone::allocate(Args... args)
{
	void* x = allocate_align(sizeof(T));
	try {
		finalizer_array_.push(&zone::object_destructor<T>, x);
	} catch (...) {
		undo_allocate(sizeof(T));
		throw;
	}
	try {
		return new (x) T(args...);
	} catch (...) {
		--finalizer_array_.tail_;
		undo_allocate(sizeof(T));
		throw;
	}
}

}  // namespace msgpack

#endif /* msgpack/zone.hpp */
<|endoftext|>


<commit_before>//
// Copyright (c) 2016 Kimball Thurston
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#include "plane_resize.h"
#include "scanline_process.h"
#include <base/cpu_features.h>

////////////////////////////////////////

namespace
{
using namespace image;

static void
doResizeVertPoint( scanline &dest, int y, const plane &in, float scale )
{
	int srcY = static_cast<int>( ( static_cast<float>( y ) + 0.5F ) * scale );
	srcY = std::min( in.height() - 1, srcY );
	const float *inLine = in.line( srcY );
	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = inLine[x];
}

static void
doResizeHorizPoint( scanline &dest, const scanline &in, float scale )
{
	int maxS = in.width() - 1;
	for ( int x = 0; x < dest.width(); ++x )
	{
		int srcX = static_cast<int>( ( static_cast<float>( x ) + 0.5F ) * scale );
		srcX = std::min( maxS, srcX );
		dest[x] = in[srcX];
	}
}

////////////////////////////////////////

static void
doResizeVertBilinear( scanline &dest, int y, const plane &in, float scale )
{
	float srcY = ( static_cast<float>( y ) + 0.5F ) * scale;
	int lowY = static_cast<int>( srcY );
	float perc = srcY - static_cast<float>( lowY );

	const float *lowLine = in.line( lowY );
	const float *hiLine = lowLine;
	if ( ( lowY + 1 ) < in.height() )
		hiLine = in.line( lowY + 1 );
	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = base::lerp( lowLine[x], hiLine[x], perc );
}

static void
doResizeHorizBilinear( scanline &dest, const scanline &in, float scale )
{
	for ( int x = 0; x < dest.width(); ++x )
	{
		float srcX = ( static_cast<float>( x ) + 0.5F ) * scale;
		int lowX = static_cast<int>( srcX );
		float perc = srcX - static_cast<float>( lowX );
		int hiX = lowX + 1;
		if ( hiX >= dest.width() )
			hiX = lowX;

		dest[x] = base::lerp( in[lowX], in[hiX], perc );
	}
}

////////////////////////////////////////

static void
doResizeVertBicubic( scanline &dest, int y, const plane &in, float scale )
{
	float srcY = ( static_cast<float>( y ) + 0.5F ) * scale;
	int pY = static_cast<int>( srcY );
	float t = srcY - static_cast<float>( pY );
	int hm1 = in.height() - 1;
	const float *p0 = in.line( std::max( int(0), pY - 1 ) );
	const float *p1 = in.line( pY );
	const float *p2 = in.line( std::min( int(hm1), pY + 1 ) );
	const float *p3 = in.line( std::min( int(hm1), pY + 2 ) );

	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = base::cubic_interp( t, p0[x], p1[x], p2[x], p3[x] );
}

static void
doResizeHorizBicubic( scanline &dest, const scanline &in, float scale )
{
	int wm1 = in.width() - 1;
	for ( int x = 0; x < dest.width(); ++x )
	{
		float srcX = ( static_cast<float>( x ) + 0.5F ) * scale;
		int pX = static_cast<int>( srcX );
		float p0 = in[std::max( int(0), pX - 1 )];
		float p1 = in[pX];
		float p2 = in[std::min( int(wm1), pX + 1 )];
		float p3 = in[std::min( int(wm1), pX + 2 )];

		float t = srcX - static_cast<float>( pX );
		dest[x] = base::cubic_interp( t, p0, p1, p2, p3 );
	}
}

} // empty namespace

////////////////////////////////////////

namespace image
{

////////////////////////////////////////

plane
resize_horiz_point( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_point", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_point( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_point", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz_bilinear( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_bilinear", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_bilinear( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_bilinear", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz_bicubic( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_bicubic", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_bicubic( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_bicubic", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz( const plane &p, const std::string &filter, int neww )
{
	throw_not_yet();
}

////////////////////////////////////////

plane
resize_vert( const plane &p, const std::string &filter, int newh )
{
	throw_not_yet();
}

////////////////////////////////////////

std::vector<plane>
make_pyramid( const plane &in, const std::string &filter, float eta, int n )
{
	precondition( eta > 0.F && eta < 1.F, "Invalid eta {0} for pyramid, must be between 0 and 1", eta );

	std::vector<plane> ret;
	int curLev = 1;
	ret.push_back( in );
	while ( n == 0 || curLev < n )
	{
		float curS = powf( eta, curLev );
		float curWf = curS * static_cast<float>( in.width() );
		float curHf = curS * static_cast<float>( in.height() );
		int curW = static_cast<int>( ceilf( curWf ) );
		int curH = static_cast<int>( ceilf( curHf ) );

		if ( curW < 2 || curH < 2 )
		{
			std::cout << "Terminating pyramid at level " << curLev << std::endl;
			break;
		}

		std::cout << "adding level " << curLev << " at " << curW << "x" << curH << std::endl;
		if ( filter == "bilinear" )
			ret.push_back( resize_bilinear( ret.back(), curW, curH ) );
		else if ( filter == "bicubic" )
			ret.push_back( resize_bicubic( ret.back(), curW, curH ) );
		else if ( filter == "point" || filter == "dirac" )
			ret.push_back( resize_point( ret.back(), curW, curH ) );
		else
			throw_not_yet();

		++curLev;
	}

	return ret;
}

////////////////////////////////////////

std::vector<image_buf>
make_pyramid( const image_buf &in, const std::string &filter, float eta, int n )
{
	precondition( eta > 0.F && eta < 1.F, "Invalid eta {0} for pyramid, must be between 0 and 1", eta );

	std::vector<image_buf> ret;
	int curLev = 1;
	ret.push_back( in );
	while ( n == 0 || curLev < n )
	{
		float curS = powf( eta, curLev );
		float curWf = curS * static_cast<float>( in.width() );
		float curHf = curS * static_cast<float>( in.height() );
		int curW = static_cast<int>( ceilf( curWf ) );
		int curH = static_cast<int>( ceilf( curHf ) );

		if ( curW < 2 || curH < 2 )
		{
			std::cout << "Terminating pyramid at level " << curLev << std::endl;
			break;
		}

		std::cout << "adding level " << curLev << " at " << curW << "x" << curH << std::endl;
		if ( filter == "bilinear" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_bilinear( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else if ( filter == "bicubic" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_bicubic( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else if ( filter == "point" || filter == "dirac" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_point( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else
		{
			throw_not_yet();
		}
		++curLev;
	}

	return ret;
}

////////////////////////////////////////

void
add_resize( engine::registry &r )
{
	using namespace engine;
	r.add( op( "p.resize_vert_point", base::choose_runtime( doResizeVertPoint ), n_scanline_plane_adapter<false, decltype(doResizeVertPoint)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_point", base::choose_runtime( doResizeHorizPoint ), scanline_plane_adapter<true, decltype(doResizeHorizPoint)>(), dispatch_scan_processing, op::one_to_one ) );

	r.add( op( "p.resize_vert_bilinear", base::choose_runtime( doResizeVertBilinear ), n_scanline_plane_adapter<false, decltype(doResizeVertBilinear)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_bilinear", base::choose_runtime( doResizeHorizBilinear ), scanline_plane_adapter<true, decltype(doResizeHorizBilinear)>(), dispatch_scan_processing, op::one_to_one ) );

	r.add( op( "p.resize_vert_bicubic", base::choose_runtime( doResizeVertBicubic ), n_scanline_plane_adapter<false, decltype(doResizeVertBicubic)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_bicubic", base::choose_runtime( doResizeHorizBicubic ), scanline_plane_adapter<true, decltype(doResizeHorizBicubic)>(), dispatch_scan_processing, op::one_to_one ) );

//	r.add( op( "p.resize_vert_generic", base::choose_runtime( doResizeVertGeneric ), n_scanline_plane_adapter<false, decltype(doResizeVertGeneric)>(), dispatch_scan_processing, op::n_to_one ) );
//	r.add( op( "p.resize_horiz_generic", base::choose_runtime( doResizeHorizGeneric ), scanline_plane_adapter<true, decltype(doResizeHorizGeneric)>(), dispatch_scan_processing, op::one_to_one ) );
}

////////////////////////////////////////

} // image

<commit_msg>fix rounding, out of bounds access in simple resizers<commit_after>//
// Copyright (c) 2016 Kimball Thurston
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#include "plane_resize.h"
#include "scanline_process.h"
#include <base/cpu_features.h>

////////////////////////////////////////

namespace
{
using namespace image;

static void
doResizeVertPoint( scanline &dest, int y, const plane &in, float scale )
{
	int srcY = static_cast<int>( ( static_cast<float>( y ) ) * scale + 0.5F );
	srcY = std::min( in.height() - 1, srcY );
	const float *inLine = in.line( srcY );
	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = inLine[x];
}

static void
doResizeHorizPoint( scanline &dest, const scanline &in, float scale )
{
	int maxS = in.width() - 1;
	for ( int x = 0; x < dest.width(); ++x )
	{
		int srcX = static_cast<int>( ( static_cast<float>( x ) ) * scale + 0.5F );
		srcX = std::min( maxS, srcX );
		dest[x] = in[srcX];
	}
}

////////////////////////////////////////

static void
doResizeVertBilinear( scanline &dest, int y, const plane &in, float scale )
{
	float srcY = static_cast<float>( y ) * scale;
	int lowY = static_cast<int>( srcY );
	float perc = srcY - static_cast<float>( lowY );
	lowY = std::min( in.height() - 1, lowY );

	const float *lowLine = in.line( lowY );
	const float *hiLine = lowLine;
	if ( ( lowY + 1 ) < in.height() )
		hiLine = in.line( lowY + 1 );
	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = base::lerp( lowLine[x], hiLine[x], perc );
}

static void
doResizeHorizBilinear( scanline &dest, const scanline &in, float scale )
{
	int maxw = in.width() - 1;
	for ( int x = 0; x < dest.width(); ++x )
	{
		float srcX = static_cast<float>( x ) * scale;
		int lowX = static_cast<int>( srcX );
		float perc = srcX - static_cast<float>( lowX );
		lowX = std::min( maxw, lowX );
		int hiX = std::min( maxw, lowX + 1 );

		dest[x] = base::lerp( in[lowX], in[hiX], perc );
	}
}

////////////////////////////////////////

static void
doResizeVertBicubic( scanline &dest, int y, const plane &in, float scale )
{
	float srcY = static_cast<float>( y ) * scale;
	int pY = static_cast<int>( srcY );
	float t = srcY - static_cast<float>( pY );
	int hm1 = in.height() - 1;
	pY = std::min( hm1, pY );
	const float *p0 = in.line( std::max( int(0), pY - 1 ) );
	const float *p1 = in.line( pY );
	const float *p2 = in.line( std::min( int(hm1), pY + 1 ) );
	const float *p3 = in.line( std::min( int(hm1), pY + 2 ) );

	for ( int x = 0; x < dest.width(); ++x )
		dest[x] = base::cubic_interp( t, p0[x], p1[x], p2[x], p3[x] );
}

static void
doResizeHorizBicubic( scanline &dest, const scanline &in, float scale )
{
	int wm1 = in.width() - 1;
	for ( int x = 0; x < dest.width(); ++x )
	{
		float srcX = static_cast<float>( x ) * scale;
		int pX = static_cast<int>( srcX );
		float t = srcX - static_cast<float>( pX );
		pX = std::min( wm1, pX );
		float p0 = in[std::max( int(0), pX - 1 )];
		float p1 = in[pX];
		float p2 = in[std::min( int(wm1), pX + 1 )];
		float p3 = in[std::min( int(wm1), pX + 2 )];

		dest[x] = base::cubic_interp( t, p0, p1, p2, p3 );
	}
}

} // empty namespace

////////////////////////////////////////

namespace image
{

////////////////////////////////////////

plane
resize_horiz_point( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_point", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_point( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_point", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz_bilinear( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_bilinear", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_bilinear( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_bilinear", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz_bicubic( const plane &p, int neww )
{
	precondition( neww > 0, "Invalid new width {0} to resize", neww );
	engine::dimensions d = p.dims();
	d.x = neww;
	float scale = static_cast<float>( p.width() ) / static_cast<float>( neww );
	return plane( "p.resize_horiz_bicubic", d, p, scale );
}

////////////////////////////////////////

plane
resize_vert_bicubic( const plane &p, int newh )
{
	precondition( newh > 0, "Invalid new width {0} to resize", newh );
	engine::dimensions d = p.dims();
	d.y = newh;
	float scale = static_cast<float>( p.height() ) / static_cast<float>( newh );
	return plane( "p.resize_vert_bicubic", d, p, scale );
}

////////////////////////////////////////

plane
resize_horiz( const plane &p, const std::string &filter, int neww )
{
	throw_not_yet();
}

////////////////////////////////////////

plane
resize_vert( const plane &p, const std::string &filter, int newh )
{
	throw_not_yet();
}

////////////////////////////////////////

std::vector<plane>
make_pyramid( const plane &in, const std::string &filter, float eta, int n )
{
	precondition( eta > 0.F && eta < 1.F, "Invalid eta {0} for pyramid, must be between 0 and 1", eta );

	std::vector<plane> ret;
	int curLev = 1;
	ret.push_back( in );
	while ( n == 0 || curLev < n )
	{
		float curS = powf( eta, curLev );
		float curWf = curS * static_cast<float>( in.width() );
		float curHf = curS * static_cast<float>( in.height() );
		int curW = static_cast<int>( ceilf( curWf ) );
		int curH = static_cast<int>( ceilf( curHf ) );

		if ( curW < 2 || curH < 2 )
		{
			std::cout << "Terminating pyramid at level " << curLev << std::endl;
			break;
		}

		std::cout << "adding level " << curLev << " at " << curW << "x" << curH << std::endl;
		if ( filter == "bilinear" )
			ret.push_back( resize_bilinear( ret.back(), curW, curH ) );
		else if ( filter == "bicubic" )
			ret.push_back( resize_bicubic( ret.back(), curW, curH ) );
		else if ( filter == "point" || filter == "dirac" )
			ret.push_back( resize_point( ret.back(), curW, curH ) );
		else
			throw_not_yet();

		++curLev;
	}

	return ret;
}

////////////////////////////////////////

std::vector<image_buf>
make_pyramid( const image_buf &in, const std::string &filter, float eta, int n )
{
	precondition( eta > 0.F && eta < 1.F, "Invalid eta {0} for pyramid, must be between 0 and 1", eta );

	std::vector<image_buf> ret;
	int curLev = 1;
	ret.push_back( in );
	while ( n == 0 || curLev < n )
	{
		float curS = powf( eta, curLev );
		float curWf = curS * static_cast<float>( in.width() );
		float curHf = curS * static_cast<float>( in.height() );
		int curW = static_cast<int>( ceilf( curWf ) );
		int curH = static_cast<int>( ceilf( curHf ) );

		if ( curW < 2 || curH < 2 )
		{
			std::cout << "Terminating pyramid at level " << curLev << std::endl;
			break;
		}

		std::cout << "adding level " << curLev << " at " << curW << "x" << curH << std::endl;
		if ( filter == "bilinear" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_bilinear( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else if ( filter == "bicubic" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_bicubic( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else if ( filter == "point" || filter == "dirac" )
		{
			image_buf tmp = ret.back();
			for ( size_t p = 0; p != tmp.size(); ++p )
				tmp[p] = resize_point( tmp[p], curW, curH );
			ret.emplace_back( std::move( tmp ) );
		}
		else
		{
			throw_not_yet();
		}
		++curLev;
	}

	return ret;
}

////////////////////////////////////////

void
add_resize( engine::registry &r )
{
	using namespace engine;
	r.add( op( "p.resize_vert_point", base::choose_runtime( doResizeVertPoint ), n_scanline_plane_adapter<false, decltype(doResizeVertPoint)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_point", base::choose_runtime( doResizeHorizPoint ), scanline_plane_adapter<true, decltype(doResizeHorizPoint)>(), dispatch_scan_processing, op::one_to_one ) );

	r.add( op( "p.resize_vert_bilinear", base::choose_runtime( doResizeVertBilinear ), n_scanline_plane_adapter<false, decltype(doResizeVertBilinear)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_bilinear", base::choose_runtime( doResizeHorizBilinear ), scanline_plane_adapter<true, decltype(doResizeHorizBilinear)>(), dispatch_scan_processing, op::one_to_one ) );

	r.add( op( "p.resize_vert_bicubic", base::choose_runtime( doResizeVertBicubic ), n_scanline_plane_adapter<false, decltype(doResizeVertBicubic)>(), dispatch_scan_processing, op::n_to_one ) );
	r.add( op( "p.resize_horiz_bicubic", base::choose_runtime( doResizeHorizBicubic ), scanline_plane_adapter<true, decltype(doResizeHorizBicubic)>(), dispatch_scan_processing, op::one_to_one ) );

//	r.add( op( "p.resize_vert_generic", base::choose_runtime( doResizeVertGeneric ), n_scanline_plane_adapter<false, decltype(doResizeVertGeneric)>(), dispatch_scan_processing, op::n_to_one ) );
//	r.add( op( "p.resize_horiz_generic", base::choose_runtime( doResizeHorizGeneric ), scanline_plane_adapter<true, decltype(doResizeHorizGeneric)>(), dispatch_scan_processing, op::one_to_one ) );
}

////////////////////////////////////////

} // image

<|endoftext|>


<commit_before>/**
*  Copyright (C) 2018 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program 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 Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <OdaCommon.h>
#include <OdString.h>

#include <toString.h>
#include <DgLevelTableRecord.h>

#include "geometry_dumper.h"
#include "../../../../core/model/bson/repo_bson_factory.h"
using namespace repo::manipulator::modelconvertor::odaHelper;

void GeometryDumper::triangleOut(const OdInt32* p3Vertices, const OdGeVector3d* pNormal)
{
	const OdGePoint3d*  pVertexDataList = vertexDataList();
	const OdGeVector3d* pNormals = NULL;

	if ((pVertexDataList + p3Vertices[0]) != (pVertexDataList + p3Vertices[1]) &&
		(pVertexDataList + p3Vertices[0]) != (pVertexDataList + p3Vertices[2]) &&
		(pVertexDataList + p3Vertices[1]) != (pVertexDataList + p3Vertices[2]))
	{
		std::vector<repo::lib::RepoVector3D64> vertices;
		for (int i = 0; i < 3; ++i)
		{
			vertices.push_back({ pVertexDataList[p3Vertices[i]].x , pVertexDataList[p3Vertices[i]].y, pVertexDataList[p3Vertices[i]].z });
		}
		collector->addFace(vertices);
	}
}

double GeometryDumper::deviation(
	const OdGiDeviationType deviationType,
	const OdGePoint3d& pointOnCurve) const {
	return 0;
}

VectoriseDevice* GeometryDumper::device()
{
	return static_cast<VectoriseDevice*>(OdGsBaseVectorizeView::device());
}

bool GeometryDumper::doDraw(OdUInt32 i, const OdGiDrawable* pDrawable)
{
	OdDgElementPtr pElm = OdDgElement::cast(pDrawable);

	OdString sClassName = toString(pElm->isA());
	OdString sHandle = pElm->isDBRO() ? toString(pElm->elementId().getHandle()) : toString(OD_T("non-DbResident"));

	std::stringstream ss;
	ss << sHandle;
	collector->setNextMeshName(ss.str());

	OdGiSubEntityTraitsData traits = effectiveTraits();
	OdDgElementId idLevel = traits.layer();
	if (!idLevel.isNull())
	{
		OdDgLevelTableRecordPtr pLevel = idLevel.openObject(OdDg::kForRead);
		OdUInt32 iLevelEntry = pLevel->getEntryId();

		std::stringstream ss;
		ss << pLevel->getName();
		auto layerName = ss.str();
		repoInfo << layerName;
		collector->setLayer(layerName);
	}
	return OdGsBaseMaterialView::doDraw(i, pDrawable);
}

OdCmEntityColor GeometryDumper::fixByACI(const ODCOLORREF *ids, const OdCmEntityColor &color)
{
	if (color.isByACI() || color.isByDgnIndex())
	{
		return OdCmEntityColor(ODGETRED(ids[color.colorIndex()]), ODGETGREEN(ids[color.colorIndex()]), ODGETBLUE(ids[color.colorIndex()]));
	}
	else if (!color.isByColor())
	{
		return OdCmEntityColor(0, 0, 0);
	}
	return color;
}

OdGiMaterialItemPtr GeometryDumper::fillMaterialCache(
	OdGiMaterialItemPtr prevCache,
	OdDbStub* materialId,
	const OdGiMaterialTraitsData & materialData
) {

	auto id = (OdUInt64)(OdIntPtr)materialId;

	OdGiMaterialColor diffuseColor; OdGiMaterialMap diffuseMap;
	OdGiMaterialColor ambientColor;
	OdGiMaterialColor specularColor; OdGiMaterialMap specularMap; double glossFactor;
	double opacityPercentage; OdGiMaterialMap opacityMap;
	double refrIndex; OdGiMaterialMap refrMap;

	materialData.diffuse(diffuseColor, diffuseMap);
	materialData.ambient(ambientColor);
	materialData.specular(specularColor, specularMap, glossFactor);
	materialData.opacity(opacityPercentage, opacityMap);
	materialData.refraction(refrIndex, refrMap);

	OdGiMaterialMap bumpMap;
	materialData.bump(bumpMap);

	ODCOLORREF colorDiffuse(0), colorAmbient(0), colorSpecular(0);
	if (diffuseColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorDiffuse = ODTOCOLORREF(diffuseColor.color());
	}
	else if (diffuseColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorDiffuse = OdCmEntityColor::lookUpRGB((OdUInt8)diffuseColor.color().colorIndex());
	}
	if (ambientColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorAmbient = ODTOCOLORREF(ambientColor.color());
	}
	else if (ambientColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorAmbient = OdCmEntityColor::lookUpRGB((OdUInt8)ambientColor.color().colorIndex());
	}
	if (specularColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorSpecular = ODTOCOLORREF(specularColor.color());
	}
	else if (specularColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorSpecular = OdCmEntityColor::lookUpRGB((OdUInt8)specularColor.color().colorIndex());
	}

	OdCmEntityColor color = fixByACI(this->device()->getPalette(), effectiveTraits().trueColor());
	repo_material_t material;
	// diffuse
	if (diffuseColor.method() == OdGiMaterialColor::kOverride)
		material.diffuse = { ODGETRED(colorDiffuse) / 255.0f, ODGETGREEN(colorDiffuse) / 255.0f, ODGETBLUE(colorDiffuse) / 255.0f, 1.0f };
	else
		material.diffuse = { color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f, 1.0f };
	/*
	TODO: texture support
	mData.bDiffuseChannelEnabled = (GETBIT(materialData.channelFlags(), OdGiMaterialTraits::kUseDiffuse)) ? true : false;
	if (mData.bDiffuseChannelEnabled && diffuseMap.source() == OdGiMaterialMap::kFile && !diffuseMap.sourceFileName().isEmpty())
	{
	mData.bDiffuseHasTexture = true;
	mData.sDiffuseFileSource = diffuseMap.sourceFileName();
	}*/

	// specular
	if (specularColor.method() == OdGiMaterialColor::kOverride)
		material.specular = { ODGETRED(colorSpecular) / 255.0f, ODGETGREEN(colorSpecular) / 255.0f, ODGETBLUE(colorSpecular) / 255.0f, 1.0f };
	else
		material.specular = { color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f, 1.0f };

	material.shininessStrength = 1 - glossFactor;
	material.shininess = materialData.reflectivity();

	// opacity
	material.opacity = opacityPercentage;

	// refraction
	/*mData.bRefractionChannelEnabled = (GETBIT(materialData.channelFlags(), OdGiMaterialTraits::kUseRefraction)) ? 1 : 0;
	mData.dRefractionIndex = materialData.reflectivity();*/

	// transclucence
	//mData.dTranslucence = materialData.translucence();

	collector->setCurrentMaterial(material);
	collector->stopMeshEntry();
	collector->startMeshEntry();

	return OdGiMaterialItemPtr();
}

void GeometryDumper::init(GeometryCollector *const geoCollector) {
	collector = geoCollector;
}

void GeometryDumper::beginViewVectorization()
{
	OdGsBaseMaterialView::beginViewVectorization();
	setEyeToOutputTransform(getEyeToWorldTransform());

	OdGiGeometrySimplifier::setDrawContext(OdGsBaseMaterialView::drawContext());
	output().setDestGeometry((OdGiGeometrySimplifier&)*this);
}

void GeometryDumper::endViewVectorization()
{
	collector->stopMeshEntry();
	OdGsBaseMaterialView::endViewVectorization();
}

void GeometryDumper::setMode(OdGsView::RenderMode mode)
{
	OdGsBaseVectorizeView::m_renderMode = kGouraudShaded;
	m_regenerationType = kOdGiRenderCommand;
	OdGiGeometrySimplifier::m_renderMode = OdGsBaseVectorizeView::m_renderMode;
}<commit_msg>ISSUE #271 remove log<commit_after>/**
*  Copyright (C) 2018 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program 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 Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <OdaCommon.h>
#include <OdString.h>

#include <toString.h>
#include <DgLevelTableRecord.h>

#include "geometry_dumper.h"
#include "../../../../core/model/bson/repo_bson_factory.h"
using namespace repo::manipulator::modelconvertor::odaHelper;

void GeometryDumper::triangleOut(const OdInt32* p3Vertices, const OdGeVector3d* pNormal)
{
	const OdGePoint3d*  pVertexDataList = vertexDataList();
	const OdGeVector3d* pNormals = NULL;

	if ((pVertexDataList + p3Vertices[0]) != (pVertexDataList + p3Vertices[1]) &&
		(pVertexDataList + p3Vertices[0]) != (pVertexDataList + p3Vertices[2]) &&
		(pVertexDataList + p3Vertices[1]) != (pVertexDataList + p3Vertices[2]))
	{
		std::vector<repo::lib::RepoVector3D64> vertices;
		for (int i = 0; i < 3; ++i)
		{
			vertices.push_back({ pVertexDataList[p3Vertices[i]].x , pVertexDataList[p3Vertices[i]].y, pVertexDataList[p3Vertices[i]].z });
		}
		collector->addFace(vertices);
	}
}

double GeometryDumper::deviation(
	const OdGiDeviationType deviationType,
	const OdGePoint3d& pointOnCurve) const {
	return 0;
}

VectoriseDevice* GeometryDumper::device()
{
	return static_cast<VectoriseDevice*>(OdGsBaseVectorizeView::device());
}

bool GeometryDumper::doDraw(OdUInt32 i, const OdGiDrawable* pDrawable)
{
	OdDgElementPtr pElm = OdDgElement::cast(pDrawable);

	OdString sClassName = toString(pElm->isA());
	OdString sHandle = pElm->isDBRO() ? toString(pElm->elementId().getHandle()) : toString(OD_T("non-DbResident"));

	std::stringstream ss;
	ss << sHandle;
	collector->setNextMeshName(ss.str());

	OdGiSubEntityTraitsData traits = effectiveTraits();
	OdDgElementId idLevel = traits.layer();
	if (!idLevel.isNull())
	{
		OdDgLevelTableRecordPtr pLevel = idLevel.openObject(OdDg::kForRead);
		OdUInt32 iLevelEntry = pLevel->getEntryId();

		std::stringstream ss;
		ss << pLevel->getName();
		auto layerName = ss.str();
		collector->setLayer(layerName);
	}
	return OdGsBaseMaterialView::doDraw(i, pDrawable);
}

OdCmEntityColor GeometryDumper::fixByACI(const ODCOLORREF *ids, const OdCmEntityColor &color)
{
	if (color.isByACI() || color.isByDgnIndex())
	{
		return OdCmEntityColor(ODGETRED(ids[color.colorIndex()]), ODGETGREEN(ids[color.colorIndex()]), ODGETBLUE(ids[color.colorIndex()]));
	}
	else if (!color.isByColor())
	{
		return OdCmEntityColor(0, 0, 0);
	}
	return color;
}

OdGiMaterialItemPtr GeometryDumper::fillMaterialCache(
	OdGiMaterialItemPtr prevCache,
	OdDbStub* materialId,
	const OdGiMaterialTraitsData & materialData
) {

	auto id = (OdUInt64)(OdIntPtr)materialId;

	OdGiMaterialColor diffuseColor; OdGiMaterialMap diffuseMap;
	OdGiMaterialColor ambientColor;
	OdGiMaterialColor specularColor; OdGiMaterialMap specularMap; double glossFactor;
	double opacityPercentage; OdGiMaterialMap opacityMap;
	double refrIndex; OdGiMaterialMap refrMap;

	materialData.diffuse(diffuseColor, diffuseMap);
	materialData.ambient(ambientColor);
	materialData.specular(specularColor, specularMap, glossFactor);
	materialData.opacity(opacityPercentage, opacityMap);
	materialData.refraction(refrIndex, refrMap);

	OdGiMaterialMap bumpMap;
	materialData.bump(bumpMap);

	ODCOLORREF colorDiffuse(0), colorAmbient(0), colorSpecular(0);
	if (diffuseColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorDiffuse = ODTOCOLORREF(diffuseColor.color());
	}
	else if (diffuseColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorDiffuse = OdCmEntityColor::lookUpRGB((OdUInt8)diffuseColor.color().colorIndex());
	}
	if (ambientColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorAmbient = ODTOCOLORREF(ambientColor.color());
	}
	else if (ambientColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorAmbient = OdCmEntityColor::lookUpRGB((OdUInt8)ambientColor.color().colorIndex());
	}
	if (specularColor.color().colorMethod() == OdCmEntityColor::kByColor)
	{
		colorSpecular = ODTOCOLORREF(specularColor.color());
	}
	else if (specularColor.color().colorMethod() == OdCmEntityColor::kByACI)
	{
		colorSpecular = OdCmEntityColor::lookUpRGB((OdUInt8)specularColor.color().colorIndex());
	}

	OdCmEntityColor color = fixByACI(this->device()->getPalette(), effectiveTraits().trueColor());
	repo_material_t material;
	// diffuse
	if (diffuseColor.method() == OdGiMaterialColor::kOverride)
		material.diffuse = { ODGETRED(colorDiffuse) / 255.0f, ODGETGREEN(colorDiffuse) / 255.0f, ODGETBLUE(colorDiffuse) / 255.0f, 1.0f };
	else
		material.diffuse = { color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f, 1.0f };
	/*
	TODO: texture support
	mData.bDiffuseChannelEnabled = (GETBIT(materialData.channelFlags(), OdGiMaterialTraits::kUseDiffuse)) ? true : false;
	if (mData.bDiffuseChannelEnabled && diffuseMap.source() == OdGiMaterialMap::kFile && !diffuseMap.sourceFileName().isEmpty())
	{
	mData.bDiffuseHasTexture = true;
	mData.sDiffuseFileSource = diffuseMap.sourceFileName();
	}*/

	// specular
	if (specularColor.method() == OdGiMaterialColor::kOverride)
		material.specular = { ODGETRED(colorSpecular) / 255.0f, ODGETGREEN(colorSpecular) / 255.0f, ODGETBLUE(colorSpecular) / 255.0f, 1.0f };
	else
		material.specular = { color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f, 1.0f };

	material.shininessStrength = 1 - glossFactor;
	material.shininess = materialData.reflectivity();

	// opacity
	material.opacity = opacityPercentage;

	// refraction
	/*mData.bRefractionChannelEnabled = (GETBIT(materialData.channelFlags(), OdGiMaterialTraits::kUseRefraction)) ? 1 : 0;
	mData.dRefractionIndex = materialData.reflectivity();*/

	// transclucence
	//mData.dTranslucence = materialData.translucence();

	collector->setCurrentMaterial(material);
	collector->stopMeshEntry();
	collector->startMeshEntry();

	return OdGiMaterialItemPtr();
}

void GeometryDumper::init(GeometryCollector *const geoCollector) {
	collector = geoCollector;
}

void GeometryDumper::beginViewVectorization()
{
	OdGsBaseMaterialView::beginViewVectorization();
	setEyeToOutputTransform(getEyeToWorldTransform());

	OdGiGeometrySimplifier::setDrawContext(OdGsBaseMaterialView::drawContext());
	output().setDestGeometry((OdGiGeometrySimplifier&)*this);
}

void GeometryDumper::endViewVectorization()
{
	collector->stopMeshEntry();
	OdGsBaseMaterialView::endViewVectorization();
}

void GeometryDumper::setMode(OdGsView::RenderMode mode)
{
	OdGsBaseVectorizeView::m_renderMode = kGouraudShaded;
	m_regenerationType = kOdGiRenderCommand;
	OdGiGeometrySimplifier::m_renderMode = OdGsBaseVectorizeView::m_renderMode;
}<|endoftext|>


<commit_before>#include "common/application_info.h"

#include "base/file_version_info.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"

namespace brightray {

std::string GetApplicationName() {
  auto info = make_scoped_ptr(FileVersionInfo::CreateFileVersionInfoForModule(GetModuleHandle(nullptr)));
  return UTF16ToUTF8(info->product_name());
}

std::string GetApplicationVersion() {
  auto info = make_scoped_ptr(FileVersionInfo::CreateFileVersionInfoForModule(GetModuleHandle(nullptr)));
  return UTF16ToUTF8(info->product_version());
}

}  // namespace brightray
<commit_msg>Fix cpplint errors in application_info_win.cc<commit_after>#include "common/application_info.h"

#include "base/file_version_info.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"

namespace brightray {

std::string GetApplicationName() {
  auto module = GetModuleHandle(nullptr);
  auto info = make_scoped_ptr(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return UTF16ToUTF8(info->product_name());
}

std::string GetApplicationVersion() {
  auto module = GetModuleHandle(nullptr);
  auto info = make_scoped_ptr(
      FileVersionInfo::CreateFileVersionInfoForModule(module));
  return UTF16ToUTF8(info->product_version());
}

}  // namespace brightray
<|endoftext|>


<commit_before>TEveRGBAPalette *g_zdc_palette = 0;

TEveGeoShape* zdc_make_shape(const Text_t* name, const Text_t* title_base,
			     Double_t signal,    const Text_t* path)
{
  if ( ! gGeoManager->cd(path))
  {
    Warning("zdc_make_shape", "Module name=%s, path='%s' not found.\n", name, path);
    return 0;
  }

  UChar_t rgb[3];
  g_zdc_palette->ColorFromValue(TMath::Nint(signal), rgb, kFALSE);

  TGeoShape *gs = (TGeoShape*) gGeoManager->GetCurrentVolume()->GetShape()->Clone();

  TEveGeoShape *s = new TEveGeoShape(name, Form("%s %s, E=%.3f", title_base, name, signal));
  s->SetPickable(kTRUE);
  s->SetMainColorRGB(rgb[0], rgb[1], rgb[2]);
  s->SetShape(gs);
  s->RefMainTrans().SetFrom(*gGeoManager->GetCurrentMatrix());

  // Scale z-dictance by 0.1
  Double_t* t = s->RefMainTrans().ArrT();
  t[2] *= 0.1;

  return s;
}

// ???? There are 5 towers in ESD, 4 in geom.
// Not sure about assignment A/C <-> 1/2

void esd_zdc()
{
  AliEveEventManager::AssertGeometry();

  AliESDZDC *esd = AliEveEventManager::AssertESD()->GetESDZDC();

  if (g_zdc_palette == 0)
  {
    // Map values from 0, 50 on a spectrum palette.
    g_zdc_palette = new TEveRGBAPalette(0, 50, kTRUE, kFALSE);
    g_zdc_palette->IncRefCount();
    gStyle->SetPalette(1, 0);
    g_zdc_palette->SetupColorArray();
  }

  TEveElementList* l = new TEveElementList("ZDC Data", "");
  gEve->AddElement(l);

  TEveElementList *c  = 0;
  TEveGeoShape    *s  = 0;
  Double_t        *te = 0;
  Text_t          *tb = 0;

  // ZNC geometry ------------------------------------
  tb = "ZNC";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZN1TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_1/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_1/ZN1_2"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_2/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_2/ZN1_2"));

  // ZNA geometry
  tb = "ZNA";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZN2TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_1/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_1/ZN1_2"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_2/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_2/ZN1_2"));

  // ZPC geometry ------------------------------------
  tb = "ZPC";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZP1TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_1/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_2/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_3/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_4/ZP1_1"));

  // ZPA geometry
  tb = "ZPA";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZP2TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_1/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_2/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_3/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_4/ZP1_1"));

  // End - refresh screen
  gEve->Redraw3D();
}
<commit_msg>Add display of ZDC tower centroid.<commit_after>TEveRGBAPalette *g_zdc_palette = 0;
Float_t          g_zdc_scale   = 0.1;
Float_t          g_zdc_dist    = 11695;
Float_t          g_zdc_cross   = 20;

TEveGeoShape* zdc_make_shape(const Text_t* name, const Text_t* title_base,
			     Double_t signal,    const Text_t* path)
{
  if ( ! gGeoManager->cd(path))
  {
    Warning("zdc_make_shape", "Module name=%s, path='%s' not found.\n", name, path);
    return 0;
  }

  UChar_t rgb[3];
  g_zdc_palette->ColorFromValue(TMath::Nint(signal), rgb, kFALSE);

  TGeoShape *gs = (TGeoShape*) gGeoManager->GetCurrentVolume()->GetShape()->Clone();

  TEveGeoShape *s = new TEveGeoShape(name, Form("%s %s, E=%.3f", title_base, name, signal));
  s->SetPickable(kTRUE);
  s->SetMainColorRGB(rgb[0], rgb[1], rgb[2]);
  s->SetShape(gs);
  s->RefMainTrans().SetFrom(*gGeoManager->GetCurrentMatrix());

  // Scale z-dictance by 0.1
  Double_t* t = s->RefMainTrans().ArrT();
  t[2] *= g_zdc_scale;

  return s;
}

TEveStraightLineSet*
zdc_make_cross(const Text_t* name, const Text_t* title_base,
               Float_t x, Float_t y, Float_t z, Float_t dx, Float_t dy, Float_t dz)
{
  TEveStraightLineSet* ls = new TEveStraightLineSet(name, Form("%s, x=%.3f, y=%.3f", title_base, x, y));
  ls->SetMainColor(kYellow);
  ls->SetLineWidth(2);
  ls->RefMainTrans().SetPos(x, y, z);
  ls->AddLine(dx, 0,  0, -dx, 0,  0);
  ls->AddLine(0,  dy, 0,  0, -dy, 0);
  ls->AddLine(0,  0,  dz, 0,  0, -dz);

  return ls;
}

// ???? There are 5 towers in ESD, 4 in geom.
// Not sure about assignment A/C <-> 1/2

void esd_zdc()
{
  AliEveEventManager::AssertGeometry();

  AliESDZDC *esd = AliEveEventManager::AssertESD()->GetESDZDC();

  if (g_zdc_palette == 0)
  {
    // Map values from 0, 50 on a spectrum palette.
    g_zdc_palette = new TEveRGBAPalette(0, 50, kTRUE, kFALSE);
    g_zdc_palette->IncRefCount();
    gStyle->SetPalette(1, 0);
    g_zdc_palette->SetupColorArray();
  }

  TEveElementList* l = new TEveElementList("ZDC Data", "");
  gEve->AddElement(l);

  TEveElementList *c  = 0;
  TEveGeoShape    *s  = 0;
  Double_t        *te = 0;
  Text_t          *tb = 0;

  // ZNC geometry ------------------------------------
  tb = "ZNC";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZN1TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_1/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_1/ZN1_2"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_2/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCC_1/ZNEU_1/ZNTX_2/ZN1_2"));

  // ZNA geometry
  tb = "ZNA";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZN2TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_1/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_1/ZN1_2"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_2/ZN1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCA_1/ZNEU_2/ZNTX_2/ZN1_2"));

  // ZPC geometry ------------------------------------
  tb = "ZPC";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZP1TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_1/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_2/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_3/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCC_1/ZPRO_1/ZPTX_4/ZP1_1"));

  // ZPA geometry
  tb = "ZPA";
  c = new TEveElementList(tb);
  l->AddElement(c);

  te = esd->GetZP2TowerEnergy();

  c->AddElement(zdc_make_shape("Tower 1", tb, te[1],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_1/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 2", tb, te[2],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_2/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 3", tb, te[3],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_3/ZP1_1"));

  c->AddElement(zdc_make_shape("Tower 4", tb, te[4],
			       "ALIC_1/ZDCA_1/ZPRO_2/ZPTX_4/ZP1_1"));

  // Centroids
  TEveStraightLineSet *ls = 0;

  Double32_t *cNA = esd->GetZNACentroid();
  ls = zdc_make_cross("ZNA Centroid", "ZNA",
                      cNA[0], cNA[1],  g_zdc_dist * g_zdc_scale,
                      g_zdc_cross, g_zdc_cross, g_zdc_cross);
  l->AddElement(ls);

  Double32_t *cNC = esd->GetZNCCentroid();
  ls = zdc_make_cross("ZNA Centroid", "ZNA",
                      cNC[0], cNC[1], -g_zdc_dist * g_zdc_scale,
                      g_zdc_cross, g_zdc_cross, g_zdc_cross);
  l->AddElement(ls);

  // End - refresh screen
  gEve->Redraw3D();
}
<|endoftext|>


<commit_before>
#include <config.h>

#if defined(HAVE_CLOCK_GETTIME)

#include <time.h>

unsigned GetRunningMicroSecs()
{
    struct timespec	now;

    clock_gettime( CLOCK_MONOTONIC, &now );

    unsigned usecs = ((unsigned)now.tv_nsec)/1000 + ((unsigned)now.tv_sec) * 1000000;
//    unsigned msecs = (now.tv_nsec / (1000*1000)) + now.tv_sec * 1000;

    return usecs;
}

#elif defined(HAVE_GETTIMEOFDAY_FUNC)

#include <sys/time.h>
unsigned GetRunningMicroSecs()
{
    timeval tv;

    gettimeofday( &tv, 0 );

    return (tv.tv_sec * 1000000) + tv.tv_usec;
}

#elif defined(_WIN32)

#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <assert.h>

unsigned GetRunningMicroSecs()
{
    LARGE_INTEGER   curtime;

    static unsigned timerFreq;              // timer frequency

    if( !timerFreq )
    {
        QueryPerformanceFrequency( &curtime );

        timerFreq = curtime.QuadPart / 1000000;     // i.e., ticks per usec

        assert( timerFreq );
    }

    QueryPerformanceCounter( &curtime );

    return ( curtime.LowPart / timerFreq );
}

#endif

<commit_msg>fix windows version of GetRunningMicroSecs()<commit_after>
#include <config.h>

#if defined(HAVE_CLOCK_GETTIME)

#include <time.h>

unsigned GetRunningMicroSecs()
{
    struct timespec	now;

    clock_gettime( CLOCK_MONOTONIC, &now );

    unsigned usecs = ((unsigned)now.tv_nsec)/1000 + ((unsigned)now.tv_sec) * 1000000;
//    unsigned msecs = (now.tv_nsec / (1000*1000)) + now.tv_sec * 1000;

    return usecs;
}

#elif defined(HAVE_GETTIMEOFDAY_FUNC)

#include <sys/time.h>
unsigned GetRunningMicroSecs()
{
    timeval tv;

    gettimeofday( &tv, 0 );

    return (tv.tv_sec * 1000000) + tv.tv_usec;
}

#elif defined(_WIN32)

#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <assert.h>

unsigned GetRunningMicroSecs()
{
    FILETIME    now;

    GetSystemTimeAsFileTime( &now );

    typedef unsigned long long UINT64;

    UINT64 t = (UINT64(now.dwHighDateTime) << 32) + now.dwLowDateTime;

    t /= 10;

    return unsigned( t );
}

#if 0
// test program
#include <stdio.h>
int main( int argc, char** argv )
{
    unsigned then = GetRunningMicroSecs();

    Sleep( 2000 );      // Windows Sleep( msecs )

    printf( "delta: %u\n", GetRunningMicroSecs() - then );

    return 0;
}
#endif

#endif

<|endoftext|>


<commit_before>//
// Urho3D Engine
// Copyright (c) 2008-2012 Lasse rni
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Context.h"
#include "DropDownList.h"
#include "ListView.h"
#include "UIEvents.h"
#include "Window.h"

#include "DebugNew.h"

namespace Urho3D
{

OBJECTTYPESTATIC(DropDownList);

DropDownList::DropDownList(Context* context) :
    Menu(context),
    resizePopup_(false)
{
    Window* window = new Window(context_);
    window->SetInternal(true);
    SetPopup(window);

    // Hack: parent the popup until first shown to allow loading style from XML
    AddChild(window);
    window->SetVisible(false);

    listView_ = new ListView(context_);
    listView_->SetInternal(true);
    listView_->SetScrollBarsVisible(false, false);
    listView_->SetFocusMode(FM_NOTFOCUSABLE);
    popup_->SetLayout(LM_VERTICAL);
    popup_->AddChild(listView_);
    placeholder_ = CreateChild<UIElement>();
    placeholder_->SetInternal(true);

    SubscribeToEvent(listView_, E_ITEMSELECTED, HANDLER(DropDownList, HandleItemSelected));
}

DropDownList::~DropDownList()
{
}

void DropDownList::RegisterObject(Context* context)
{
    context->RegisterFactory<DropDownList>();

    COPY_BASE_ATTRIBUTES(DropDownList, Menu);
    ACCESSOR_ATTRIBUTE(DropDownList, VAR_BOOL, "Resize Popup", GetResizePopup, SetResizePopup, bool, false, AM_FILE);
}

bool DropDownList::SaveXML(XMLElement& dest)
{
    // Hack: parent the popup and the list items during serialization
    bool popupShown = popup_ && popup_->IsVisible();
    if (popup_)
    {
        InsertChild(0, popup_);
        popup_->SetVisible(false);
    }

    while (listView_->GetNumItems())
        placeholder_->AddChild(listView_->GetItem(0));

    bool success = UIElement::SaveXML(dest);

    while (placeholder_->GetNumChildren())
        listView_->AddItem(placeholder_->GetChild(0));

    ShowPopup(popupShown);

    return success;
}

void DropDownList::ApplyAttributes()
{
    // Hack: if the placeholder has any child elements defined, move them to the list
    while (placeholder_->GetNumChildren())
        AddItem(placeholder_->GetChild(0));
}

void DropDownList::GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, const IntRect& currentScissor)
{
    Button::GetBatches(batches, quads, currentScissor);

    if (!placeholder_->IsVisible())
        return;

    UIElement* selectedItem = GetSelectedItem();
    if (selectedItem)
    {
        // Can not easily copy the selected item. However, it can be re-rendered on the placeholder's position
        const IntVector2& targetPos = placeholder_->GetScreenPosition();
        const IntVector2& originalPos = selectedItem->GetScreenPosition();
        IntVector2 offset = targetPos - originalPos;

        // GetBatches() usually resets the hover flag. Therefore get its value and then reset it for the real rendering
        bool hover = selectedItem->IsHovering();
        selectedItem->SetHovering(false);
        selectedItem->GetBatchesWithOffset(offset, batches, quads, currentScissor);
        selectedItem->SetHovering(hover);
    }
}

void DropDownList::OnShowPopup()
{
    // Resize the popup to match the size of the list content, and optionally match the button width
    UIElement* content = listView_->GetContentElement();
    content->UpdateLayout();
    const IntVector2& contentSize = content->GetSize();
    const IntRect& border = popup_->GetLayoutBorder();
    popup_->SetSize(resizePopup_ ? GetWidth() : contentSize.x_ + border.left_ + border.right_, contentSize.y_ + border.top_ +
        border.bottom_);
    listView_->SetViewPosition(IntVector2::ZERO);

    // Check if popup fits below the button. If not, show above instead
    bool showAbove = false;
    UIElement* root = GetRoot();
    if (root)
    {
        const IntVector2& screenPos = GetScreenPosition();
        if (screenPos.y_ + GetHeight() + popup_->GetHeight() > root->GetHeight() && screenPos.y_ - popup_->GetHeight() >= 0)
            showAbove = true;
    }
    if (!showAbove)
        SetPopupOffset(0, GetHeight());
    else
        SetPopupOffset(0, -popup_->GetHeight());
}

void DropDownList::AddItem(UIElement* item)
{
    InsertItem(listView_->GetNumItems(), item);
}

void DropDownList::InsertItem(unsigned index, UIElement* item)
{
    listView_->InsertItem(index, item);

    // If there was no selection, set to the first
    if (listView_->GetSelection() == M_MAX_UNSIGNED)
        listView_->SetSelection(0);
}

void DropDownList::RemoveItem(UIElement* item)
{
    listView_->RemoveItem(item);
}

void DropDownList::RemoveItem(unsigned index)
{
    listView_->RemoveItem(index);
}

void DropDownList::RemoveAllItems()
{
    listView_->RemoveAllItems();
}

void DropDownList::SetSelection(unsigned index)
{
    listView_->SetSelection(index);
}

void DropDownList::SetResizePopup(bool enable)
{
    resizePopup_ = enable;
}

unsigned DropDownList::GetNumItems() const
{
    return listView_->GetNumItems();
}

UIElement* DropDownList::GetItem(unsigned index) const
{
    return listView_->GetItem(index);
}

PODVector<UIElement*> DropDownList::GetItems() const
{
    PODVector<UIElement*> items;
    listView_->GetContentElement()->GetChildren(items);
    return items;
}

unsigned DropDownList::GetSelection() const
{
    return listView_->GetSelection();
}

UIElement* DropDownList::GetSelectedItem() const
{
    return listView_->GetSelectedItem();
}

void DropDownList::HandleItemSelected(StringHash eventType, VariantMap& eventData)
{
    // Resize the selection placeholder to match the selected item
    UIElement* selectedItem = GetSelectedItem();
    if (selectedItem)
        placeholder_->SetSize(selectedItem->GetSize());

    // Close the popup as the selection was made
    if (GetShowPopup())
        ShowPopup(false);

    // Send the event forward
    using namespace ItemSelected;

    VariantMap newEventData;
    newEventData[P_ELEMENT] = (void*)this;
    newEventData[P_SELECTION] = GetSelection();
    SendEvent(E_ITEMSELECTED, newEventData);
}

}
<commit_msg>Removed unnecessary line of code from DropDownList.<commit_after>//
// Urho3D Engine
// Copyright (c) 2008-2012 Lasse rni
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Context.h"
#include "DropDownList.h"
#include "ListView.h"
#include "UIEvents.h"
#include "Window.h"

#include "DebugNew.h"

namespace Urho3D
{

OBJECTTYPESTATIC(DropDownList);

DropDownList::DropDownList(Context* context) :
    Menu(context),
    resizePopup_(false)
{
    Window* window = new Window(context_);
    window->SetInternal(true);
    SetPopup(window);

    // Hack: parent the popup until first shown to allow loading style from XML
    AddChild(window);
    window->SetVisible(false);

    listView_ = new ListView(context_);
    listView_->SetInternal(true);
    listView_->SetScrollBarsVisible(false, false);
    listView_->SetFocusMode(FM_NOTFOCUSABLE);
    popup_->SetLayout(LM_VERTICAL);
    popup_->AddChild(listView_);
    placeholder_ = CreateChild<UIElement>();
    placeholder_->SetInternal(true);

    SubscribeToEvent(listView_, E_ITEMSELECTED, HANDLER(DropDownList, HandleItemSelected));
}

DropDownList::~DropDownList()
{
}

void DropDownList::RegisterObject(Context* context)
{
    context->RegisterFactory<DropDownList>();

    COPY_BASE_ATTRIBUTES(DropDownList, Menu);
    ACCESSOR_ATTRIBUTE(DropDownList, VAR_BOOL, "Resize Popup", GetResizePopup, SetResizePopup, bool, false, AM_FILE);
}

bool DropDownList::SaveXML(XMLElement& dest)
{
    // Hack: parent the popup and the list items during serialization
    bool popupShown = popup_ && popup_->IsVisible();
    if (popup_)
    {
        InsertChild(0, popup_);
        popup_->SetVisible(false);
    }

    while (listView_->GetNumItems())
        placeholder_->AddChild(listView_->GetItem(0));

    bool success = UIElement::SaveXML(dest);

    while (placeholder_->GetNumChildren())
        listView_->AddItem(placeholder_->GetChild(0));

    ShowPopup(popupShown);

    return success;
}

void DropDownList::ApplyAttributes()
{
    // Hack: if the placeholder has any child elements defined, move them to the list
    while (placeholder_->GetNumChildren())
        AddItem(placeholder_->GetChild(0));
}

void DropDownList::GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, const IntRect& currentScissor)
{
    Button::GetBatches(batches, quads, currentScissor);

    if (!placeholder_->IsVisible())
        return;

    UIElement* selectedItem = GetSelectedItem();
    if (selectedItem)
    {
        // Can not easily copy the selected item. However, it can be re-rendered on the placeholder's position
        const IntVector2& targetPos = placeholder_->GetScreenPosition();
        const IntVector2& originalPos = selectedItem->GetScreenPosition();
        IntVector2 offset = targetPos - originalPos;

        // GetBatches() usually resets the hover flag. Therefore get its value and then reset it for the real rendering
        bool hover = selectedItem->IsHovering();
        selectedItem->SetHovering(false);
        selectedItem->GetBatchesWithOffset(offset, batches, quads, currentScissor);
        selectedItem->SetHovering(hover);
    }
}

void DropDownList::OnShowPopup()
{
    // Resize the popup to match the size of the list content, and optionally match the button width
    UIElement* content = listView_->GetContentElement();
    content->UpdateLayout();
    const IntVector2& contentSize = content->GetSize();
    const IntRect& border = popup_->GetLayoutBorder();
    popup_->SetSize(resizePopup_ ? GetWidth() : contentSize.x_ + border.left_ + border.right_, contentSize.y_ + border.top_ +
        border.bottom_);

    // Check if popup fits below the button. If not, show above instead
    bool showAbove = false;
    UIElement* root = GetRoot();
    if (root)
    {
        const IntVector2& screenPos = GetScreenPosition();
        if (screenPos.y_ + GetHeight() + popup_->GetHeight() > root->GetHeight() && screenPos.y_ - popup_->GetHeight() >= 0)
            showAbove = true;
    }
    if (!showAbove)
        SetPopupOffset(0, GetHeight());
    else
        SetPopupOffset(0, -popup_->GetHeight());
}

void DropDownList::AddItem(UIElement* item)
{
    InsertItem(listView_->GetNumItems(), item);
}

void DropDownList::InsertItem(unsigned index, UIElement* item)
{
    listView_->InsertItem(index, item);

    // If there was no selection, set to the first
    if (listView_->GetSelection() == M_MAX_UNSIGNED)
        listView_->SetSelection(0);
}

void DropDownList::RemoveItem(UIElement* item)
{
    listView_->RemoveItem(item);
}

void DropDownList::RemoveItem(unsigned index)
{
    listView_->RemoveItem(index);
}

void DropDownList::RemoveAllItems()
{
    listView_->RemoveAllItems();
}

void DropDownList::SetSelection(unsigned index)
{
    listView_->SetSelection(index);
}

void DropDownList::SetResizePopup(bool enable)
{
    resizePopup_ = enable;
}

unsigned DropDownList::GetNumItems() const
{
    return listView_->GetNumItems();
}

UIElement* DropDownList::GetItem(unsigned index) const
{
    return listView_->GetItem(index);
}

PODVector<UIElement*> DropDownList::GetItems() const
{
    PODVector<UIElement*> items;
    listView_->GetContentElement()->GetChildren(items);
    return items;
}

unsigned DropDownList::GetSelection() const
{
    return listView_->GetSelection();
}

UIElement* DropDownList::GetSelectedItem() const
{
    return listView_->GetSelectedItem();
}

void DropDownList::HandleItemSelected(StringHash eventType, VariantMap& eventData)
{
    // Resize the selection placeholder to match the selected item
    UIElement* selectedItem = GetSelectedItem();
    if (selectedItem)
        placeholder_->SetSize(selectedItem->GetSize());

    // Close the popup as the selection was made
    if (GetShowPopup())
        ShowPopup(false);

    // Send the event forward
    using namespace ItemSelected;

    VariantMap newEventData;
    newEventData[P_ELEMENT] = (void*)this;
    newEventData[P_SELECTION] = GetSelection();
    SendEvent(E_ITEMSELECTED, newEventData);
}

}
<|endoftext|>


<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
*/

#include "vw_cbutil.h"
#include "cb_algs.h"

namespace VW
{
  float VowpalWabbitContextualBanditUtil::GetUnbiasedCost(uint32_t actionObservered, uint32_t actionTaken, float cost, float probability)
  {
    CB::cb_class observation = { cost, actionObservered, probability };

    return get_unbiased_cost(&observation, actionTaken);
  }
}
<commit_msg>vw_cbutil error fix attempt<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
*/

#include "vw_cbutil.h"
#include "cb_algs.h"

namespace VW
{
  float VowpalWabbitContextualBanditUtil::GetUnbiasedCost(uint32_t actionObservered, uint32_t actionTaken, float cost, float probability)
  {
    CB::cb_class observation = { cost, actionObservered, probability };

    return CB_ALGS::get_unbiased_cost(&observation, actionTaken);
  }
}
<|endoftext|>


<commit_before>
        #include <Python.h>
        #include <pybind11/pybind11.h>

        namespace py = pybind11;

extern "C" PyObject* function_with_cpp_args(PyObject* self, PyObject* args, PyObject* kwargs)
{
    static char* _keywords_[] = {"a","b",nullptr};
    py::object a;
    py::object b;

    if(!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", _keywords_, &(a.ptr()), &(b.ptr())))
        return nullptr;

    a.inc_ref();
    b.inc_ref();

    {

    py::tuple args = py::make_tuple(a, b);
    args.inc_ref();
    return args.ptr();

    }
}

static PyMethodDef module_functions_def[] = {
    {"function_with_cpp_args", reinterpret_cast<PyCFunction>(function_with_cpp_args), METH_VARARGS | METH_KEYWORDS, nullptr},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef inline_module = {
    PyModuleDef_HEAD_INIT,
    "compiled_function_with_cpp_args",
    nullptr,
    -1,
    module_functions_def
};

PyMODINIT_FUNC PyInit_compiled_function_with_cpp_args(void)
{
    PyObject* module = PyModule_Create(&inline_module);
    if (module == nullptr)
        return nullptr;
    return module;
}
<commit_msg>Remove temporary cpp code<commit_after><|endoftext|>