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

#include "content/common/unix_domain_socket_posix.h"

#include <errno.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/socket.h>

#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/pickle.h"

// static
bool UnixDomainSocket::SendMsg(int fd,
                               const void* buf,
                               size_t length,
                               const std::vector<int>& fds) {
  struct msghdr msg;
  memset(&msg, 0, sizeof(msg));
  struct iovec iov = {const_cast<void*>(buf), length};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char* control_buffer = NULL;
  if (fds.size()) {
    const unsigned control_len = CMSG_SPACE(sizeof(int) * fds.size());
    control_buffer = new char[control_len];

    struct cmsghdr *cmsg;
    msg.msg_control = control_buffer;
    msg.msg_controllen = control_len;
    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
    memcpy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size());
    msg.msg_controllen = cmsg->cmsg_len;
  }

  const ssize_t r = HANDLE_EINTR(sendmsg(fd, &msg, 0));
  const bool ret = static_cast<ssize_t>(length) == r;
  delete[] control_buffer;
  return ret;
}

// static
ssize_t UnixDomainSocket::RecvMsg(int fd,
                                  void* buf,
                                  size_t length,
                                  std::vector<int>* fds) {
  static const unsigned kMaxDescriptors = 16;

  fds->clear();

  struct msghdr msg;
  memset(&msg, 0, sizeof(msg));
  struct iovec iov = {buf, length};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char control_buffer[CMSG_SPACE(sizeof(int) * kMaxDescriptors)];
  msg.msg_control = control_buffer;
  msg.msg_controllen = sizeof(control_buffer);

  const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, 0));
  if (r == -1)
    return -1;

  int* wire_fds = NULL;
  unsigned wire_fds_len = 0;

  if (msg.msg_controllen > 0) {
    struct cmsghdr* cmsg;
    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
      if (cmsg->cmsg_level == SOL_SOCKET &&
          cmsg->cmsg_type == SCM_RIGHTS) {
        const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
        DCHECK(payload_len % sizeof(int) == 0);
        wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
        wire_fds_len = payload_len / sizeof(int);
        break;
      }
    }
  }

  if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
    for (unsigned i = 0; i < wire_fds_len; ++i)
      close(wire_fds[i]);
    errno = EMSGSIZE;
    return -1;
  }

  fds->resize(wire_fds_len);
  memcpy(&(*fds)[0], wire_fds, sizeof(int) * wire_fds_len);

  return r;
}

// static
ssize_t UnixDomainSocket::SendRecvMsg(int fd,
                                      uint8_t* reply,
                                      unsigned max_reply_len,
                                      int* result_fd,
                                      const Pickle& request) {
  int fds[2];

  // This socketpair is only used for the IPC and is cleaned up before
  // returning.
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1)
      return false;

  std::vector<int> fd_vector;
  fd_vector.push_back(fds[1]);
  if (!SendMsg(fd, request.data(), request.size(), fd_vector)) {
    close(fds[0]);
    close(fds[1]);
    return -1;
  }
  close(fds[1]);

  fd_vector.clear();
  const ssize_t reply_len = RecvMsg(fds[0], reply, max_reply_len, &fd_vector);
  close(fds[0]);
  if (reply_len == -1)
    return -1;

  if ((!fd_vector.empty() && result_fd == NULL) || fd_vector.size() > 1) {
    for (std::vector<int>::const_iterator
         i = fd_vector.begin(); i != fd_vector.end(); ++i) {
      close(*i);
    }

    NOTREACHED();

    return -1;
  }

  if (result_fd)
    *result_fd = fd_vector.empty() ? -1 : fd_vector[0];

  return reply_len;
}

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

#include "content/common/unix_domain_socket_posix.h"

#include <errno.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/socket.h>

#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/pickle.h"
#include "base/stl_util-inl.h"

// static
bool UnixDomainSocket::SendMsg(int fd,
                               const void* buf,
                               size_t length,
                               const std::vector<int>& fds) {
  struct msghdr msg;
  memset(&msg, 0, sizeof(msg));
  struct iovec iov = {const_cast<void*>(buf), length};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char* control_buffer = NULL;
  if (fds.size()) {
    const unsigned control_len = CMSG_SPACE(sizeof(int) * fds.size());
    control_buffer = new char[control_len];

    struct cmsghdr *cmsg;
    msg.msg_control = control_buffer;
    msg.msg_controllen = control_len;
    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
    memcpy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size());
    msg.msg_controllen = cmsg->cmsg_len;
  }

  const ssize_t r = HANDLE_EINTR(sendmsg(fd, &msg, 0));
  const bool ret = static_cast<ssize_t>(length) == r;
  delete[] control_buffer;
  return ret;
}

// static
ssize_t UnixDomainSocket::RecvMsg(int fd,
                                  void* buf,
                                  size_t length,
                                  std::vector<int>* fds) {
  static const unsigned kMaxDescriptors = 16;

  fds->clear();

  struct msghdr msg;
  memset(&msg, 0, sizeof(msg));
  struct iovec iov = {buf, length};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char control_buffer[CMSG_SPACE(sizeof(int) * kMaxDescriptors)];
  msg.msg_control = control_buffer;
  msg.msg_controllen = sizeof(control_buffer);

  const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, 0));
  if (r == -1)
    return -1;

  int* wire_fds = NULL;
  unsigned wire_fds_len = 0;

  if (msg.msg_controllen > 0) {
    struct cmsghdr* cmsg;
    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
      if (cmsg->cmsg_level == SOL_SOCKET &&
          cmsg->cmsg_type == SCM_RIGHTS) {
        const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
        DCHECK(payload_len % sizeof(int) == 0);
        wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
        wire_fds_len = payload_len / sizeof(int);
        break;
      }
    }
  }

  if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
    for (unsigned i = 0; i < wire_fds_len; ++i)
      close(wire_fds[i]);
    errno = EMSGSIZE;
    return -1;
  }

  fds->resize(wire_fds_len);
  memcpy(vector_as_array(fds), wire_fds, sizeof(int) * wire_fds_len);

  return r;
}

// static
ssize_t UnixDomainSocket::SendRecvMsg(int fd,
                                      uint8_t* reply,
                                      unsigned max_reply_len,
                                      int* result_fd,
                                      const Pickle& request) {
  int fds[2];

  // This socketpair is only used for the IPC and is cleaned up before
  // returning.
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1)
      return false;

  std::vector<int> fd_vector;
  fd_vector.push_back(fds[1]);
  if (!SendMsg(fd, request.data(), request.size(), fd_vector)) {
    close(fds[0]);
    close(fds[1]);
    return -1;
  }
  close(fds[1]);

  fd_vector.clear();
  const ssize_t reply_len = RecvMsg(fds[0], reply, max_reply_len, &fd_vector);
  close(fds[0]);
  if (reply_len == -1)
    return -1;

  if ((!fd_vector.empty() && result_fd == NULL) || fd_vector.size() > 1) {
    for (std::vector<int>::const_iterator
         i = fd_vector.begin(); i != fd_vector.end(); ++i) {
      close(*i);
    }

    NOTREACHED();

    return -1;
  }

  if (result_fd)
    *result_fd = fd_vector.empty() ? -1 : fd_vector[0];

  return reply_len;
}
<|endoftext|>


<commit_before>#include "statistic.h"
#include <cassert>

using namespace  dariadb::statistic;
using namespace  dariadb::statistic::integral;
using namespace  dariadb::statistic::average;

class StatisticReadClbk :public dariadb::storage::ReaderClb {
public:
	StatisticReadClbk(BaseMethod*m):_method(m)
	{
	}

	void call(const dariadb::Meas&m) {
		assert(_method != nullptr);
		_method->call(m);
	}
	BaseMethod*_method;
};

BaseMethod::BaseMethod() {
	_is_first = true;
	_result = 0;
}

void BaseMethod::call(const dariadb::Meas&m){
    if(_is_first){
        _last=m;
        _is_first=false;
    }else{
        this->calc(_last,m);
        _last=m;
    }
}

dariadb::Value BaseMethod::result()const {
	return _result;
}

void BaseMethod::fromReader(dariadb::storage::Reader_ptr&ptr, dariadb::Time from, dariadb::Time to, dariadb::Time step) {
	std::unique_ptr<StatisticReadClbk> c{ new StatisticReadClbk{ this } };
	ptr->readByStep(c.get(), from, to, step);
}

RectangleMethod::RectangleMethod(const RectangleMethod::Kind k):
	BaseMethod(),
	_kind(k)
{}

void RectangleMethod::calc(const dariadb::Meas&a, const dariadb::Meas&b){
	switch (_kind)
	{
	case Kind::LEFT:
		_result += a.value*(b.time - a.time);
		break;
	case Kind::RIGHT:
		_result += b.value*(b.time - a.time);
		break;
	case Kind::MIDLE:
		_result += ((a.value + b.value) / 2.0)*(b.time - a.time);
		break;
	default:
		assert(false);
	}
}
Average::Average():BaseMethod() {
	_count = 0;
}

void Average::call(const dariadb::Meas&a){
	_result += a.value;
	_count++;
}

void Average::calc(const dariadb::Meas&, const dariadb::Meas&){
}

dariadb::Value Average::result()const {
	assert(_count != 0);
	return _result / _count;
}<commit_msg>todo.<commit_after>#include "statistic.h"
#include <cassert>

using namespace  dariadb::statistic;
using namespace  dariadb::statistic::integral;
using namespace  dariadb::statistic::average;

class StatisticReadClbk :public dariadb::storage::ReaderClb {
public:
	StatisticReadClbk(BaseMethod*m):_method(m)
	{
	}

	void call(const dariadb::Meas&m) {
		assert(_method != nullptr);
		_method->call(m);
	}
	BaseMethod*_method;
};

BaseMethod::BaseMethod() {
	_is_first = true;
	_result = 0;
}

void BaseMethod::call(const dariadb::Meas&m){
	//TODO add check to m.Id. id must be one.
    if(_is_first){
        _last=m;
        _is_first=false;
    }else{
        this->calc(_last,m);
        _last=m;
    }
}

dariadb::Value BaseMethod::result()const {
	return _result;
}

void BaseMethod::fromReader(dariadb::storage::Reader_ptr&ptr, dariadb::Time from, dariadb::Time to, dariadb::Time step) {
	std::unique_ptr<StatisticReadClbk> c{ new StatisticReadClbk{ this } };
	ptr->readByStep(c.get(), from, to, step);
}

RectangleMethod::RectangleMethod(const RectangleMethod::Kind k):
	BaseMethod(),
	_kind(k)
{}

void RectangleMethod::calc(const dariadb::Meas&a, const dariadb::Meas&b){
	switch (_kind)
	{
	case Kind::LEFT:
		_result += a.value*(b.time - a.time);
		break;
	case Kind::RIGHT:
		_result += b.value*(b.time - a.time);
		break;
	case Kind::MIDLE:
		_result += ((a.value + b.value) / 2.0)*(b.time - a.time);
		break;
	default:
		assert(false);
	}
}
Average::Average():BaseMethod() {
	_count = 0;
}

void Average::call(const dariadb::Meas&a){
	_result += a.value;
	_count++;
}

void Average::calc(const dariadb::Meas&, const dariadb::Meas&){
}

dariadb::Value Average::result()const {
	assert(_count != 0);
	return _result / _count;
}<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <pandora/util/ReferenceList.hpp>
#include <pandora/PSize.hpp>
#include <pandora/Selection.hpp>
#include <pandora/DataSet.hpp>

using namespace std;

namespace pandora {
namespace util {

const PSize ReferenceList::MIN_CHUNK_SIZE = {1};
const PSize ReferenceList::MAX_SIZE_1D = {H5S_UNLIMITED};

ReferenceList::ReferenceList(const ReferenceList &other)
  : group(other.group), ds_name(other.ds_name)
{}

ReferenceList::ReferenceList(const Group &group, const string &ds_name)
  : group(group), ds_name(ds_name)
{}

bool ReferenceList::has(const string &id) const {

  vector<string> ids = get();
  return std::find(ids.begin(), ids.end(), id) != ids.end();
}

vector<string> ReferenceList::get() const {
  vector<string> ids;

  if (group.hasData(ds_name)) {
    DataSet ds = group.openData(ds_name);
    ds.read(ids, true);
  }

  return ids;
}

void ReferenceList::set(const vector<string> &ids) {
  if (group.hasData(ds_name)) {
    DataSet ds = group.openData(ds_name);
    ds.extend({ids.size()});
    ds.write(ids);
  } else {
    DataSet ds = DataSet::create(group.h5Group(), ds_name, ids,
                                 &MAX_SIZE_1D, &MIN_CHUNK_SIZE);
    ds.write(ids);
  }
}

void ReferenceList::add(const string &id) {
  vector<string> new_ids = {id};

  if (group.hasData(ds_name)) {
    DataSet ds = group.openData("sources");
    PSize old_size = ds.size();
    PSize new_size = old_size + 1;
    ds.extend(new_size);
    PSize count = {1};
    Selection sel = ds.createSelection();
    sel.select(count, old_size);
    ds.write(new_ids, sel);
  } else {
    DataSet ds = DataSet::create(group.h5Group(), ds_name, new_ids,
                                 &MAX_SIZE_1D, &MIN_CHUNK_SIZE);
    ds.write(new_ids);
  }
}

bool ReferenceList::remove(const string &id) {
  bool removed = false;

  if (group.hasData(ds_name)) {
    vector<string> ids;
    DataSet ds = group.openData(ds_name);
    ds.read(ids, true);

    for (size_t i = 0; i < ids.size(); i++) {
      if (ids[i] == id) {
        ids.erase(ids.begin() + i);
        removed = true;
        break;
      }
    }

    if (removed) {
      PSize new_size = ds.size();
      ds.extend(--new_size);
      ds.write(ids);
    }
  }

  return removed;
}

bool ReferenceList::operator==(const ReferenceList &other) const {
  return group == other.group && ds_name == other.ds_name;
}

bool ReferenceList::operator!=(const ReferenceList &other) const {
  return !(*this == other);
}

ReferenceList& ReferenceList::operator=(const ReferenceList &other) {
  if (*this != other) {
    this->group = other.group;
    this->ds_name = other.ds_name;
  }
  return *this;
}

ReferenceList::~ReferenceList() {}

} // namespace util
} // namespace pandora
<commit_msg>fixed bug in referenceList<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <pandora/util/ReferenceList.hpp>
#include <pandora/PSize.hpp>
#include <pandora/Selection.hpp>
#include <pandora/DataSet.hpp>

using namespace std;

namespace pandora {
namespace util {

const PSize ReferenceList::MIN_CHUNK_SIZE = {1};
const PSize ReferenceList::MAX_SIZE_1D = {H5S_UNLIMITED};

ReferenceList::ReferenceList(const ReferenceList &other)
  : group(other.group), ds_name(other.ds_name)
{}

ReferenceList::ReferenceList(const Group &group, const string &ds_name)
  : group(group), ds_name(ds_name)
{}

bool ReferenceList::has(const string &id) const {

  vector<string> ids = get();
  return std::find(ids.begin(), ids.end(), id) != ids.end();
}

vector<string> ReferenceList::get() const {
  vector<string> ids;

  if (group.hasData(ds_name)) {
    DataSet ds = group.openData(ds_name);
    ds.read(ids, true);
  }

  return ids;
}

void ReferenceList::set(const vector<string> &ids) {
  if (group.hasData(ds_name)) {
    DataSet ds = group.openData(ds_name);
    ds.extend({ids.size()});
    ds.write(ids);
  } else {
    DataSet ds = DataSet::create(group.h5Group(), ds_name, ids,
                                 &MAX_SIZE_1D, &MIN_CHUNK_SIZE);
    ds.write(ids);
  }
}

void ReferenceList::add(const string &id) {
  vector<string> new_ids = {id};

  if (group.hasData(ds_name)) {
    DataSet ds = group.openData(ds_name);
    PSize old_size = ds.size();
    PSize new_size = old_size + 1;
    ds.extend(new_size);
    PSize count = {1};
    Selection sel = ds.createSelection();
    sel.select(count, old_size);
    ds.write(new_ids, sel);
  } else {
    DataSet ds = DataSet::create(group.h5Group(), ds_name, new_ids,
                                 &MAX_SIZE_1D, &MIN_CHUNK_SIZE);
    ds.write(new_ids);
  }
}

bool ReferenceList::remove(const string &id) {
  bool removed = false;

  if (group.hasData(ds_name)) {
    vector<string> ids;
    DataSet ds = group.openData(ds_name);
    ds.read(ids, true);

    for (size_t i = 0; i < ids.size(); i++) {
      if (ids[i] == id) {
        ids.erase(ids.begin() + i);
        removed = true;
        break;
      }
    }

    if (removed) {
      PSize new_size = ds.size();
      ds.extend(--new_size);
      ds.write(ids);
    }
  }

  return removed;
}

bool ReferenceList::operator==(const ReferenceList &other) const {
  return group == other.group && ds_name == other.ds_name;
}

bool ReferenceList::operator!=(const ReferenceList &other) const {
  return !(*this == other);
}

ReferenceList& ReferenceList::operator=(const ReferenceList &other) {
  if (*this != other) {
    this->group = other.group;
    this->ds_name = other.ds_name;
  }
  return *this;
}

ReferenceList::~ReferenceList() {}

} // namespace util
} // namespace pandora
<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2014 VoltDB Inc.
 *
 * 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef POOL_HPP_
#define POOL_HPP_
#include <vector>
#include <iostream>
#include <stdint.h>
#include <sys/mman.h>
#include <errno.h>
#include <climits>
#include <string.h>
#include "common/FatalException.hpp"

namespace voltdb {
#ifndef MEMCHECK
/**
 * Description of a chunk of memory allocated on the heap
 */
class Chunk {
public:
    Chunk()
        : m_offset(0), m_size(0), m_chunkData(NULL)
    {
    }

    inline Chunk(uint64_t size, void *chunkData)
        : m_offset(0), m_size(size), m_chunkData(static_cast<char*>(chunkData))
    {
    }

    int64_t getSize() const
    {
        return static_cast<int64_t>(m_size);
    }

    uint64_t m_offset;
    uint64_t m_size;
    char *m_chunkData;
};

/*
 * Find next higher power of two
 * From http://en.wikipedia.org/wiki/Power_of_two
 */
template <class T>
inline T nexthigher(T k) {
        if (k == 0)
                return 1;
        k--;
        for (int i=1; i<sizeof(T)*CHAR_BIT; i<<=1)
                k = k | k >> i;
        return k+1;
}

static const size_t TEMP_POOL_CHUNK_SIZE = 262144;

/**
 * A memory pool that provides fast allocation and deallocation. The
 * only way to release memory is to free all memory in the pool by
 * calling purge.
 */
class Pool {
public:
    Pool() :
        m_allocationSize(TEMP_POOL_CHUNK_SIZE), m_maxChunkCount(0), m_currentChunkIndex(0)
    {
    }

    Pool(uint64_t allocationSize, uint64_t maxChunkCount) :
#ifdef USE_MMAP
        m_allocationSize(nexthigher(allocationSize)),
#else
        m_allocationSize(allocationSize),
#endif
        m_maxChunkCount(static_cast<std::size_t>(maxChunkCount)),
        m_currentChunkIndex(0)
    {
    }

    ~Pool() {
        for (std::size_t ii = 0; ii < m_chunks.size(); ii++) {
#ifdef USE_MMAP
            if (::munmap( m_chunks[ii].m_chunkData, m_chunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_chunks[ii].m_chunkData;
#endif
        }
        for (std::size_t ii = 0; ii < m_oversizeChunks.size(); ii++) {
#ifdef USE_MMAP
            if (::munmap( m_oversizeChunks[ii].m_chunkData, m_oversizeChunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_oversizeChunks[ii].m_chunkData;
#endif
        }
    }

    /*
     * Allocate a continous block of memory of the specified size.
     */
    inline void* allocate(std::size_t size) {
        if (m_chunks.empty()) {
#ifdef USE_MMAP
            char *storage =
                    static_cast<char*>(::mmap( 0, m_allocationSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
            if (storage == MAP_FAILED) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed mmap");
            }
#else
            char *storage = new char[m_allocationSize];
#endif
            m_chunks.push_back(Chunk(m_allocationSize, storage));
        }

        /*
         * See if there is space in the current chunk
         */
        Chunk *currentChunk = &m_chunks[m_currentChunkIndex];
        if (size > currentChunk->m_size - currentChunk->m_offset) {
            /*
             * Not enough space. Check if it is greater then our allocation size.
             */
            if (size > m_allocationSize) {
                /*
                 * Allocate an oversize chunk that will not be reused.
                 */
#ifdef USE_MMAP
                char *storage =
                        static_cast<char*>(::mmap( 0, nexthigher(size), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
                if (storage == MAP_FAILED) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed mmap");
                }
#else
                char *storage = new char[size];
#endif
                m_oversizeChunks.push_back(Chunk(nexthigher(size), storage));
                Chunk &newChunk = m_oversizeChunks.back();
                newChunk.m_offset = size;
                return newChunk.m_chunkData;
            }

            /*
             * Check if there is an already allocated chunk we can use.
             */
            m_currentChunkIndex++;
            if (m_currentChunkIndex < m_chunks.size()) {
                currentChunk = &m_chunks[m_currentChunkIndex];
                currentChunk->m_offset = size;
                return currentChunk->m_chunkData;
            } else {
                /*
                 * Need to allocate a new chunk
                 */
//                std::cout << "Pool had to allocate a new chunk. Not a good thing "
//                  "from a performance perspective. If you see this we need to look "
//                  "into structuring our pool sizes and allocations so the this doesn't "
//                  "happen frequently" << std::endl;
#ifdef USE_MMAP
                char *storage =
                        static_cast<char*>(::mmap( 0, m_allocationSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
                if (storage == MAP_FAILED) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed mmap");
                }
#else
                char *storage = new char[m_allocationSize];
#endif
                m_chunks.push_back(Chunk(m_allocationSize, storage));
                Chunk &newChunk = m_chunks.back();
                newChunk.m_offset = size;
                return newChunk.m_chunkData;
            }
        }

        /*
         * Get the offset into the current chunk. Then increment the
         * offset counter by the amount being allocated.
         */
        void *retval = currentChunk->m_chunkData + currentChunk->m_offset;
        currentChunk->m_offset += size;

        //Ensure 8 byte alignment of future allocations
        currentChunk->m_offset += (8 - (currentChunk->m_offset % 8));
        if (currentChunk->m_offset > currentChunk->m_size) {
            currentChunk->m_offset = currentChunk->m_size;
        }

        return retval;
    }

    /*
     * Allocate a continous block of memory of the specified size conveniently initialized to 0s
     */
    inline void* allocateZeroes(std::size_t size) { return ::memset(allocate(size), 0, size); }

    inline void purge() {
        /*
         * Erase any oversize chunks that were allocated
         */
        const std::size_t numOversizeChunks = m_oversizeChunks.size();
        for (std::size_t ii = 0; ii < numOversizeChunks; ii++) {
#ifdef USE_MMAP
            if (::munmap( m_oversizeChunks[ii].m_chunkData, m_oversizeChunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_oversizeChunks[ii].m_chunkData;
#endif
        }
        m_oversizeChunks.clear();

        /*
         * Set the current chunk to the first in the list
         */
        m_currentChunkIndex = 0;
        std::size_t numChunks = m_chunks.size();

        /*
         * If more then maxChunkCount chunks are allocated erase all extra chunks
         */
        if (numChunks > m_maxChunkCount) {
            for (std::size_t ii = m_maxChunkCount; ii < numChunks; ii++) {
#ifdef USE_MMAP
                if (::munmap( m_chunks[ii].m_chunkData, m_chunks[ii].m_size) != 0) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed munmap");
                }
#else
                delete []m_chunks[ii].m_chunkData;
#endif
            }
            m_chunks.resize(m_maxChunkCount);
        }

        numChunks = m_chunks.size();
        for (std::size_t ii = 0; ii < numChunks; ii++) {
            m_chunks[ii].m_offset = 0;
        }
    }

    int64_t getAllocatedMemory()
    {
        int64_t total = 0;
        total += m_chunks.size() * m_allocationSize;
        for (int i = 0; i < m_oversizeChunks.size(); i++)
        {
            total += m_oversizeChunks[i].getSize();
        }
        return total;
    }

private:
    const uint64_t m_allocationSize;
    std::size_t m_maxChunkCount;
    std::size_t m_currentChunkIndex;
    std::vector<Chunk> m_chunks;
    /*
     * Oversize chunks that will be freed and not reused.
     */
    std::vector<Chunk> m_oversizeChunks;
    // No implicit copies
    Pool(const Pool&);
    Pool& operator=(const Pool&);
};
#else
/**
 * A debug version of the memory pool that does each allocation on the heap keeps a list for when purge is called
 */
class Pool {
public:
    Pool()
    {
    }

    Pool(uint64_t allocationSize, uint64_t maxChunkCount) :
        m_memTotal(0)
    {
    }

    ~Pool() {
        purge();
    }

    /*
     * Allocate a continous block of memory of the specified size.
     */
    inline void* allocate(std::size_t size) {
        char *retval = new char[size];
        m_allocations.push_back(retval);
        m_memTotal += size;
        return retval;
    }

    /*
     * Allocate a continous block of memory of the specified size conveniently initialized to 0s
     */
    inline void* allocateZeroes(std::size_t size) { return ::memset(allocate(size), 0, size); }

    inline void purge() {
        for (std::size_t ii = 0; ii < m_allocations.size(); ii++) {
            delete [] m_allocations[ii];
        }
        m_allocations.clear();
        m_memTotal = 0;
    }

    int64_t getAllocatedMemory()
    {
        return m_memTotal;
    }

private:
    std::vector<char*> m_allocations;
    int64_t m_memTotal;
    // No implicit copies
    Pool(const Pool&);
    Pool& operator=(const Pool&);
};
#endif
}
#endif /* POOL_HPP_ */
<commit_msg>move the constants to VoltDB scope for memcheck build<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2014 VoltDB Inc.
 *
 * 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 VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef POOL_HPP_
#define POOL_HPP_
#include <vector>
#include <iostream>
#include <stdint.h>
#include <sys/mman.h>
#include <errno.h>
#include <climits>
#include <string.h>
#include "common/FatalException.hpp"

namespace voltdb {
static const size_t TEMP_POOL_CHUNK_SIZE = 262144;

#ifndef MEMCHECK
/**
 * Description of a chunk of memory allocated on the heap
 */
class Chunk {
public:
    Chunk()
        : m_offset(0), m_size(0), m_chunkData(NULL)
    {
    }

    inline Chunk(uint64_t size, void *chunkData)
        : m_offset(0), m_size(size), m_chunkData(static_cast<char*>(chunkData))
    {
    }

    int64_t getSize() const
    {
        return static_cast<int64_t>(m_size);
    }

    uint64_t m_offset;
    uint64_t m_size;
    char *m_chunkData;
};

/*
 * Find next higher power of two
 * From http://en.wikipedia.org/wiki/Power_of_two
 */
template <class T>
inline T nexthigher(T k) {
        if (k == 0)
                return 1;
        k--;
        for (int i=1; i<sizeof(T)*CHAR_BIT; i<<=1)
                k = k | k >> i;
        return k+1;
}

/**
 * A memory pool that provides fast allocation and deallocation. The
 * only way to release memory is to free all memory in the pool by
 * calling purge.
 */
class Pool {
public:
    Pool() :
        m_allocationSize(TEMP_POOL_CHUNK_SIZE), m_maxChunkCount(0), m_currentChunkIndex(0)
    {
    }

    Pool(uint64_t allocationSize, uint64_t maxChunkCount) :
#ifdef USE_MMAP
        m_allocationSize(nexthigher(allocationSize)),
#else
        m_allocationSize(allocationSize),
#endif
        m_maxChunkCount(static_cast<std::size_t>(maxChunkCount)),
        m_currentChunkIndex(0)
    {
    }

    ~Pool() {
        for (std::size_t ii = 0; ii < m_chunks.size(); ii++) {
#ifdef USE_MMAP
            if (::munmap( m_chunks[ii].m_chunkData, m_chunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_chunks[ii].m_chunkData;
#endif
        }
        for (std::size_t ii = 0; ii < m_oversizeChunks.size(); ii++) {
#ifdef USE_MMAP
            if (::munmap( m_oversizeChunks[ii].m_chunkData, m_oversizeChunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_oversizeChunks[ii].m_chunkData;
#endif
        }
    }

    /*
     * Allocate a continous block of memory of the specified size.
     */
    inline void* allocate(std::size_t size) {
        if (m_chunks.empty()) {
#ifdef USE_MMAP
            char *storage =
                    static_cast<char*>(::mmap( 0, m_allocationSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
            if (storage == MAP_FAILED) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed mmap");
            }
#else
            char *storage = new char[m_allocationSize];
#endif
            m_chunks.push_back(Chunk(m_allocationSize, storage));
        }

        /*
         * See if there is space in the current chunk
         */
        Chunk *currentChunk = &m_chunks[m_currentChunkIndex];
        if (size > currentChunk->m_size - currentChunk->m_offset) {
            /*
             * Not enough space. Check if it is greater then our allocation size.
             */
            if (size > m_allocationSize) {
                /*
                 * Allocate an oversize chunk that will not be reused.
                 */
#ifdef USE_MMAP
                char *storage =
                        static_cast<char*>(::mmap( 0, nexthigher(size), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
                if (storage == MAP_FAILED) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed mmap");
                }
#else
                char *storage = new char[size];
#endif
                m_oversizeChunks.push_back(Chunk(nexthigher(size), storage));
                Chunk &newChunk = m_oversizeChunks.back();
                newChunk.m_offset = size;
                return newChunk.m_chunkData;
            }

            /*
             * Check if there is an already allocated chunk we can use.
             */
            m_currentChunkIndex++;
            if (m_currentChunkIndex < m_chunks.size()) {
                currentChunk = &m_chunks[m_currentChunkIndex];
                currentChunk->m_offset = size;
                return currentChunk->m_chunkData;
            } else {
                /*
                 * Need to allocate a new chunk
                 */
//                std::cout << "Pool had to allocate a new chunk. Not a good thing "
//                  "from a performance perspective. If you see this we need to look "
//                  "into structuring our pool sizes and allocations so the this doesn't "
//                  "happen frequently" << std::endl;
#ifdef USE_MMAP
                char *storage =
                        static_cast<char*>(::mmap( 0, m_allocationSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0 ));
                if (storage == MAP_FAILED) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed mmap");
                }
#else
                char *storage = new char[m_allocationSize];
#endif
                m_chunks.push_back(Chunk(m_allocationSize, storage));
                Chunk &newChunk = m_chunks.back();
                newChunk.m_offset = size;
                return newChunk.m_chunkData;
            }
        }

        /*
         * Get the offset into the current chunk. Then increment the
         * offset counter by the amount being allocated.
         */
        void *retval = currentChunk->m_chunkData + currentChunk->m_offset;
        currentChunk->m_offset += size;

        //Ensure 8 byte alignment of future allocations
        currentChunk->m_offset += (8 - (currentChunk->m_offset % 8));
        if (currentChunk->m_offset > currentChunk->m_size) {
            currentChunk->m_offset = currentChunk->m_size;
        }

        return retval;
    }

    /*
     * Allocate a continous block of memory of the specified size conveniently initialized to 0s
     */
    inline void* allocateZeroes(std::size_t size) { return ::memset(allocate(size), 0, size); }

    inline void purge() {
        /*
         * Erase any oversize chunks that were allocated
         */
        const std::size_t numOversizeChunks = m_oversizeChunks.size();
        for (std::size_t ii = 0; ii < numOversizeChunks; ii++) {
#ifdef USE_MMAP
            if (::munmap( m_oversizeChunks[ii].m_chunkData, m_oversizeChunks[ii].m_size) != 0) {
                std::cout << strerror( errno ) << std::endl;
                throwFatalException("Failed munmap");
            }
#else
            delete [] m_oversizeChunks[ii].m_chunkData;
#endif
        }
        m_oversizeChunks.clear();

        /*
         * Set the current chunk to the first in the list
         */
        m_currentChunkIndex = 0;
        std::size_t numChunks = m_chunks.size();

        /*
         * If more then maxChunkCount chunks are allocated erase all extra chunks
         */
        if (numChunks > m_maxChunkCount) {
            for (std::size_t ii = m_maxChunkCount; ii < numChunks; ii++) {
#ifdef USE_MMAP
                if (::munmap( m_chunks[ii].m_chunkData, m_chunks[ii].m_size) != 0) {
                    std::cout << strerror( errno ) << std::endl;
                    throwFatalException("Failed munmap");
                }
#else
                delete []m_chunks[ii].m_chunkData;
#endif
            }
            m_chunks.resize(m_maxChunkCount);
        }

        numChunks = m_chunks.size();
        for (std::size_t ii = 0; ii < numChunks; ii++) {
            m_chunks[ii].m_offset = 0;
        }
    }

    int64_t getAllocatedMemory()
    {
        int64_t total = 0;
        total += m_chunks.size() * m_allocationSize;
        for (int i = 0; i < m_oversizeChunks.size(); i++)
        {
            total += m_oversizeChunks[i].getSize();
        }
        return total;
    }

private:
    const uint64_t m_allocationSize;
    std::size_t m_maxChunkCount;
    std::size_t m_currentChunkIndex;
    std::vector<Chunk> m_chunks;
    /*
     * Oversize chunks that will be freed and not reused.
     */
    std::vector<Chunk> m_oversizeChunks;
    // No implicit copies
    Pool(const Pool&);
    Pool& operator=(const Pool&);
};
#else
/**
 * A debug version of the memory pool that does each allocation on the heap keeps a list for when purge is called
 */
class Pool {
public:
    Pool()
    {
    }

    Pool(uint64_t allocationSize, uint64_t maxChunkCount) :
        m_memTotal(0)
    {
    }

    ~Pool() {
        purge();
    }

    /*
     * Allocate a continous block of memory of the specified size.
     */
    inline void* allocate(std::size_t size) {
        char *retval = new char[size];
        m_allocations.push_back(retval);
        m_memTotal += size;
        return retval;
    }

    /*
     * Allocate a continous block of memory of the specified size conveniently initialized to 0s
     */
    inline void* allocateZeroes(std::size_t size) { return ::memset(allocate(size), 0, size); }

    inline void purge() {
        for (std::size_t ii = 0; ii < m_allocations.size(); ii++) {
            delete [] m_allocations[ii];
        }
        m_allocations.clear();
        m_memTotal = 0;
    }

    int64_t getAllocatedMemory()
    {
        return m_memTotal;
    }

private:
    std::vector<char*> m_allocations;
    int64_t m_memTotal;
    // No implicit copies
    Pool(const Pool&);
    Pool& operator=(const Pool&);
};
#endif
}
#endif /* POOL_HPP_ */
<|endoftext|>


<commit_before>int main() {
}
<commit_msg>argc, argV<commit_after>int main(int argc, char **argv) {
  return 0;
}
<|endoftext|>


<commit_before>#include "shared.h"

#include "job.h"

#include "image.h"

ImagePair Job::get_next_pair() {
	std::unique_lock<std::mutex> ul{mutex};

	while (index_major != images.size() && images[index_major] == nullptr) {
		if (index_next_to_create < images.size()) {
			// create image
			auto i = index_next_to_create++;
			ul.unlock();
			auto image = std::make_shared<Image>(paths[i]);
			ul.lock();
			images[i] = image;
		} else {
			// no more images to create but allow other threads to finish creating images
			ul.unlock();
			ul.lock();
		}
	}

	if (index_major == images.size())
		return {nullptr, nullptr};

	auto index_minor_old = index_minor;
	auto index_major_old = index_major;

	if (index_minor == index_major) {
		index_major++;
		index_minor = 0;
	} else {
		index_minor++;
	}

	return {images[index_minor_old], images[index_major_old]};
}

float Job::get_progress() const {
	std::lock_guard<std::mutex> lg{mutex};
	return static_cast<float>(progress_current()) / progress_total();
}

bool Job::is_completed() const {
	std::lock_guard<std::mutex> lg{mutex};
	return index_major == images.size();
}

std::size_t Job::progress_current() const {
	return index_major * (1 + index_major) / 2 + index_minor;
}

std::size_t Job::progress_total() const {
	return paths.size() * (1 + paths.size()) / 2;
}
<commit_msg>Style<commit_after>#include "shared.h"

#include "job.h"

#include "image.h"

ImagePair Job::get_next_pair() {
	std::unique_lock<std::mutex> ul{mutex};

	while (index_major != images.size() && images[index_major] == nullptr) {
		if (index_next_to_create < images.size()) {
			// create image
			auto i = index_next_to_create++;
			ul.unlock();
			auto image = std::make_shared<Image>(paths[i]);
			ul.lock();
			images[i] = image;
		} else {
			// no more images to create but allow other threads to finish creating images
			ul.unlock();
			ul.lock();
		}
	}

	if (index_major == images.size())
		return {nullptr, nullptr};

	auto result = ImagePair{images[index_minor], images[index_major]};

	if (index_minor == index_major) {
		index_major++;
		index_minor = 0;
	} else {
		index_minor++;
	}

	return result;
}

float Job::get_progress() const {
	std::lock_guard<std::mutex> lg{mutex};
	return static_cast<float>(progress_current()) / progress_total();
}

bool Job::is_completed() const {
	std::lock_guard<std::mutex> lg{mutex};
	return index_major == images.size();
}

std::size_t Job::progress_current() const {
	return index_major * (1 + index_major) / 2 + index_minor;
}

std::size_t Job::progress_total() const {
	return paths.size() * (1 + paths.size()) / 2;
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "contents.hh"
#include "show_message.hh"

namespace vick {
namespace join {

struct join_c : public change {
    const move_t y, x;
    join_c(const contents& contents)
        : y(contents.y)
        , x(contents.cont[y].size()) {}
    virtual bool is_overriding() override { return true; }
    virtual void undo(contents& contents) override {
        contents.cont.insert(contents.cont.begin() + y + 1,
                             contents.cont[y].substr(x));
        contents.cont[y] = contents.cont[y].substr(0, x);
    }
    virtual void redo(contents& contents) override {
        contents.cont[y] += contents.cont[y + 1];
        contents.cont.erase(contents.cont.begin() + y + 1);
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override {
        return std::make_shared<join_c>(contents);
    }
};

boost::optional<std::shared_ptr<change> >
join_two_lines(contents& contents, boost::optional<int>) {
    if (contents.y >= contents.cont.size() - 1) {
        show_message("Can't join lines past end");
        return boost::none;
    }
    std::shared_ptr<change> join = std::make_shared<join_c>(contents);
    join->redo(contents);
    return join;
}
}
}
<commit_msg>Make `change::is_overriding()` `const noexcept`<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "contents.hh"
#include "show_message.hh"

namespace vick {
namespace join {

struct join_c : public change {
    const move_t y, x;
    join_c(const contents& contents)
        : y(contents.y)
        , x(contents.cont[y].size()) {}
    virtual bool is_overriding() const noexcept override {
        return true;
    }
    virtual void undo(contents& contents) override {
        contents.cont.insert(contents.cont.begin() + y + 1,
                             contents.cont[y].substr(x));
        contents.cont[y] = contents.cont[y].substr(0, x);
    }
    virtual void redo(contents& contents) override {
        contents.cont[y] += contents.cont[y + 1];
        contents.cont.erase(contents.cont.begin() + y + 1);
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override {
        return std::make_shared<join_c>(contents);
    }
};

boost::optional<std::shared_ptr<change> >
join_two_lines(contents& contents, boost::optional<int>) {
    if (contents.y >= contents.cont.size() - 1) {
        show_message("Can't join lines past end");
        return boost::none;
    }
    std::shared_ptr<change> join = std::make_shared<join_c>(contents);
    join->redo(contents);
    return join;
}
}
}
<|endoftext|>


<commit_before>// win32find.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/types.h>

void _check_invariant_conditions(int argc, char *argv[])
{
	if (argc == 1 || argc > 3)
	{
		fprintf(stderr, "usage: %s [starting point...] [expression]\n", argv[0]);
		exit(-1); // argument length
	}
	if (strlen(argv[1]) > MAX_PATH)
	{
		fprintf(stderr, "argument length: path cannot exceed %d characters\n", MAX_PATH);
		exit(-1);
	}
	if (argc > 3 && strlen(argv[2]) > FILENAME_MAX)
	{
		fprintf(stderr, "argument length: expression cannot exceed %d characters\n", FILENAME_MAX);
		exit(-1);
	}
}

void _search(wchar_t base_path[], wchar_t filename[])
{
	LPWIN32_FIND_DATA hFile = (LPWIN32_FIND_DATA) GlobalAlloc(GMEM_ZEROINIT, sizeof(WIN32_FIND_DATA));
	HANDLE findResult = NULL;

	wchar_t combined_filename[MAX_PATH] = TEXT("");

	StringCchCat(combined_filename, MAX_PATH - FILENAME_MAX - 1, base_path);
	StringCchCat(combined_filename, 1, TEXT("/"));
	StringCchCat(combined_filename, FILENAME_MAX, filename);

	findResult = FindFirstFile((LPCWSTR)combined_filename, hFile);

	if (findResult == INVALID_HANDLE_VALUE)
	{
		DWORD dw_error_code = 0;

		dw_error_code = GetLastError();

		if (dw_error_code == ERROR_FILE_NOT_FOUND)
		{
			_tprintf(TEXT("No results to display.\n"));
		}
		else
		{
			_tprintf(TEXT("FindFirstFile failed %d\n"), dw_error_code);
		}
	}

	do
	{
		_tprintf(TEXT("%s\n"), hFile->cFileName);
	} while (FindNextFile(findResult, hFile));

	FindClose(findResult);
}

int main(int argc, char *argv[])
{
	_check_invariant_conditions(argc, argv);

	wchar_t base_path[MAX_PATH] = L"";
	wchar_t file_name[FILENAME_MAX] = L"";

	if (argc == 2)
	{
		wchar_t fn[FILENAME_MAX];
		mbstowcs_s(NULL, fn, argv[1], FILENAME_MAX);

		StringCchCat(base_path, 4, L".\\");
		StringCchCat(file_name, FILENAME_MAX * sizeof(wchar_t), fn);
	}
	else if (argc == 3)
	{
		wchar_t fn[FILENAME_MAX * sizeof(wchar_t)];
		mbstowcs_s(NULL, fn, argv[2], FILENAME_MAX);

		wchar_t bp[MAX_PATH * sizeof(wchar_t)];
		mbstowcs_s(NULL, bp, argv[1], FILENAME_MAX);

		StringCchCat(base_path, MAX_PATH * sizeof(wchar_t), bp);
		StringCchCat(file_name, FILENAME_MAX * sizeof(wchar_t), fn);
	}

	_search(base_path, file_name);

	return 0;
}<commit_msg>making find recursive<commit_after>// win32find.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/types.h>

void _check_invariant_conditions(int argc, char *argv[])
{
	if (argc == 1 || argc > 3)
	{
		fprintf(stderr, "usage: %s [starting point...] [expression]\n", argv[0]);
		exit(-1); // argument length
	}
	if (strlen(argv[1]) > MAX_PATH)
	{
		fprintf(stderr, "argument length: path cannot exceed %d characters\n", MAX_PATH);
		exit(-1);
	}
	if (argc > 3 && strlen(argv[2]) > FILENAME_MAX)
	{
		fprintf(stderr, "argument length: expression cannot exceed %d characters\n", FILENAME_MAX);
		exit(-1);
	}
}

void _search(wchar_t base_path[], wchar_t filename[])
{
	LPWIN32_FIND_DATA hFile = (LPWIN32_FIND_DATA)GlobalAlloc(GMEM_ZEROINIT, sizeof(WIN32_FIND_DATA));
	LPWIN32_FIND_DATA hDirectory = (LPWIN32_FIND_DATA) GlobalAlloc(GMEM_ZEROINIT, sizeof(WIN32_FIND_DATA));

	HANDLE findFileResult = NULL;
	HANDLE findDirectoryResult = NULL;

	wchar_t wildcard[MAX_PATH] = L"";

	size_t bp_sz = wcsnlen_s(base_path, MAX_PATH);

	StringCchCat(wildcard, bp_sz + 1, base_path);
	StringCchCat(wildcard, bp_sz + 2, L"*");

	findDirectoryResult = FindFirstFile((LPCWSTR)wildcard, hDirectory);

	if (findDirectoryResult == INVALID_HANDLE_VALUE)
	{
		DWORD dw_error_code = 0;

		dw_error_code = GetLastError();

		if (dw_error_code != ERROR_FILE_NOT_FOUND)
		{
			_tprintf(TEXT("FindFirstFile failed %d\n"), dw_error_code);
		}
	}

	do
	{
		if (hDirectory->dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY
			&& wcscmp(hDirectory->cFileName, L".") != 0
			&& wcscmp(hDirectory->cFileName, L"..") != 0)
		{
			wchar_t new_bp[MAX_PATH] = L"";

			size_t fn_sz = wcsnlen_s(hDirectory->cFileName, FILENAME_MAX);

			StringCchCat(new_bp, bp_sz + 1, base_path);
			StringCchCat(new_bp, bp_sz + fn_sz + 1, hDirectory->cFileName);
			StringCchCat(new_bp, bp_sz + fn_sz + 2, L"\\");

			_search(new_bp, filename);
		}

	} while (FindNextFile(findDirectoryResult, hDirectory));

	wchar_t combined_filename[MAX_PATH] = TEXT("");

	StringCchCat(combined_filename, bp_sz + 1, base_path);
	StringCchCat(combined_filename, bp_sz + 2, TEXT("\\"));
	StringCchCat(combined_filename, bp_sz + wcsnlen_s(filename, FILENAME_MAX) + 2, filename);

	findFileResult = FindFirstFile((LPCWSTR)combined_filename, hFile);

	if (findFileResult == INVALID_HANDLE_VALUE)
	{
		DWORD dw_error_code = 0;

		dw_error_code = GetLastError();

		if (dw_error_code != ERROR_FILE_NOT_FOUND)
		{
			_tprintf(TEXT("FindFirstFile failed %d\n"), dw_error_code);
			return;
		}

		return;
	}

	do
	{
		wchar_t fpn[MAX_PATH] = L"";
		StringCchCat(fpn, bp_sz + 1, base_path);
		StringCchCat(fpn, bp_sz + 2, L"\\");
		StringCchCat(fpn, bp_sz + wcsnlen_s(hFile->cFileName, FILENAME_MAX) + 2, hFile->cFileName);

		_tprintf(TEXT("%s\n"), fpn);
	} while (FindNextFile(findFileResult, hFile));

	FindClose(findFileResult);
}

int main(int argc, char *argv[])
{
	_check_invariant_conditions(argc, argv);

	wchar_t base_path[MAX_PATH] = L"";
	wchar_t file_name[FILENAME_MAX] = L"";

	if (argc == 2)
	{
		wchar_t fn[FILENAME_MAX];
		mbstowcs_s(NULL, fn, argv[1], FILENAME_MAX);

		StringCchCat(base_path, sizeof(wchar_t) * 3, L".\\");
		StringCchCat(file_name, FILENAME_MAX * sizeof(wchar_t), fn);
	}
	else if (argc == 3)
	{
		wchar_t fn[FILENAME_MAX * sizeof(wchar_t)];
		mbstowcs_s(NULL, fn, argv[2], FILENAME_MAX);

		wchar_t bp[MAX_PATH * sizeof(wchar_t)];
		mbstowcs_s(NULL, bp, argv[1], FILENAME_MAX);

		StringCchCat(base_path, MAX_PATH * sizeof(wchar_t), bp);
		StringCchCat(file_name, FILENAME_MAX * sizeof(wchar_t), fn);
	}

	_search(base_path, file_name);

	return 0;
}<|endoftext|>


<commit_before>#ifndef SILICIUM_SINK_HPP
#define SILICIUM_SINK_HPP

#include <silicium/override.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/filesystem/path.hpp>
#include <ostream>
#include <array>
#include <memory>

namespace Si
{
	template <class Element>
	struct sink
	{
		virtual ~sink()
		{
		}

		virtual boost::iterator_range<Element *> make_append_space(std::size_t size) = 0;
		virtual void flush_append_space() = 0;
		virtual void append(boost::iterator_range<Element const *> data) = 0;
	};

	template <class Element>
	struct flushable_sink : sink<Element>
	{
		virtual void flush() = 0;
	};

	template <class Element>
	void commit(sink<Element> &destination, std::size_t count)
	{
		destination.make_append_space(count);
		destination.flush_append_space();
	}

	template <class Element, class Buffer = std::array<Element, ((1U << 13U) / sizeof(Element))>>
	struct buffering_sink : flushable_sink<Element>
	{
		explicit buffering_sink(sink<Element> &destination, Buffer buffer = Buffer())
			: m_destination(destination)
			, m_fallback_buffer(std::move(buffer))
			, m_buffer_used(0)
		{
		}

		boost::iterator_range<Element *> make_append_space(std::size_t size) SILICIUM_OVERRIDE
		{
			auto first_try = m_destination.make_append_space(size);
			if (!first_try.empty())
			{
				auto const copied = (std::min)(static_cast<std::ptrdiff_t>(m_buffer_used), first_try.size());
				std::copy(m_fallback_buffer.begin(), m_fallback_buffer.begin() + copied, first_try.begin());
				m_buffer_used = 0;
				return first_try;
			}
			m_buffer_used = (std::min)(size, m_fallback_buffer.size());
			return boost::make_iterator_range(m_fallback_buffer.data(), m_fallback_buffer.data() + m_buffer_used);
		}

		void flush_append_space() SILICIUM_OVERRIDE
		{
			if (m_buffer_used)
			{
				flush();
			}
			else
			{
				m_destination.flush_append_space();
			}
		}

		void append(boost::iterator_range<Element const *> data) SILICIUM_OVERRIDE
		{
			if (data.size() <= (m_fallback_buffer.size() - m_buffer_used))
			{
				boost::range::copy(data, m_fallback_buffer.begin() + m_buffer_used);
				m_buffer_used += data.size();
				return;
			}

			flush();
			m_destination.append(data);
		}

		void flush() SILICIUM_OVERRIDE
		{
			m_destination.append(boost::make_iterator_range(m_fallback_buffer.data(), m_fallback_buffer.data() + m_buffer_used));
			m_buffer_used = 0;
		}

	private:

		sink<Element> &m_destination;
		Buffer m_fallback_buffer;
		std::size_t m_buffer_used;
	};

	template <class Element, class OutputIterator>
	struct iterator_sink : sink<Element>
	{
		explicit iterator_sink(OutputIterator out)
			: m_out(std::move(out))
		{
		}

		virtual boost::iterator_range<Element *> make_append_space(std::size_t) SILICIUM_OVERRIDE
		{
			return {};
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
		}

		virtual void append(boost::iterator_range<Element const *> data) SILICIUM_OVERRIDE
		{
			boost::range::copy(data, m_out);
		}

	private:

		OutputIterator m_out;
	};

	template <class Element, class OutputIterator>
	auto make_iterator_sink(OutputIterator out)
		-> iterator_sink<Element, typename std::decay<OutputIterator>::type>
	{
		return iterator_sink<Element, typename std::decay<OutputIterator>::type>(std::move(out));
	}

	template <class Container>
	auto make_container_sink(Container &destination)
		-> iterator_sink<typename Container::value_type, std::back_insert_iterator<Container>>
	{
		return make_iterator_sink<typename Container::value_type>(std::back_inserter(destination));
	}

	struct ostream_sink : flushable_sink<char>
	{
		//unique_ptr to make ostreams movable
		explicit ostream_sink(std::unique_ptr<std::ostream> file)
			: m_file(std::move(file))
		{
			m_file->exceptions(std::ios::failbit | std::ios::badbit);
		}

		virtual boost::iterator_range<char *> make_append_space(std::size_t) SILICIUM_OVERRIDE
		{
			return {};
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
		}

		virtual void append(boost::iterator_range<char const *> data) SILICIUM_OVERRIDE
		{
			m_file->write(data.begin(), data.size());
		}

		virtual void flush() SILICIUM_OVERRIDE
		{
			m_file->flush();
		}

	private:

		std::unique_ptr<std::ostream> m_file;
	};

	std::unique_ptr<flushable_sink<char>> make_file_sink(boost::filesystem::path const &name);

	template <class Element>
	struct auto_flush_sink : sink<Element>
	{
		auto_flush_sink()
			: m_next(nullptr)
		{
		}

		explicit auto_flush_sink(flushable_sink<Element> &next)
			: m_next(&next)
		{
		}

		virtual boost::iterator_range<char *> make_append_space(std::size_t size) SILICIUM_OVERRIDE
		{
			assert(m_next);
			return m_next->make_append_space(size);
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
			assert(m_next);
			m_next->flush_append_space();
			m_next->flush();
		}

		virtual void append(boost::iterator_range<char const *> data) SILICIUM_OVERRIDE
		{
			assert(m_next);
			m_next->append(data);
			m_next->flush();
		}

	private:

		flushable_sink<Element> *m_next;
	};

	template <class Element>
	auto_flush_sink<Element> make_auto_flush_sink(flushable_sink<Element> &next)
	{
		return auto_flush_sink<Element>(next);
	}

	template <class Element>
	void append(Si::sink<Element> &out, std::basic_string<Element> const &str)
	{
		out.append(boost::make_iterator_range(str.data(), str.data() + str.size()));
	}

	template <class Element>
	void append(Si::sink<Element> &out, Element const *c_str)
	{
		out.append(boost::make_iterator_range(c_str, c_str + std::char_traits<Element>::length(c_str)));
	}

	template <class Element>
	void append(Si::sink<Element> &out, Element const &single)
	{
		out.append(boost::make_iterator_range(&single, &single + 1));
	}
}

#endif
<commit_msg>add sink that append to an std::ostream &<commit_after>#ifndef SILICIUM_SINK_HPP
#define SILICIUM_SINK_HPP

#include <silicium/override.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/filesystem/path.hpp>
#include <ostream>
#include <array>
#include <memory>

namespace Si
{
	template <class Element>
	struct sink
	{
		virtual ~sink()
		{
		}

		virtual boost::iterator_range<Element *> make_append_space(std::size_t size) = 0;
		virtual void flush_append_space() = 0;
		virtual void append(boost::iterator_range<Element const *> data) = 0;
	};

	template <class Element>
	struct flushable_sink : sink<Element>
	{
		virtual void flush() = 0;
	};

	template <class Element>
	void commit(sink<Element> &destination, std::size_t count)
	{
		destination.make_append_space(count);
		destination.flush_append_space();
	}

	template <class Element, class Buffer = std::array<Element, ((1U << 13U) / sizeof(Element))>>
	struct buffering_sink : flushable_sink<Element>
	{
		explicit buffering_sink(sink<Element> &destination, Buffer buffer = Buffer())
			: m_destination(destination)
			, m_fallback_buffer(std::move(buffer))
			, m_buffer_used(0)
		{
		}

		boost::iterator_range<Element *> make_append_space(std::size_t size) SILICIUM_OVERRIDE
		{
			auto first_try = m_destination.make_append_space(size);
			if (!first_try.empty())
			{
				auto const copied = (std::min)(static_cast<std::ptrdiff_t>(m_buffer_used), first_try.size());
				std::copy(m_fallback_buffer.begin(), m_fallback_buffer.begin() + copied, first_try.begin());
				m_buffer_used = 0;
				return first_try;
			}
			m_buffer_used = (std::min)(size, m_fallback_buffer.size());
			return boost::make_iterator_range(m_fallback_buffer.data(), m_fallback_buffer.data() + m_buffer_used);
		}

		void flush_append_space() SILICIUM_OVERRIDE
		{
			if (m_buffer_used)
			{
				flush();
			}
			else
			{
				m_destination.flush_append_space();
			}
		}

		void append(boost::iterator_range<Element const *> data) SILICIUM_OVERRIDE
		{
			if (data.size() <= (m_fallback_buffer.size() - m_buffer_used))
			{
				boost::range::copy(data, m_fallback_buffer.begin() + m_buffer_used);
				m_buffer_used += data.size();
				return;
			}

			flush();
			m_destination.append(data);
		}

		void flush() SILICIUM_OVERRIDE
		{
			m_destination.append(boost::make_iterator_range(m_fallback_buffer.data(), m_fallback_buffer.data() + m_buffer_used));
			m_buffer_used = 0;
		}

	private:

		sink<Element> &m_destination;
		Buffer m_fallback_buffer;
		std::size_t m_buffer_used;
	};

	template <class Element, class OutputIterator>
	struct iterator_sink : sink<Element>
	{
		explicit iterator_sink(OutputIterator out)
			: m_out(std::move(out))
		{
		}

		virtual boost::iterator_range<Element *> make_append_space(std::size_t) SILICIUM_OVERRIDE
		{
			return {};
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
		}

		virtual void append(boost::iterator_range<Element const *> data) SILICIUM_OVERRIDE
		{
			boost::range::copy(data, m_out);
		}

	private:

		OutputIterator m_out;
	};

	template <class Element, class OutputIterator>
	auto make_iterator_sink(OutputIterator out)
		-> iterator_sink<Element, typename std::decay<OutputIterator>::type>
	{
		return iterator_sink<Element, typename std::decay<OutputIterator>::type>(std::move(out));
	}

	template <class Container>
	auto make_container_sink(Container &destination)
		-> iterator_sink<typename Container::value_type, std::back_insert_iterator<Container>>
	{
		return make_iterator_sink<typename Container::value_type>(std::back_inserter(destination));
	}

	struct ostream_ref_sink : flushable_sink<char>
	{
		explicit ostream_ref_sink(std::ostream &file)
		   : m_file(file)
		{
		}

		virtual boost::iterator_range<char *> make_append_space(std::size_t) SILICIUM_OVERRIDE
		{
		   return {};
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
		}

		virtual void append(boost::iterator_range<char const *> data) SILICIUM_OVERRIDE
		{
		   m_file.write(data.begin(), data.size());
		}

		virtual void flush() SILICIUM_OVERRIDE
		{
		   m_file.flush();
		}

	private:

		std::ostream &m_file;
	};

	struct ostream_sink : flushable_sink<char>
	{
		//unique_ptr to make ostreams movable
		explicit ostream_sink(std::unique_ptr<std::ostream> file)
			: m_file(std::move(file))
		{
			m_file->exceptions(std::ios::failbit | std::ios::badbit);
		}

		virtual boost::iterator_range<char *> make_append_space(std::size_t) SILICIUM_OVERRIDE
		{
			return {};
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
		}

		virtual void append(boost::iterator_range<char const *> data) SILICIUM_OVERRIDE
		{
			m_file->write(data.begin(), data.size());
		}

		virtual void flush() SILICIUM_OVERRIDE
		{
			m_file->flush();
		}

	private:

		std::unique_ptr<std::ostream> m_file;
	};

	std::unique_ptr<flushable_sink<char>> make_file_sink(boost::filesystem::path const &name);

	template <class Element>
	struct auto_flush_sink : sink<Element>
	{
		auto_flush_sink()
			: m_next(nullptr)
		{
		}

		explicit auto_flush_sink(flushable_sink<Element> &next)
			: m_next(&next)
		{
		}

		virtual boost::iterator_range<char *> make_append_space(std::size_t size) SILICIUM_OVERRIDE
		{
			assert(m_next);
			return m_next->make_append_space(size);
		}

		virtual void flush_append_space() SILICIUM_OVERRIDE
		{
			assert(m_next);
			m_next->flush_append_space();
			m_next->flush();
		}

		virtual void append(boost::iterator_range<char const *> data) SILICIUM_OVERRIDE
		{
			assert(m_next);
			m_next->append(data);
			m_next->flush();
		}

	private:

		flushable_sink<Element> *m_next;
	};

	template <class Element>
	auto_flush_sink<Element> make_auto_flush_sink(flushable_sink<Element> &next)
	{
		return auto_flush_sink<Element>(next);
	}

	template <class Element>
	void append(Si::sink<Element> &out, std::basic_string<Element> const &str)
	{
		out.append(boost::make_iterator_range(str.data(), str.data() + str.size()));
	}

	template <class Element>
	void append(Si::sink<Element> &out, Element const *c_str)
	{
		out.append(boost::make_iterator_range(c_str, c_str + std::char_traits<Element>::length(c_str)));
	}

	template <class Element>
	void append(Si::sink<Element> &out, Element const &single)
	{
		out.append(boost::make_iterator_range(&single, &single + 1));
	}
}

#endif
<|endoftext|>


<commit_before>/**	@file	ScenesManager.cpp
	@author	Philip Abbet

	Implementation of the class 'Athena::Entities::ScenesManager'
*/

#include <Athena-Entities/ScenesManager.h>
#include <Athena-Entities/Scene.h>
#include <Athena-Core/Log/LogManager.h>

using namespace Athena::Entities;
using namespace Athena::Utils;
using namespace Athena::Log;
using namespace std;

/************************************** CONSTANTS ***************************************/

/// Context used for logging
static const char* __CONTEXT__ = "Scenes manager";

/********************************** STATIC ATTRIBUTES ***********************************/

/// The instance of the singleton
template<> ScenesManager* Singleton<ScenesManager>::ms_Singleton = 0;

/****************************** CONSTRUCTION / DESTRUCTION ******************************/

ScenesManager::ScenesManager()
: m_pCurrentScene(0)
{
	ATHENA_LOG_EVENT("Creation");
}

//-----------------------------------------------------------------------

ScenesManager::~ScenesManager()
{
	ATHENA_LOG_EVENT("Destruction");

	destroyAll();
}

//-----------------------------------------------------------------------

ScenesManager& ScenesManager::getSingleton()
{
	assert(ms_Singleton);
	return *ms_Singleton;
}

//-----------------------------------------------------------------------

ScenesManager* ScenesManager::getSingletonPtr()
{
	return ms_Singleton;
}

/******************************** MANAGEMENT OF THE SCENES ******************************/

Scene* ScenesManager::create(const std::string& strName)
{
	// Assertions
	assert(!strName.empty() && "Invalid entity name");

	return new Scene(strName);
}

//-----------------------------------------------------------------------

Scene* ScenesManager::getScene(const std::string& strName)
{
	assert(!strName.empty() && "The name is empty");

	// Declarations
	tScenesNativeIterator iter, iterEnd;

	// Search the entity
	for (iter = m_scenes.begin(), iterEnd = m_scenes.end(); iter != iterEnd; ++iter)
	{
		if ((*iter)->getName() == strName)
		{
			// Return it
			return (*iter);
		}
	}

	// Not found
	return 0;
}

//-----------------------------------------------------------------------

void ScenesManager::destroy(const std::string& strName)
{
	// Assertions
	assert(!strName.empty() && "The name is empty");

	// Declarations
	Scene* pScene;

	// Search the entity
	pScene = getScene(strName);
	if (pScene)
	{
		destroy(pScene);
	}
	else
	{
		ATHENA_LOG_ERROR("Failed to destroy the scene '" + strName + "'");
		assert(false);	// A scene not registered with this manager is not possible
	}
}

//-----------------------------------------------------------------------

void ScenesManager::destroy(Scene* pScene)
{
	// Assertions
	assert(pScene && "Invalid scene");

	delete pScene;
}

//-----------------------------------------------------------------------

void ScenesManager::destroyAll()
{
	while (!m_scenes.empty())
		destroy(m_scenes.front());
}

//-----------------------------------------------------------------------

void ScenesManager::_registerScene(Scene* pScene)
{
	// Assertions
	assert(pScene && "Invalid scene");

	// Add the scene to the list
	m_scenes.push_back(pScene);
}

//-----------------------------------------------------------------------

void ScenesManager::_destroyScene(Scene* pScene)
{
	// CScenesManager
	assert(pScene && "Invalid scene");

	// Declarations
	tScenesNativeIterator iter, iterEnd;

	// Search the entity
	for (iter = m_scenes.begin(), iterEnd = m_scenes.end(); iter != iterEnd; ++iter)
	{
		if (*iter == pScene)
		{
			// Remove it from the list
			m_scenes.erase(iter);
			break;
		}
	}

	if (m_pCurrentScene == pScene)
		m_pCurrentScene = 0;
}

//-----------------------------------------------------------------------

void ScenesManager::_onSceneShown(Scene* pScene)
{
	// Assertions
	assert(pScene);
	assert(!pScene->isShown());

	if (m_pCurrentScene)
		m_pCurrentScene->hide();

	m_pCurrentScene = pScene;
}

//-----------------------------------------------------------------------

void ScenesManager::_onSceneHidden(Scene* pScene)
{
	// Assertions
	assert(pScene);
	assert(pScene->isShown());

	m_pCurrentScene = 0;
}
<commit_msg>Fix a typo<commit_after>/**	@file	ScenesManager.cpp
	@author	Philip Abbet

	Implementation of the class 'Athena::Entities::ScenesManager'
*/

#include <Athena-Entities/ScenesManager.h>
#include <Athena-Entities/Scene.h>
#include <Athena-Core/Log/LogManager.h>

using namespace Athena::Entities;
using namespace Athena::Utils;
using namespace Athena::Log;
using namespace std;

/************************************** CONSTANTS ***************************************/

/// Context used for logging
static const char* __CONTEXT__ = "Scenes manager";

/********************************** STATIC ATTRIBUTES ***********************************/

/// The instance of the singleton
template<> ScenesManager* Singleton<ScenesManager>::ms_Singleton = 0;

/****************************** CONSTRUCTION / DESTRUCTION ******************************/

ScenesManager::ScenesManager()
: m_pCurrentScene(0)
{
	ATHENA_LOG_EVENT("Creation");
}

//-----------------------------------------------------------------------

ScenesManager::~ScenesManager()
{
	ATHENA_LOG_EVENT("Destruction");

	destroyAll();
}

//-----------------------------------------------------------------------

ScenesManager& ScenesManager::getSingleton()
{
	assert(ms_Singleton);
	return *ms_Singleton;
}

//-----------------------------------------------------------------------

ScenesManager* ScenesManager::getSingletonPtr()
{
	return ms_Singleton;
}

/******************************** MANAGEMENT OF THE SCENES ******************************/

Scene* ScenesManager::create(const std::string& strName)
{
	// Assertions
	assert(!strName.empty() && "Invalid entity name");

	return new Scene(strName);
}

//-----------------------------------------------------------------------

Scene* ScenesManager::getScene(const std::string& strName)
{
	assert(!strName.empty() && "The name is empty");

	// Declarations
	tScenesNativeIterator iter, iterEnd;

	// Search the entity
	for (iter = m_scenes.begin(), iterEnd = m_scenes.end(); iter != iterEnd; ++iter)
	{
		if ((*iter)->getName() == strName)
		{
			// Return it
			return (*iter);
		}
	}

	// Not found
	return 0;
}

//-----------------------------------------------------------------------

void ScenesManager::destroy(const std::string& strName)
{
	// Assertions
	assert(!strName.empty() && "The name is empty");

	// Declarations
	Scene* pScene;

	// Search the entity
	pScene = getScene(strName);
	if (pScene)
	{
		destroy(pScene);
	}
	else
	{
		ATHENA_LOG_ERROR("Failed to destroy the scene '" + strName + "'");
		assert(false);	// A scene not registered with this manager is not possible
	}
}

//-----------------------------------------------------------------------

void ScenesManager::destroy(Scene* pScene)
{
	// Assertions
	assert(pScene && "Invalid scene");

	delete pScene;
}

//-----------------------------------------------------------------------

void ScenesManager::destroyAll()
{
	while (!m_scenes.empty())
		destroy(m_scenes.front());
}

//-----------------------------------------------------------------------

void ScenesManager::_registerScene(Scene* pScene)
{
	// Assertions
	assert(pScene && "Invalid scene");

	// Add the scene to the list
	m_scenes.push_back(pScene);
}

//-----------------------------------------------------------------------

void ScenesManager::_destroyScene(Scene* pScene)
{
	// Assertions
	assert(pScene && "Invalid scene");

	// Declarations
	tScenesNativeIterator iter, iterEnd;

	// Search the scene
	for (iter = m_scenes.begin(), iterEnd = m_scenes.end(); iter != iterEnd; ++iter)
	{
		if (*iter == pScene)
		{
			// Remove it from the list
			m_scenes.erase(iter);
			break;
		}
	}

	if (m_pCurrentScene == pScene)
		m_pCurrentScene = 0;
}

//-----------------------------------------------------------------------

void ScenesManager::_onSceneShown(Scene* pScene)
{
	// Assertions
	assert(pScene);
	assert(!pScene->isShown());

	if (m_pCurrentScene)
		m_pCurrentScene->hide();

	m_pCurrentScene = pScene;
}

//-----------------------------------------------------------------------

void ScenesManager::_onSceneHidden(Scene* pScene)
{
	// Assertions
	assert(pScene);
	assert(pScene->isShown());

	m_pCurrentScene = 0;
}
<|endoftext|>


<commit_before>#include "common.h"
#include "World.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &, std::vector<Object *> &) {
	chunks.With([] (ChunksType &chunks) {
		//INFO(chunks.size());
	});

	if(cameraObj == nullptr) { return; }
	auto camera = cameraObj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		auto pos = cameraObj->Get<PositionComponent>();
		if(pos != nullptr) {
			const unsigned char distance = 6;

			auto chunkSizeF = glm::fvec3(chunkSize);
			auto keyBase = glm::ivec3(glm::floor(pos->position.To<glm::fvec3>()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							if(obj != nullptr) {
								engine->RemoveObject(obj, false);
								obj->Pool();
							}
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, nullptr));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto data = Generate(keyTuple);
									auto chunkObj = Chunk::New(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));
									auto pos = chunkObj->Get<PositionComponent>();
									auto chunkPos = glm::fvec3(key) * chunkSizeF;
									pos->position = Point(chunkPos.x, chunkPos.y, chunkPos.z + chunkSize.z, 1);

									jobM->Do([this, keyTuple, key, chunkSizeF, chunkObj] () {
										engine->AddObject(chunkObj);
										chunks.With([&keyTuple, chunkObj] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, chunkObj);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

void World::ObjectAdded(Object *obj) {
	auto camera = obj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		cameraObj = obj;
	}
}

std::vector<bool> World::Generate(const ChunkKeyType &keyTuple) const {
	/*const float start = -0.5, end = -0;
	static double factor = 1.0f;
	factor /= 1.0001f;
	auto r = factor * (start - end) + end;*/

	const float scale = 0.5f;
	const float scaleX = scale, scaleY = scale * 2, scaleZ = scale;

	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	float xIncr = 1.0f / chunkSize.x, yIncr = 1.0f / chunkSize.y, zIncr = 1.0f / chunkSize.z;
	int i = 0;
	for(float z = 0; z < 1; z += zIncr) {
		for(float x = 0; x < 1; x += xIncr) {
			for(float y = 0; y < 1; y += yIncr) {
				double random = noise.eval(
					( std::get<0>(keyTuple) + x) * scaleX,
					( std::get<1>(keyTuple) + y) * scaleY,
					(-std::get<2>(keyTuple) + z) * scaleZ
				);
				blocks.at(i++) = random > 0.45f;
			}
		}
	}
	return blocks;
}
<commit_msg>World: Tidy up; separate block generation from chunk generation<commit_after>#include "common.h"
#include "World.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &, std::vector<Object *> &) {
	if(cameraObj == nullptr) { return; }
	auto camera = cameraObj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		auto pos = cameraObj->Get<PositionComponent>();
		if(pos != nullptr) {
			const unsigned char distance = 5;

			auto chunkSizeF = glm::fvec3(chunkSize);
			auto keyBase = glm::ivec3(glm::floor(pos->position.To<glm::fvec3>()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							if(obj != nullptr) {
								engine->RemoveObject(obj, false);
								obj->Pool();
							}
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, nullptr));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto data = Generate(keyTuple);
									auto chunkObj = Chunk::New(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));
									auto pos = chunkObj->Get<PositionComponent>();
									auto chunkPos = glm::fvec3(key) * chunkSizeF;
									pos->position = Point(chunkPos.x, chunkPos.y, chunkPos.z + chunkSize.z, 1);

									jobM->Do([this, keyTuple, key, chunkSizeF, chunkObj] () {
										engine->AddObject(chunkObj);
										chunks.With([&keyTuple, chunkObj] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, chunkObj);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

void World::ObjectAdded(Object *obj) {
	auto camera = obj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		cameraObj = obj;
	}
}

std::vector<bool> World::Generate(const ChunkKeyType &keyTuple) const {
	const float scale = 1.0f;
	const float scaleX = scale, scaleY = scale, scaleZ = scale;

	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	float xIncr = 1.0f / chunkSize.x, yIncr = 1.0f / chunkSize.y, zIncr = 1.0f / chunkSize.z;
	int i = 0;
	for(float z = 0; z < 1; z += zIncr) {
		for(float x = 0; x < 1; x += xIncr) {
			for(float y = 0; y < 1; y += yIncr) {
				blocks.at(i++) = GenerateBlock(
					( std::get<0>(keyTuple) + x) * scaleX,
					( std::get<1>(keyTuple) + y) * scaleY,
					(-std::get<2>(keyTuple) + z) * scaleZ
				);
			}
		}
	}
	return blocks;
}

bool World::GenerateBlock(const float x, const float y, const float z) const {
	return noise.eval(x, y, z) > 0.45f;
}
<|endoftext|>


<commit_before>#include "common.h"
#include "World.h"
#include "JobManager.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &) {
	auto pair = engine->objects.right.equal_range(&typeid(PlayerCameraComponent));
	for(auto it = pair.first; it != pair.second; ++it) {
		auto object = it->get_left();
		auto camera = static_cast<PlayerCameraComponent *>(it->info.get());

		auto pos = engine->GetComponent<PositionComponent>(object);
		if(pos != nullptr) {
			const unsigned char distance = 5;

			auto chunkSizeF = glm::fvec3(chunkSize);
			auto keyBase = glm::ivec3(glm::floor(pos->position.To<glm::fvec3>()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							engine->RemoveObject(obj);
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, 0));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto chunkPos = glm::fvec3(key) * chunkSizeF;
									auto pos = Point3(chunkPos.x, chunkPos.y, chunkPos.z);
									auto data = GenerateChunk(Point3(std::get<0>(keyTuple), std::get<1>(keyTuple), std::get<2>(keyTuple)));
									auto chunk = new Chunk(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));

									jobM->Do([this, keyTuple, chunk, pos] () {
										auto id = engine->AddObject();
										engine->AddComponent<PositionComponent>(id, pos);
										engine->InsertComponent<ModelComponent>(id, chunk);
										chunks.With([&keyTuple, id] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, id);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

std::vector<bool> World::GenerateChunk(const Point3 &&p) const {
	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	const Point3 blockSize(1, 1, 1);
	Point3 actual = p * Point3(blockSize.x * chunkSize.x, blockSize.y * chunkSize.y, blockSize.z * chunkSize.z);

	int i = 0;
	for(float z = 0; z < blockSize.z * chunkSize.z; z += blockSize.z) {
		for(float x = 0; x < blockSize.x * chunkSize.x; x += blockSize.x) {
			for(float y = 0; y < blockSize.y * chunkSize.y; y += blockSize.y) {
				blocks.at(i++) = GenerateBlock(actual + Point3(x, y, z));
			}
		}
	}
	return blocks;
}

bool World::GenerateBlock(const Point3 &&p) const {
	/* periodic 'normal distribution' function */
	auto fDensity = [] (const double x) {
		return 1.0 - glm::abs(glm::sin(x));
	};

	const float scale = 17.0f;
	auto result = noise.eval(p.x / scale, p.y * 1.6f / scale, p.z / scale);
	return (
		result > (fDensity(p.x / scale / 32.0f) - 1) * 1.5f + 0.1f ||
		result > (fDensity(p.y / scale / 10.0f) - 1) * 1.5f + 0.1f ||
		result > (fDensity(p.z / scale / 32.0f) - 1) * 1.5f + 0.1f
		);
}
<commit_msg>Various World fixes<commit_after>#include "common.h"
#include "World.h"
#include "JobManager.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &) {
	auto pair = engine->objects.right.equal_range(&typeid(PlayerCameraComponent));
	for(auto it = pair.first; it != pair.second; ++it) {
		auto object = it->get_left();
		auto camera = static_cast<PlayerCameraComponent *>(it->info.get());

		auto pos = engine->GetComponent<PositionComponent>(object);
		if(pos != nullptr) {
			const unsigned char distance = 5;

			auto chunkSizeF = Point3(chunkSize);
			auto keyBase = glm::ivec3(glm::round(pos->position.Get()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, jobM, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							jobM->Do([this, obj] () { engine->RemoveObject(obj); }, JobPriority::Low, JobThread::Main);
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, 0));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto pos = new PositionComponent(Point3(key) * chunkSizeF);
									auto data = GenerateChunk(Point3(std::get<0>(keyTuple), std::get<1>(keyTuple), std::get<2>(keyTuple)));
									auto chunk = new Chunk(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));

									jobM->Do([this, keyTuple, chunk, pos] () {
										auto id = engine->AddObject();
										engine->InsertComponent<PositionComponent>(id, pos);
										engine->InsertComponent<ModelComponent>(id, chunk);
										chunks.With([&keyTuple, id] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, id);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

std::vector<bool> World::GenerateChunk(const Point3 &&p) const {
	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	const Point3 blockSize(1, 1, 1);
	Point3 actual = p * Point3(blockSize.x * chunkSize.x, blockSize.y * chunkSize.y, blockSize.z * chunkSize.z);

	int i = 0;
	for(float z = 0; z < blockSize.z * chunkSize.z; z += blockSize.z) {
		for(float x = 0; x < blockSize.x * chunkSize.x; x += blockSize.x) {
			for(float y = 0; y < blockSize.y * chunkSize.y; y += blockSize.y) {
				blocks.at(i++) = GenerateBlock(actual + Point3(x, y, z));
			}
		}
	}
	return blocks;
}

bool World::GenerateBlock(const Point3 &&p) const {
	/* periodic 'normal distribution' function */
	auto fDensity = [] (const double x) {
		return 1.0 - glm::abs(glm::sin(x));
	};

	const float scale = 17.0f;
	auto result = noise.eval(p.x / scale, p.y * 1.6f / scale, p.z / scale);
	return (
		result > (fDensity(p.x / scale / 32.0f) - 1) * 1.5f + 0.1f ||
		result > (fDensity(p.y / scale / 10.0f) - 1) * 1.5f + 0.1f ||
		result > (fDensity(p.z / scale / 32.0f) - 1) * 1.5f + 0.1f
		);
}
<|endoftext|>


<commit_before>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2010-08-13 Markus Litz <Markus.Litz@dlr.de>
* Changed: $Id: main.cpp 203 2012-09-25 08:47:55Z martinsiggel $
*
* Version: $Revision: 203 $
*
* 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.
*/

#include <iostream>
#include <fstream>
#include <clocale>

#include <QString>
#include <QMessageBox>

#include "TIGLViewerWindow.h"
#include "CommandLineParameters.h"

using namespace std;

int parseArguments(QStringList);
void showHelp(QString);

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

#ifdef __APPLE__
    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
#endif

#if defined __linux__
    // we need to set us locale as we use "." for decimal point
    putenv("LC_NUMERIC=C");
    setlocale(LC_NUMERIC, "C");
#elif defined __APPLE__
    setlocale(LC_NUMERIC, "C");
#endif

    // set shader file location
    QString shaderDir = QCoreApplication::applicationDirPath();
#ifdef __APPLE__
    shaderDir += "/../Resources";
#else
    shaderDir += "/../share/tigl/shaders";
#endif
    if (qgetenv("CSF_ShadersDirectory").isNull()) {
        qputenv("CSF_ShadersDirectory", shaderDir.toUtf8());
    }

    int retval = parseArguments(app.arguments());
    if (retval != 0) {
        showHelp(app.arguments().at(0));
        return retval;
    }

    TIGLViewerWindow window;
    window.show();

    if (!PARAMS.controlFile.isEmpty()){
        window.setInitialControlFile(PARAMS.controlFile);
    }

    // if a filename is given, open the configuration
    if (!PARAMS.initialFilename.isEmpty()) {
        window.openFile(PARAMS.initialFilename);
    }

    // if a script is given
    if (!PARAMS.initialScript.isEmpty()) {
        window.openScript(PARAMS.initialScript);
    }

    retval = app.exec();
    return retval;
}

/**
 * Show a dialog with command line information.
 */
void showHelp(QString appName)
{
    QString helpText = appName + " [--help] [--filename <filename>]\n\n";
    helpText += "  --help                      This help page\n";
    helpText += "  --filename <filename>    Initial CPACS file to open and display.\n";
    helpText += "  --modelUID <uid>         Initial model uid open and display.\n";
    helpText += "  --script <filename>       Script to execute.\n";
    helpText += "  --windowtitle <title>    The titel of the TIGLViewer window.\n";
    helpText += "  --controlFile <filename>    Name of the control file.\n";
    helpText += "  --JediMode <on|off>      Makes you some kind of superhero like CPACS-Ninja.\n";

    QMessageBox::information(0, "TIGLViewer Argument Error",
                                 helpText,
                                 QMessageBox::Ok );
}

/**
 * Parsing the command line arguments. The values will be saved
 * in a global structure "PARAMS".
 */
int parseArguments(QStringList argList)
{
    for (int i = 1; i < argList.size(); i++) {
        QString arg = argList.at(i);
        if (arg.compare("--help") == 0) {
            return -1;
        }
        else if (arg.compare("--filename") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing filename" << endl;
                return -1;
            }
            else {
                PARAMS.initialFilename = argList.at(++i);
            }
        }
        else if (arg.compare("--script") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing script filename" << endl;
                return -1;
            }
            else {
                PARAMS.initialScript = argList.at(++i);
            }
        }
        else if (arg.compare("--windowtitle") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing windowtitle" << endl;
                PARAMS.windowTitle = "TIGLViewer";
            }
            else {
                PARAMS.windowTitle = argList.at(++i);
            }
        }
        else if (arg.compare("--modelUID") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing modelUID" << endl;
                PARAMS.modelUID = "";
            }
            else {
                PARAMS.modelUID = argList.at(++i);
            }
        }
        else if (arg.compare("--controlFile") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing controlFile" << endl;
                PARAMS.controlFile = "";
            }
            else {
                PARAMS.controlFile = argList.at(++i);
            }
        }
        /* when there is a string behind the executable, we assume its the filename */
        else {
            PARAMS.initialFilename = arg;
        }
    }

    return 0;
}

<commit_msg>Implemented check for shaders directory<commit_after>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2010-08-13 Markus Litz <Markus.Litz@dlr.de>
* Changed: $Id: main.cpp 203 2012-09-25 08:47:55Z martinsiggel $
*
* Version: $Revision: 203 $
*
* 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.
*/

#include <iostream>
#include <fstream>
#include <clocale>

#include <QString>
#include <QMessageBox>

#include "TIGLViewerWindow.h"
#include "CommandLineParameters.h"

using namespace std;

int parseArguments(QStringList);
void showHelp(QString);

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

#ifdef __APPLE__
    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
#endif

#if defined __linux__
    // we need to set us locale as we use "." for decimal point
    putenv("LC_NUMERIC=C");
    setlocale(LC_NUMERIC, "C");
#elif defined __APPLE__
    setlocale(LC_NUMERIC, "C");
#endif

    // set shader file location
    QString shaderDir = QCoreApplication::applicationDirPath();
#ifdef __APPLE__
    shaderDir += "/../Resources";
#else
    shaderDir += "/../share/tigl/shaders";
#endif

    QByteArray envVar = qgetenv("CSF_ShadersDirectory");
    if (envVar.isNull()) {
        qputenv("CSF_ShadersDirectory", shaderDir.toUtf8());
    }
    else {
        shaderDir = envVar;
    }

    // check existance of shader dir
    if (!QFile(shaderDir+"/PhongShading.fs").exists()) {
        std::stringstream str;
        str << "Illegal or non existing shader directory "
            << "
" << shaderDir.toStdString() << "
"
            << "Set the enviroment variable CSF_ShadersDirectory to provide a path for the OpenCASCADE shaders.";
        QMessageBox::critical(0, "Startup error...",
                                  str.str().c_str(),
                                  QMessageBox::Ok );
        return 1;
    }

    int retval = parseArguments(app.arguments());
    if (retval != 0) {
        showHelp(app.arguments().at(0));
        return retval;
    }

    TIGLViewerWindow window;
    window.show();

    if (!PARAMS.controlFile.isEmpty()){
        window.setInitialControlFile(PARAMS.controlFile);
    }

    // if a filename is given, open the configuration
    if (!PARAMS.initialFilename.isEmpty()) {
        window.openFile(PARAMS.initialFilename);
    }

    // if a script is given
    if (!PARAMS.initialScript.isEmpty()) {
        window.openScript(PARAMS.initialScript);
    }

    retval = app.exec();
    return retval;
}

/**
 * Show a dialog with command line information.
 */
void showHelp(QString appName)
{
    QString helpText = appName + " [--help] [--filename <filename>]\n\n";
    helpText += "  --help                      This help page\n";
    helpText += "  --filename <filename>    Initial CPACS file to open and display.\n";
    helpText += "  --modelUID <uid>         Initial model uid open and display.\n";
    helpText += "  --script <filename>       Script to execute.\n";
    helpText += "  --windowtitle <title>    The titel of the TIGLViewer window.\n";
    helpText += "  --controlFile <filename>    Name of the control file.\n";
    helpText += "  --JediMode <on|off>      Makes you some kind of superhero like CPACS-Ninja.\n";

    QMessageBox::information(0, "TIGLViewer Argument Error",
                                 helpText,
                                 QMessageBox::Ok );
}

/**
 * Parsing the command line arguments. The values will be saved
 * in a global structure "PARAMS".
 */
int parseArguments(QStringList argList)
{
    for (int i = 1; i < argList.size(); i++) {
        QString arg = argList.at(i);
        if (arg.compare("--help") == 0) {
            return -1;
        }
        else if (arg.compare("--filename") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing filename" << endl;
                return -1;
            }
            else {
                PARAMS.initialFilename = argList.at(++i);
            }
        }
        else if (arg.compare("--script") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing script filename" << endl;
                return -1;
            }
            else {
                PARAMS.initialScript = argList.at(++i);
            }
        }
        else if (arg.compare("--windowtitle") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing windowtitle" << endl;
                PARAMS.windowTitle = "TIGLViewer";
            }
            else {
                PARAMS.windowTitle = argList.at(++i);
            }
        }
        else if (arg.compare("--modelUID") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing modelUID" << endl;
                PARAMS.modelUID = "";
            }
            else {
                PARAMS.modelUID = argList.at(++i);
            }
        }
        else if (arg.compare("--controlFile") == 0) {
            if (i+1 >= argList.size()) {
                cout << "missing controlFile" << endl;
                PARAMS.controlFile = "";
            }
            else {
                PARAMS.controlFile = argList.at(++i);
            }
        }
        /* when there is a string behind the executable, we assume its the filename */
        else {
            PARAMS.initialFilename = arg;
        }
    }

    return 0;
}

<|endoftext|>