<commit_before>#include <chord.h>
#include <dhash.h>
#include <dhash_common.h>
#include "dhashcli.h"

#include "dhblock_noauth.h"
#include "dhblock_noauth_srv.h"
#include "dhblock_noauth.h"

#include "locationtable.h"
#include "location.h"

#include "merkle_tree.h"
#include "merkle_server.h"

// "fake" key to merkle on.. low 32 bits are hash of the block contents
ptr<dbrec>
dhblock_noauth_srv::get_merkle_key (chordID key, ptr<dbrec> data)
{

  assert (data);

  //get the low bits: xor of the marshalled words
  long *d = (long *)data->value;
  long hash = 0;
  for (int i = 0; i < data->len/4; i++)
    hash ^= d[i];

  if (hash < 0) hash = -hash;

  //mix the hash in with the low bytes
  chordID fkey = key >> 32;
  fkey = fkey << 32;
  chordID mkey = fkey | bigint(hash);

  return id2dbrec(mkey);
}

// key to store data under in the DB. Low 32-bits are zero
ptr<dbrec>
dhblock_noauth_srv::get_database_key (chordID key)
{

  //get a key with the low bits cleard out
  key = key >> 32;
  key = key << 32;
  assert (key > 0);  //assert that there were some high bits left
  ptr<dbrec> nk = id2dbrec (key);

  return nk;
}

dhblock_noauth_srv::dhblock_noauth_srv (ptr<vnode> node, str desc,
					str dbname, dbOptions opts) :
  dhblock_replicated_srv (node, desc, dbname, opts, DHASH_NOAUTH)
{

  // merkle state, don't populate from db
  mtree = New merkle_tree (db, false);

  //populate the merkle tree with appropriately bit-hacked keys
  ptr<dbEnumeration> it = db->enumerate ();
  ptr<dbPair> d = it->firstElement();
  for (int i = 0; d; i++, d = it->nextElement()) {
    if (i == 0)
      warn << "Database is not empty.  Loading into merkle tree\n";

    ptr<dbrec> data = db->lookup (d->key);
    assert (data);
    merkle_hash mkey = to_merkle_hash (get_merkle_key (dbrec2id(d->key), data));

    warn << "insert: " << dbrec2id(get_merkle_key (dbrec2id(d->key), data)) << " into merkle tree\n";

    mtree->insert (mkey);
  }

  // merkle state
  msrv = New merkle_server (mtree);

}

ptr<dbrec>
dhblock_noauth_srv::fetch (chordID k)
{
  ptr<dbrec> id = dhblock_noauth_srv::get_database_key (k);
  return db->lookup (id);
}

dhash_stat
dhblock_noauth_srv::store (chordID key, ptr<dbrec> new_data)
{
  dhash_stat stat (DHASH_OK);

  ptr<dbrec> dprep = merge_data (key, new_data);

  if (dprep) { //NULL unless new_data changed contents
    ptr<dbrec> kdb = dhblock_noauth_srv::get_database_key (key);
    ptr<dbrec> old_data = db->lookup (kdb);

    //put the key in the merkle tree; kick out the old key
    merkle_hash mkey;
    if (old_data) {
      mkey = to_merkle_hash (dhblock_noauth_srv::get_merkle_key (key, old_data));
      mtree->remove (mkey);
      db->del (kdb);
    }
    mkey = to_merkle_hash (dhblock_noauth_srv::get_merkle_key (key, dprep));
    mtree->insert (mkey);
    db->insert (kdb, dprep);

    warn << "db write: "
	 << " U " << key << " " << dprep->len << "\n";
  }
  return stat;
}

// add new_data to existing key
// returns NULL unless new_data added new sub-blocks
ptr<dbrec>
dhblock_noauth_srv::merge_data (chordID key, ptr<dbrec> new_data)
{

  vec<str> new_elems = dhblock_noauth::get_payload (new_data->value,
						    new_data->len);
  vec<str> old_elems;

  ptr<dbrec> kdb = dhblock_noauth_srv::get_database_key (key);
  ptr<dbrec> prev_data = db->lookup (kdb);
  if (prev_data)
    old_elems = dhblock_noauth::get_payload (prev_data->value, prev_data->len);

  qhash<bigint, bool, hashID> old_hashes;
  for (u_int i = 0; i < old_elems.size (); i++) {
    old_hashes.insert (compute_hash (old_elems[i].cstr (),
				     old_elems[i].len ()),
		       true);
  }

  u_int pre_merge_size = old_elems.size ();
  //look through the new data for sub blocks we don't have
  for (u_int i = 0; i < new_elems.size (); i++) {
    if (!old_hashes[compute_hash (new_elems[i].cstr (),
				  new_elems[i].len ())]) {
      //a new block, append it to old_elems
      old_elems.push_back (new_elems[i]);
    }
  }

  if (old_elems.size () == pre_merge_size) {
    return NULL;
  }

  //otherwise, delete the old data block and insert the new marshalled one
  str marshalled_block = dhblock_noauth::marshal_block (old_elems);

  ptr<dbrec> rec = New refcounted<dbrec> (marshalled_block.cstr (),
					  marshalled_block.len ());
  return rec;
}

void
dhblock_noauth_srv::bsmupdate (user_args *sbp, dhash_bsmupdate_arg *arg)
{

  if (arg->round_over) {
    //    warn << "sync round over\n";
  } else {
    /** XXX Should make sure that only called from localhost! */
    chord_node n = make_chord_node (arg->n);
    ptr<location> from = node->locations->lookup (n.x);
    if (from) {
      chordID dbkey = dbrec2id (dhblock_noauth_srv::get_database_key (arg->key));
      if (!arg->local) {
	//send our block to from
	warn << node->my_ID () << " sending " << dbkey << " to " << from->id () << "\n";
	cli->sendblock (from,  blockID (dbkey, DHASH_NOAUTH), db,
			wrap (this, &dhblock_noauth_srv::repair_send_cb));
      } else {
	warn << "getting " << dbkey << " from " << from << "\n";
	// get his block and call store?
	cli->retrieve (blockID (dbkey, DHASH_NOAUTH),
		       wrap (this, &dhblock_noauth_srv::repair_retrieve_cb,dbkey));

      }
    } else
      warn << "stale bsmupdate\n";
  }
  sbp->reply (NULL);
}

void
dhblock_noauth_srv::repair_send_cb (dhash_stat err, bool something)
{
  if (err)
    warn << "error sending block\n";
}
void
dhblock_noauth_srv::repair_retrieve_cb (chordID dbkey,
					dhash_stat err,
					ptr<dhash_block> b,
					route r)
{
  if (err) {
    warn << "noauth: retrieve failed for repair of " << dbkey << "\n";
    return;
  }

  ptr<dbrec> d = New refcounted<dbrec> (b->data.cstr (), b->data.len ());
  dhblock_noauth_srv::store (dbkey, d);
}
<commit_msg>Use an unsigned for the hash, to avoid corner case of hash == long.min<commit_after>#include <chord.h>
#include <dhash.h>
#include <dhash_common.h>
#include "dhashcli.h"

#include "dhblock_noauth.h"
#include "dhblock_noauth_srv.h"
#include "dhblock_noauth.h"

#include "locationtable.h"
#include "location.h"

#include "merkle_tree.h"
#include "merkle_server.h"

// "fake" key to merkle on.. low 32 bits are hash of the block contents
ptr<dbrec>
dhblock_noauth_srv::get_merkle_key (chordID key, ptr<dbrec> data)
{

  assert (data);

  //get the low bits: xor of the marshalled words
  long *d = (long *)data->value;
  unsigned long hash = 0;
  for (int i = 0; i < data->len/4; i++)
    hash ^= d[i];

  if (hash < 0) hash = -hash;

  //mix the hash in with the low bytes
  chordID fkey = key >> 32;
  fkey = fkey << 32;
  chordID mkey = fkey | bigint(hash);

  //warn << "merkle key for " << key << " with data hash " << hash << " is " << mkey << "\n";
  return id2dbrec(mkey);
}

// key to store data under in the DB. Low 32-bits are zero
ptr<dbrec>
dhblock_noauth_srv::get_database_key (chordID key)
{

  //get a key with the low bits cleard out
  key = key >> 32;
  key = key << 32;
  assert (key > 0);  //assert that there were some high bits left
  ptr<dbrec> nk = id2dbrec (key);

  return nk;
}

dhblock_noauth_srv::dhblock_noauth_srv (ptr<vnode> node, str desc,
					str dbname, dbOptions opts) :
  dhblock_replicated_srv (node, desc, dbname, opts, DHASH_NOAUTH)
{

  // merkle state, don't populate from db
  mtree = New merkle_tree (db, false);

  //populate the merkle tree with appropriately bit-hacked keys
  ptr<dbEnumeration> it = db->enumerate ();
  ptr<dbPair> d = it->firstElement();
  for (int i = 0; d; i++, d = it->nextElement()) {
    if (i == 0)
      warn << "Database is not empty.  Loading into merkle tree\n";

    ptr<dbrec> data = db->lookup (d->key);
    assert (data);
    merkle_hash mkey = to_merkle_hash (get_merkle_key (dbrec2id(d->key), data));

    warn << "insert: " << dbrec2id(get_merkle_key (dbrec2id(d->key), data)) << " into merkle tree\n";

    mtree->insert (mkey);
  }

  // merkle state
  msrv = New merkle_server (mtree);

}

ptr<dbrec>
dhblock_noauth_srv::fetch (chordID k)
{
  ptr<dbrec> id = dhblock_noauth_srv::get_database_key (k);
  return db->lookup (id);
}

dhash_stat
dhblock_noauth_srv::store (chordID key, ptr<dbrec> new_data)
{
  dhash_stat stat (DHASH_OK);

  ptr<dbrec> dprep = merge_data (key, new_data);

  if (dprep) { //NULL unless new_data changed contents
    ptr<dbrec> kdb = dhblock_noauth_srv::get_database_key (key);
    ptr<dbrec> old_data = db->lookup (kdb);

    //put the key in the merkle tree; kick out the old key
    merkle_hash mkey;
    if (old_data) {
      mkey = to_merkle_hash (dhblock_noauth_srv::get_merkle_key (key, old_data));
      mtree->remove (mkey);
      db->del (kdb);
    }
    mkey = to_merkle_hash (dhblock_noauth_srv::get_merkle_key (key, dprep));
    mtree->insert (mkey);
    db->insert (kdb, dprep);

    warn << "db write: "
	 << " U " << key << " " << dprep->len << "\n";
  }
  return stat;
}

// add new_data to existing key
// returns NULL unless new_data added new sub-blocks
ptr<dbrec>
dhblock_noauth_srv::merge_data (chordID key, ptr<dbrec> new_data)
{

  vec<str> new_elems = dhblock_noauth::get_payload (new_data->value,
						    new_data->len);
  vec<str> old_elems;

  ptr<dbrec> kdb = dhblock_noauth_srv::get_database_key (key);
  ptr<dbrec> prev_data = db->lookup (kdb);
  if (prev_data)
    old_elems = dhblock_noauth::get_payload (prev_data->value, prev_data->len);

  qhash<bigint, bool, hashID> old_hashes;
  for (u_int i = 0; i < old_elems.size (); i++) {
    old_hashes.insert (compute_hash (old_elems[i].cstr (),
				     old_elems[i].len ()),
		       true);
  }

  u_int pre_merge_size = old_elems.size ();
  //look through the new data for sub blocks we don't have
  for (u_int i = 0; i < new_elems.size (); i++) {
    if (!old_hashes[compute_hash (new_elems[i].cstr (),
				  new_elems[i].len ())]) {
      //a new block, append it to old_elems
      old_elems.push_back (new_elems[i]);
    }
  }

  if (old_elems.size () == pre_merge_size) {
    return NULL;
  }

  //otherwise, delete the old data block and insert the new marshalled one
  str marshalled_block = dhblock_noauth::marshal_block (old_elems);

  ptr<dbrec> rec = New refcounted<dbrec> (marshalled_block.cstr (),
					  marshalled_block.len ());
  return rec;
}

void
dhblock_noauth_srv::bsmupdate (user_args *sbp, dhash_bsmupdate_arg *arg)
{

  if (arg->round_over) {
    //    warn << "sync round over\n";
  } else {
    /** XXX Should make sure that only called from localhost! */
    chord_node n = make_chord_node (arg->n);
    ptr<location> from = node->locations->lookup (n.x);
    if (from) {
      chordID dbkey = dbrec2id (dhblock_noauth_srv::get_database_key (arg->key));
      if (!arg->local) {
	//send our block to from
	warn << node->my_ID () << " sending " << dbkey << " to " << from->id () << "\n";
	cli->sendblock (from,  blockID (dbkey, DHASH_NOAUTH), db,
			wrap (this, &dhblock_noauth_srv::repair_send_cb));
      } else {
	warn << "getting " << dbkey << " from " << from << "\n";
	// get his block and call store?
	cli->retrieve (blockID (dbkey, DHASH_NOAUTH),
		       wrap (this, &dhblock_noauth_srv::repair_retrieve_cb,dbkey));

      }
    } else
      warn << "stale bsmupdate\n";
  }
  sbp->reply (NULL);
}

void
dhblock_noauth_srv::repair_send_cb (dhash_stat err, bool something)
{
  if (err)
    warn << "error sending block\n";
}
void
dhblock_noauth_srv::repair_retrieve_cb (chordID dbkey,
					dhash_stat err,
					ptr<dhash_block> b,
					route r)
{
  if (err) {
    warn << "noauth: retrieve failed for repair of " << dbkey << "\n";
    return;
  }

  ptr<dbrec> d = New refcounted<dbrec> (b->data.cstr (), b->data.len ());
  dhblock_noauth_srv::store (dbkey, d);
}
<|endoftext|>


<commit_before>/*
 *   karm
 *   This file only: Copyright (C) 1999  Espen Sand, espensa@online.no
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
 * $Id:
 * $Log:
 */

#include <qlabel.h>
#include <qlineedit.h>

#include <kapp.h>
#include <klocale.h>

#include "adddlg.h"

AddTaskDialog::AddTaskDialog( QWidget *parent, const char *name, bool modal )
  :KDialogBase( parent, name, modal, "task", Ok|Cancel, Ok, true )
{
  QWidget *page = new QWidget( this );
  setMainWidget(page);

  QGridLayout *topLayout = new QGridLayout( page, 2, 2, 0, spacingHint() );

  QString text = i18n("Task name");
  QLabel *label = new QLabel( text, page, "name" );
  topLayout->addWidget( label, 0, 0 );

  mTaskName = new QLineEdit( page, "lineedit" );
  mTaskName->setMinimumWidth(fontMetrics().maxWidth()*15);
  topLayout->addWidget( mTaskName, 0, 1 );

  text = i18n("Accumulated time\n(in minutes)");
  label = new QLabel( text, page, "time" );
  topLayout->addWidget( label, 1, 0 );

  mTaskTime = new QLineEdit( page, "lineedit" );
  mTaskTime->setMinimumWidth(fontMetrics().maxWidth()*15);
  topLayout->addWidget( mTaskTime, 1, 1 );
}

void AddTaskDialog::setTask( const QString &name, long time )
{
  mTaskName->setText( name );
  mTaskTime->setText( QString().setNum( time ) );
}

QString AddTaskDialog::taskName( void ) const
{
  return( mTaskName->text() );
}

long AddTaskDialog::taskTime( void ) const
{
  return( atol( mTaskTime->text().ascii()) );
}

void AddTaskDialog::slotOk( void )
{
  emit finished( true );
}

void AddTaskDialog::slotCancel( void )
{
  emit finished( false );
}
<commit_msg>	QLayout fixes..<commit_after>/*
 *   karm
 *   This file only: Copyright (C) 1999  Espen Sand, espensa@online.no
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
 * $Id:
 * $Log:
 */

#include <qlabel.h>
#include <qlineedit.h>
#include <qlayout.h>

#include <kapp.h>
#include <klocale.h>

#include "adddlg.h"

AddTaskDialog::AddTaskDialog( QWidget *parent, const char *name, bool modal )
  :KDialogBase( parent, name, modal, "task", Ok|Cancel, Ok, true )
{
  QWidget *page = new QWidget( this );
  setMainWidget(page);

  QGridLayout *topLayout = new QGridLayout( page, 2, 2, 0, spacingHint() );

  QString text = i18n("Task name");
  QLabel *label = new QLabel( text, page, "name" );
  topLayout->addWidget( label, 0, 0 );

  mTaskName = new QLineEdit( page, "lineedit" );
  mTaskName->setMinimumWidth(fontMetrics().maxWidth()*15);
  topLayout->addWidget( mTaskName, 0, 1 );

  text = i18n("Accumulated time\n(in minutes)");
  label = new QLabel( text, page, "time" );
  topLayout->addWidget( label, 1, 0 );

  mTaskTime = new QLineEdit( page, "lineedit" );
  mTaskTime->setMinimumWidth(fontMetrics().maxWidth()*15);
  topLayout->addWidget( mTaskTime, 1, 1 );
}

void AddTaskDialog::setTask( const QString &name, long time )
{
  mTaskName->setText( name );
  mTaskTime->setText( QString().setNum( time ) );
}

QString AddTaskDialog::taskName( void ) const
{
  return( mTaskName->text() );
}

long AddTaskDialog::taskTime( void ) const
{
  return( atol( mTaskTime->text().ascii()) );
}

void AddTaskDialog::slotOk( void )
{
  emit finished( true );
}

void AddTaskDialog::slotCancel( void )
{
  emit finished( false );
}
<|endoftext|>


<commit_before>//=====================================================================//
/*!	@file
	@brief	ファイル情報クラス
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "utils/file_info.hpp"
#include <dirent.h>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <iostream>

namespace utils {

	//-----------------------------------------------------------------//
	/*!
		@brief	ディレクトリーのファイルリストを作成
		@param[in]	root	ルート・パス
		@param[out]	list	ファイルリストを受け取るクラス
		@return リストの取得に失敗した場合「false」
	*/
	//-----------------------------------------------------------------//
	bool create_file_list(const std::string& root, file_infos& list)
	{
		if(root.empty()) return false;

#ifdef WIN32
		utils::wstring wsr;
		utf8_to_utf16(root, wsr);
		wchar_t* wtmp = new wchar_t[wsr.size() + 1];
		for(uint32_t i = 0; i < wsr.size(); ++i) {
			wtmp[i] = wsr[i];
		}
		wtmp[wsr.size()] = 0;
		_WDIR* dir = _wopendir(wtmp);
		delete[] wtmp;
#else
		DIR* dir = opendir(root.c_str());
#endif
		if(dir) {
#ifdef WIN32
			struct _wdirent* ent;
			while((ent = _wreaddir(dir)) != 0) {
				struct _stat st;
				utils::wstring fn;
				utf8_to_utf16(root, fn);
				fn += '/';
				{
					wchar_t wch;
					wchar_t* p = ent->d_name;
					while((wch = *p++) != 0) {
						fn += wch;
					}
				}
				wchar_t* wfn = new wchar_t[fn.size() + 1];
				for(uint32_t i = 0; i < fn.size(); ++i) {
					wfn[i] = fn[i];
				}
				wfn[fn.size()] = 0;
				if(ent->d_namlen > 0 && _wstat(wfn, &st) == 0) {
					bool d = S_ISDIR(st.st_mode);
					wstring ws;
					wchar_t wch;
					wchar_t* p = ent->d_name;
					while((wch = *p++) != 0) {
						ws += wch;
					}
					std::string s;
					utf16_to_utf8(ws, s);
					file_info info(s, d, st.st_size, st.st_mtime, st.st_mode);
					list.push_back(info);
				}
				delete[] wfn;
			}
			_wclosedir(dir);
#else
			struct dirent* ent;
			while((ent = readdir(dir)) != 0) {
				struct stat st;
				std::string fn = root;
				fn += '/';
				fn += ent->d_name;
				if(stat(fn.c_str(), &st) == 0) {
///					std::cout << fn << std::endl;
#ifdef __PPU__
					bool d = false;
					if(st.st_mode & CELL_FS_S_IFDIR) d = true;
#else
					bool d = S_ISDIR(st.st_mode);
#endif
					file_info info(ent->d_name, d, st.st_size, st.st_mtime, st.st_mode);
					list.push_back(info);
				}
			}
			closedir(dir);
#endif
			return true;
		} else {
			return false;
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	ファイル情報からフォーマットされた文字列を生成
		@param[in]	list	fileinfos クラス
		@param[in]	format	フォーマット（ディレクトリー出力専用形式）@n
							%s ---> ファイル名@n
							%n ---> ファイルサイズ@n
							%/ ---> ディレクトリーなら、'/'を追加
		@param[in]	dst		出力先列
	*/
	//-----------------------------------------------------------------//
	void create_format_file_infos(const file_infos& list, const std::string& format, utils::strings& dst)
	{
		BOOST_FOREACH(const file_info& fi, list) {
			if(format.empty()) {
				std::string s = fi.get_name();
				if(fi.is_directory()) s += '/';
				dst.push_back(s);
			} else {
				std::string s;
				char m = 0;
				BOOST_FOREACH(char c, format) {
					if(m) {
						if(c == '%') ;
						else if(c == 's' || c == 'S') {
							s += fi.get_name();
							c = 0;
						} else if(c == 'n') {
							s += boost::io::str(boost::format("%d") % fi.get_size());
							c = 0;
						} else if(c == '/') {
							if(!fi.is_directory()) c = 0;
						}
						m = 0;
					} else if(c == '%') {
						m = c;
						c = 0;
					}
					if(c) s += c;
				}
				dst.push_back(s);
			}
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	ファイル情報リストを正規表現フィルターで再構成
		@param[in]	src		fileinfos クラス
		@param[in]	filter	拡張子文字列
		@param[in]	cap	「false」なら大文字小文字を判定する
		@return		出力列
	*/
	//-----------------------------------------------------------------//
	file_infos filter_file_infos(const file_infos& src, const std::string& filter, bool cap)
	{
		file_infos dst;

		utils::strings ss;
		if(!filter.empty()) {
			ss = utils::split_text(filter, ",");
		}

		BOOST_FOREACH(const file_info& f, src) {
			bool add = false;
			if(f.is_directory() || ss.empty()) add = true;
			else {
				const std::string& n = f.get_name();
				BOOST_FOREACH(const std::string& s, ss) {
					const char* p = strrchr(n.c_str(), '.');
					if(p) {
						std::string ext(p + 1);
						if(cap) {
							if(s == ext) {
								add = true;
								break;
							}
						} else {
							if(utils::no_capital_strcmp(ext, s) == 0) {
								add = true;
								break;
							}
						}
					}
				}
			}
			if(add) dst.push_back(f);
		}
		return std::move(dst);
	}
}
<commit_msg>update drive latter path<commit_after>//=====================================================================//
/*!	@file
	@brief	ファイル情報クラス
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "utils/file_info.hpp"
#include <dirent.h>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <iostream>

namespace utils {

	//-----------------------------------------------------------------//
	/*!
		@brief	ディレクトリーのファイルリストを作成
		@param[in]	root	ルート・パス
		@param[out]	list	ファイルリストを受け取るクラス
		@return リストの取得に失敗した場合「false」
	*/
	//-----------------------------------------------------------------//
	bool create_file_list(const std::string& root, file_infos& list)
	{
		if(root.empty()) return false;

#ifdef WIN32
		utils::wstring wsr;
		utf8_to_utf16(root, wsr);
		if(!wsr.empty()) {
			// driver latter convert
			if(root[0] == '/' && ((root[1] >= 'A' && root[1] <= 'Z') || (root[1] >= 'a' && root[1] <= 'z')) && root[2] == '/') {
				wsr[0] = wsr[1];
				wsr[1] = ':';
			}
		}
		wchar_t* wtmp = new wchar_t[wsr.size() + 1];
		for(uint32_t i = 0; i < wsr.size(); ++i) {
			wtmp[i] = wsr[i];
		}
		wtmp[wsr.size()] = 0;
		_WDIR* dir = _wopendir(wtmp);
		delete[] wtmp;
#else
		DIR* dir = opendir(root.c_str());
#endif
		if(dir) {
#ifdef WIN32
			struct _wdirent* ent;
			while((ent = _wreaddir(dir)) != 0) {
				struct _stat st;
				utils::wstring fn;
				utf8_to_utf16(root, fn);
				fn += '/';
				{
					wchar_t wch;
					wchar_t* p = ent->d_name;
					while((wch = *p++) != 0) {
						fn += wch;
					}
				}
				wchar_t* wfn = new wchar_t[fn.size() + 1];
				for(uint32_t i = 0; i < fn.size(); ++i) {
					wfn[i] = fn[i];
				}
				wfn[fn.size()] = 0;
				if(ent->d_namlen > 0 && _wstat(wfn, &st) == 0) {
					bool d = S_ISDIR(st.st_mode);
					wstring ws;
					wchar_t wch;
					wchar_t* p = ent->d_name;
					while((wch = *p++) != 0) {
						ws += wch;
					}
					std::string s;
					utf16_to_utf8(ws, s);
					file_info info(s, d, st.st_size, st.st_mtime, st.st_mode);
					list.push_back(info);
				}
				delete[] wfn;
			}
			_wclosedir(dir);
#else
			struct dirent* ent;
			while((ent = readdir(dir)) != 0) {
				struct stat st;
				std::string fn = root;
				fn += '/';
				fn += ent->d_name;
				if(stat(fn.c_str(), &st) == 0) {
///					std::cout << fn << std::endl;
#ifdef __PPU__
					bool d = false;
					if(st.st_mode & CELL_FS_S_IFDIR) d = true;
#else
					bool d = S_ISDIR(st.st_mode);
#endif
					file_info info(ent->d_name, d, st.st_size, st.st_mtime, st.st_mode);
					list.push_back(info);
				}
			}
			closedir(dir);
#endif
			return true;
		} else {
			return false;
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	ファイル情報からフォーマットされた文字列を生成
		@param[in]	list	fileinfos クラス
		@param[in]	format	フォーマット（ディレクトリー出力専用形式）@n
							%s ---> ファイル名@n
							%n ---> ファイルサイズ@n
							%/ ---> ディレクトリーなら、'/'を追加
		@param[in]	dst		出力先列
	*/
	//-----------------------------------------------------------------//
	void create_format_file_infos(const file_infos& list, const std::string& format, utils::strings& dst)
	{
		BOOST_FOREACH(const file_info& fi, list) {
			if(format.empty()) {
				std::string s = fi.get_name();
				if(fi.is_directory()) s += '/';
				dst.push_back(s);
			} else {
				std::string s;
				char m = 0;
				BOOST_FOREACH(char c, format) {
					if(m) {
						if(c == '%') ;
						else if(c == 's' || c == 'S') {
							s += fi.get_name();
							c = 0;
						} else if(c == 'n') {
							s += boost::io::str(boost::format("%d") % fi.get_size());
							c = 0;
						} else if(c == '/') {
							if(!fi.is_directory()) c = 0;
						}
						m = 0;
					} else if(c == '%') {
						m = c;
						c = 0;
					}
					if(c) s += c;
				}
				dst.push_back(s);
			}
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	ファイル情報リストを正規表現フィルターで再構成
		@param[in]	src		fileinfos クラス
		@param[in]	filter	拡張子文字列
		@param[in]	cap	「false」なら大文字小文字を判定する
		@return		出力列
	*/
	//-----------------------------------------------------------------//
	file_infos filter_file_infos(const file_infos& src, const std::string& filter, bool cap)
	{
		file_infos dst;

		utils::strings ss;
		if(!filter.empty()) {
			ss = utils::split_text(filter, ",");
		}

		BOOST_FOREACH(const file_info& f, src) {
			bool add = false;
			if(f.is_directory() || ss.empty()) add = true;
			else {
				const std::string& n = f.get_name();
				BOOST_FOREACH(const std::string& s, ss) {
					const char* p = strrchr(n.c_str(), '.');
					if(p) {
						std::string ext(p + 1);
						if(cap) {
							if(s == ext) {
								add = true;
								break;
							}
						} else {
							if(utils::no_capital_strcmp(ext, s) == 0) {
								add = true;
								break;
							}
						}
					}
				}
			}
			if(add) dst.push_back(f);
		}
		return std::move(dst);
	}
}
<|endoftext|>


<commit_before>#include "AnimSprLoader.h"

#include <sprite2/AnimSprite.h>

namespace glue
{

AnimSprLoader::AnimSprLoader(s2::AnimSprite* spr)
	: m_spr(spr)
{
	if (m_spr) {
		m_spr->AddReference();
	}
}

AnimSprLoader::~AnimSprLoader()
{
	if (m_spr) {
		m_spr->RemoveReference();
	}
}

void AnimSprLoader::LoadJson(const Json::Value& val, const std::string& dir)
{
	if (!m_spr || val["animation"].isNull()) {
		return;
	}

	const Json::Value& anim_val = val["animation"];

	m_spr->SetLoop(anim_val["loop"].asBool());
	m_spr->SetInterval(anim_val["interval"].asDouble());

	m_spr->SetFPS(anim_val["fps"].asInt());

	m_spr->SetActive(anim_val["active"].asBool());
}

}<commit_msg>fix anim loader<commit_after>#include "AnimSprLoader.h"

#include <sprite2/AnimSprite.h>

namespace glue
{

AnimSprLoader::AnimSprLoader(s2::AnimSprite* spr)
	: m_spr(spr)
{
	if (m_spr) {
		m_spr->AddReference();
	}
}

AnimSprLoader::~AnimSprLoader()
{
	if (m_spr) {
		m_spr->RemoveReference();
	}
}

void AnimSprLoader::LoadJson(const Json::Value& val, const std::string& dir)
{
	if (!m_spr || val["animation"].isNull()) {
		return;
	}

	const Json::Value& anim_val = val["animation"];

	m_spr->SetLoop(anim_val["loop"].asBool());
	m_spr->SetInterval(anim_val["interval"].asDouble());

	m_spr->SetFPS(anim_val["fps"].asInt());

	if (anim_val.isMember("active")) {
		m_spr->SetActive(anim_val["active"].asBool());
	}
}

}<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <boost/thread.hpp>

#include "bcm_host.h"
extern "C" {
#include "ilclient.h"
}

static int video_decode_test(const char *filename, int x_offset, int y_offset, int width, int height) {
  OMX_VIDEO_PARAM_PORTFORMATTYPE format;
  COMPONENT_T *video_decode = NULL, *video_render = NULL;
  COMPONENT_T * list[3];
  TUNNEL_T tunnel[2];
  ILCLIENT_T *client;
  FILE *in;
  int status = 0;
  unsigned int data_len = 0;

  memset(list, 0, sizeof (list));
  memset(tunnel, 0, sizeof (tunnel));

  if ((in = fopen(filename, "rb")) == NULL)
    return -2;

  if ((client = ilclient_init()) == NULL) {
    fclose(in);
    return -3;
  }

  if (OMX_Init() != OMX_ErrorNone) {
    ilclient_destroy(client);
    fclose(in);
    return -4;
  }

  // create video_decode
  if (ilclient_create_component(client, &video_decode, "video_decode", (ILCLIENT_CREATE_FLAGS_T) (ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0)
    status = -14;
  list[0] = video_decode;

  // create video_render
  if (status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
    status = -14;
  list[1] = video_render;

  // Set up ROI
  OMX_CONFIG_DISPLAYREGIONTYPE configDisplay;
  memset(&configDisplay, 0, sizeof (OMX_CONFIG_DISPLAYREGIONTYPE));
  configDisplay.nSize = sizeof (OMX_CONFIG_DISPLAYREGIONTYPE);
  configDisplay.nVersion.nVersion = OMX_VERSION;
  configDisplay.nPortIndex = 90;
  configDisplay.fullscreen = OMX_FALSE;
  configDisplay.noaspect = OMX_TRUE;
  configDisplay.set = (OMX_DISPLAYSETTYPE) (OMX_DISPLAY_SET_DEST_RECT | OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_NOASPECT);
  configDisplay.dest_rect.x_offset = x_offset;
  configDisplay.dest_rect.y_offset = y_offset;
  configDisplay.dest_rect.width = width;
  configDisplay.dest_rect.height = height;

  OMX_SetParameter(ILC_GET_HANDLE(video_render), OMX_IndexConfigDisplayRegion, &configDisplay);

  set_tunnel(tunnel, video_decode, 131, video_render, 90);

  if (status == 0)
    ilclient_change_component_state(video_decode, OMX_StateIdle);

  memset(&format, 0, sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE));
  format.nSize = sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE);
  format.nVersion.nVersion = OMX_VERSION;
  format.nPortIndex = 130;
  format.eCompressionFormat = OMX_VIDEO_CodingAVC;

  if (status == 0 &&
          OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
          ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) {
    OMX_BUFFERHEADERTYPE *buf;
    int port_settings_changed = 0;
    int first_packet = 1;

    ilclient_change_component_state(video_decode, OMX_StateExecuting);

    while ((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) {
      // feed data and wait until we get port settings changed
      unsigned char *dest = buf->pBuffer;

      data_len += fread(dest, 1, buf->nAllocLen - data_len, in);

      if (port_settings_changed == 0 &&
              ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) ||
              (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1,
              ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) {
        port_settings_changed = 1;

        if (ilclient_setup_tunnel(tunnel, 0, 0) != 0) {
          status = -7;
          break;
        }

        ilclient_change_component_state(video_render, OMX_StateExecuting);
      }
      if (!data_len)
        break;

      buf->nFilledLen = data_len;
      data_len = 0;

      buf->nOffset = 0;
      if (first_packet) {
        buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
        first_packet = 0;
      } else
        buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;

      if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) {
        status = -6;
        break;
      }
    }

    buf->nFilledLen = 0;
    buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;

    if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
      status = -20;

    // wait for EOS from render
    ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
            ILCLIENT_BUFFER_FLAG_EOS, 10000);

    // need to flush the renderer to allow video_decode to disable its input port
    ilclient_flush_tunnels(tunnel, 0);

  }

  fclose(in);

  ilclient_disable_tunnel(tunnel);
  ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
  ilclient_teardown_tunnels(tunnel);

  ilclient_state_transition(list, OMX_StateIdle);
  ilclient_state_transition(list, OMX_StateLoaded);

  ilclient_cleanup_components(list);

  OMX_Deinit();

  ilclient_destroy(client);
  return status;
}

int main(int argc, char **argv) {
  bcm_host_init();

  int width = 1920;
  int height = 1080;
  int cols = 2;
  int rows = 2;

  boost::thread_group g;

  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {
      int xoff = x * (width / cols);
      int yoff = y * (height / rows);

      g.create_thread(boost::bind(video_decode_test, "video-LQ-640.h264", xoff, yoff, width / cols, height / rows));
    }
  }
  g.join_all();
}

<commit_msg>Display 12 videos, but only 9 show up<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <boost/thread.hpp>

#include "bcm_host.h"
extern "C" {
#include "ilclient.h"
}

static char const *err2str(int err) {
  switch (err) {
    case OMX_ErrorInsufficientResources: return "OMX_ErrorInsufficientResources";
    case OMX_ErrorUndefined: return "OMX_ErrorUndefined";
    case OMX_ErrorInvalidComponentName: return "OMX_ErrorInvalidComponentName";
    case OMX_ErrorComponentNotFound: return "OMX_ErrorComponentNotFound";
    case OMX_ErrorInvalidComponent: return "OMX_ErrorInvalidComponent";
    case OMX_ErrorBadParameter: return "OMX_ErrorBadParameter";
    case OMX_ErrorNotImplemented: return "OMX_ErrorNotImplemented";
    case OMX_ErrorUnderflow: return "OMX_ErrorUnderflow";
    case OMX_ErrorOverflow: return "OMX_ErrorOverflow";
    case OMX_ErrorHardware: return "OMX_ErrorHardware";
    case OMX_ErrorInvalidState: return "OMX_ErrorInvalidState";
    case OMX_ErrorStreamCorrupt: return "OMX_ErrorStreamCorrupt";
    case OMX_ErrorPortsNotCompatible: return "OMX_ErrorPortsNotCompatible";
    case OMX_ErrorResourcesLost: return "OMX_ErrorResourcesLost";
    case OMX_ErrorNoMore: return "OMX_ErrorNoMore";
    case OMX_ErrorVersionMismatch: return "OMX_ErrorVersionMismatch";
    case OMX_ErrorNotReady: return "OMX_ErrorNotReady";
    case OMX_ErrorTimeout: return "OMX_ErrorTimeout";
    case OMX_ErrorSameState: return "OMX_ErrorSameState";
    case OMX_ErrorResourcesPreempted: return "OMX_ErrorResourcesPreempted";
    case OMX_ErrorPortUnresponsiveDuringAllocation: return "OMX_ErrorPortUnresponsiveDuringAllocation";
    case OMX_ErrorPortUnresponsiveDuringDeallocation: return "OMX_ErrorPortUnresponsiveDuringDeallocation";
    case OMX_ErrorPortUnresponsiveDuringStop: return "OMX_ErrorPortUnresponsiveDuringStop";
    case OMX_ErrorIncorrectStateTransition: return "OMX_ErrorIncorrectStateTransition";
    case OMX_ErrorIncorrectStateOperation: return "OMX_ErrorIncorrectStateOperation";
    case OMX_ErrorUnsupportedSetting: return "OMX_ErrorUnsupportedSetting";
    case OMX_ErrorUnsupportedIndex: return "OMX_ErrorUnsupportedIndex";
    case OMX_ErrorBadPortIndex: return "OMX_ErrorBadPortIndex";
    case OMX_ErrorPortUnpopulated: return "OMX_ErrorPortUnpopulated";
    case OMX_ErrorComponentSuspended: return "OMX_ErrorComponentSuspended";
    case OMX_ErrorDynamicResourcesUnavailable: return "OMX_ErrorDynamicResourcesUnavailable";
    case OMX_ErrorMbErrorsInFrame: return "OMX_ErrorMbErrorsInFrame";
    case OMX_ErrorFormatNotDetected: return "OMX_ErrorFormatNotDetected";
    case OMX_ErrorContentPipeOpenFailed: return "OMX_ErrorContentPipeOpenFailed";
    case OMX_ErrorContentPipeCreationFailed: return "OMX_ErrorContentPipeCreationFailed";
    case OMX_ErrorSeperateTablesUsed: return "OMX_ErrorSeperateTablesUsed";
    case OMX_ErrorTunnelingUnsupported: return "OMX_ErrorTunnelingUnsupported";
    default: return "unknown error";
  }
}

static void error_callback(void *userdata, COMPONENT_T *comp, OMX_U32 data) {
  fprintf(stderr, "OMX error %s\n", err2str(data));
}

static int video_decode_test(int i, const char *filename, int x_offset, int y_offset, int width, int height) {
  OMX_VIDEO_PARAM_PORTFORMATTYPE format;
  COMPONENT_T *video_decode = NULL, *video_render = NULL;
  COMPONENT_T * list[3];
  TUNNEL_T tunnel[2];
  ILCLIENT_T *client;
  FILE *in;
  int status = 0;
  unsigned int data_len = 0;

  memset(list, 0, sizeof (list));
  memset(tunnel, 0, sizeof (tunnel));

  if ((in = fopen(filename, "rb")) == NULL)
    return -2;

  if ((client = ilclient_init()) == NULL) {
    fclose(in);
    return -3;
  }

  if (OMX_Init() != OMX_ErrorNone) {
    ilclient_destroy(client);
    fclose(in);
    return -4;
  }

  ilclient_set_error_callback(client, error_callback, NULL);

  // create video_decode
  if (ilclient_create_component(client, &video_decode, "video_decode", (ILCLIENT_CREATE_FLAGS_T) (ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0)
    status = -14;
  list[0] = video_decode;

  // create video_render
  if (status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
    status = -14;
  list[1] = video_render;

  // Set up ROI
  OMX_CONFIG_DISPLAYREGIONTYPE configDisplay;
  memset(&configDisplay, 0, sizeof (OMX_CONFIG_DISPLAYREGIONTYPE));
  configDisplay.nSize = sizeof (OMX_CONFIG_DISPLAYREGIONTYPE);
  configDisplay.nVersion.nVersion = OMX_VERSION;
  configDisplay.nPortIndex = 90;
  configDisplay.fullscreen = OMX_FALSE;
  configDisplay.noaspect = OMX_TRUE;
  configDisplay.set = (OMX_DISPLAYSETTYPE) (OMX_DISPLAY_SET_DEST_RECT | OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_NOASPECT);
  configDisplay.dest_rect.x_offset = x_offset;
  configDisplay.dest_rect.y_offset = y_offset;
  configDisplay.dest_rect.width = width;
  configDisplay.dest_rect.height = height;

  if (OMX_SetParameter(ILC_GET_HANDLE(video_render), OMX_IndexConfigDisplayRegion, &configDisplay) != OMX_ErrorNone) {
    printf("OMX_GetParameter failed\n");
  }

  set_tunnel(tunnel, video_decode, 131, video_render, 90);

  if (status == 0)
    ilclient_change_component_state(video_decode, OMX_StateIdle);

  memset(&format, 0, sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE));
  format.nSize = sizeof (OMX_VIDEO_PARAM_PORTFORMATTYPE);
  format.nVersion.nVersion = OMX_VERSION;
  format.nPortIndex = 130;
  format.eCompressionFormat = OMX_VIDEO_CodingAVC;

  if (OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) != OMX_ErrorNone) {
    printf("OMX_SetParameter OMX_IndexParamVideoPortFormat failed\n");
  }

  OMX_PARAM_PORTDEFINITIONTYPE portdef;
  portdef.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
  portdef.nVersion.nVersion = OMX_VERSION;
  portdef.nPortIndex = 130;
  if (OMX_GetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamPortDefinition, &portdef) == OMX_ErrorNone) {
    printf("OMX_GetParameter\n");
    portdef.nBufferCountActual = portdef.nBufferCountMin;
    portdef.nBufferSize = 4 * 1024;
    if (OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamPortDefinition, &portdef) != OMX_ErrorNone) {
      printf("OMX_SetParameter error\n");
    }
  }

  printf("%d ilclient_enable_port_buffers\n", i);
  if (status == 0 && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) {
    OMX_BUFFERHEADERTYPE *buf;
    int port_settings_changed = 0;
    int first_packet = 1;

    printf("%d ilclient_change_component_state\n", i);
    ilclient_change_component_state(video_decode, OMX_StateExecuting);

    printf("%d ilclient_get_input_buffer\n", i);
    while ((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) {
      // feed data and wait until we get port settings changed
      unsigned char *dest = buf->pBuffer;

      data_len += fread(dest, 1, buf->nAllocLen - data_len, in);

      if (port_settings_changed == 0 &&
              ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) ||
              (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1,
              ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) {
        port_settings_changed = 1;
        printf("%d port_settings_changed\n", i);
        if (ilclient_setup_tunnel(tunnel, 0, 0) != 0) {
          status = -7;
          break;
        }

        ilclient_change_component_state(video_render, OMX_StateExecuting);
      }
      if (!data_len)
        break;

      buf->nFilledLen = data_len;
      data_len = 0;

      buf->nOffset = 0;
      if (first_packet) {
        buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
        first_packet = 0;
      } else
        buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;

      if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) {
        status = -6;
        break;
      }
    }

    buf->nFilledLen = 0;
    buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;

    if (OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
      status = -20;

    // wait for EOS from render
    ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
            ILCLIENT_BUFFER_FLAG_EOS, 10000);

    // need to flush the renderer to allow video_decode to disable its input port
    ilclient_flush_tunnels(tunnel, 0);

  }

  fclose(in);

  ilclient_disable_tunnel(tunnel);
  ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
  ilclient_teardown_tunnels(tunnel);

  ilclient_state_transition(list, OMX_StateIdle);
  ilclient_state_transition(list, OMX_StateLoaded);

  ilclient_cleanup_components(list);

  OMX_Deinit();

  ilclient_destroy(client);
  return status;
}

int main() {
  bcm_host_init();

  int width = 1920;
  int height = 1080;
  int cols = 4;
  int rows = 3;

  boost::thread_group g;

  int i = 1;
  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {
      int xoff = x * (width / cols);
      int yoff = y * (height / rows);

      g.create_thread(boost::bind(video_decode_test, i, "video-LQ-640.h264", xoff, yoff, width / cols, height / rows));
      usleep(1000 * 100);
      i++;
    }
  }
  g.join_all();
}

<|endoftext|>


<commit_before>/*
 * labyrinth.cpp
 *
 *  Created on: 15.01.2015 г.
 *      Author: trifon
 */

#include <iostream>
using namespace std;

const int MAX = 100;

char labyrinth[MAX][MAX];
int m, n;

void readLabyrinth() {
	cin >> m >> n;
	cin.ignore();
	for(int i = 0; i < m; i++)
		cin.getline(labyrinth[i], n + 2);
}

void printLabyrinth() {
	for(int i = 0; i < m; i++)
		cout << labyrinth[i] << endl;
}

void findStart(int& x, int& y) {
	for(int i = 0; i < m; i++)
		for(int j = 0; j < n; j++)
			if (labyrinth[i][j] == 'o') {
				x = i;
				y = j;
				return;
			}
}

int main() {
	readLabyrinth();
	printLabyrinth();
	int startx, starty;
	findStart(startx, starty);
	cout << "Започваме от " << "("
			<< startx << "," << starty << ")\n";
	return 0;
}

<commit_msg>Първи вариант на търсене на съкровище: не работи!<commit_after>/*
 * labyrinth.cpp
 *
 *  Created on: 15.01.2015 г.
 *      Author: trifon
 */

#include <iostream>
using namespace std;

const int MAX = 100;

char labyrinth[MAX][MAX];
int m, n;

void readLabyrinth() {
	cin >> m >> n;
	cin.ignore();
	for(int i = 0; i < m; i++)
		cin.getline(labyrinth[i], n + 2);
}

void printLabyrinth() {
	for(int i = 0; i < m; i++)
		cout << labyrinth[i] << endl;
}

void findStart(int& x, int& y) {
	for(int i = 0; i < m; i++)
		for(int j = 0; j < n; j++)
			if (labyrinth[i][j] == 'o') {
				x = i;
				y = j;
				return;
			}
}

// findTreasure(x, y) == true <->
//          можем от (x, y) да достигнем до съкровището
bool findTreasure(int x, int y) {
	if (labyrinth[x][y] == '$') {
		// лесен хубав случай
		cout << "Намерихме съкровището на (" << x <<
				"," << y << ")!\n";
		return true;
	}
	if (labyrinth[x][y] == '*')
		// лесен лош случай
		return false;
	// стъпка надолу
	if (findTreasure(x + 1, y))
		return true;
	// стъпка нагоре
	if (findTreasure(x - 1, y))
		return true;
	// стъпка наляво
	if (findTreasure(x, y - 1))
		return true;
	// стъпка надясно
	if (findTreasure(x, y + 1))
		return true;
	return false;
}

int main() {
	readLabyrinth();
	printLabyrinth();
	int startx, starty;
	findStart(startx, starty);
	cout << "Започваме от " << "("
			<< startx << "," << starty << ")\n";
	cout << findTreasure(startx, starty) << endl;
	printLabyrinth();
	return 0;
}

<|endoftext|>


<commit_before>#include <omp.h>

#include "measure_omp.h"
#include "wall_clock.h"

void measureOmpOneMutex()
{
    // Measure time for incrementing doubles as ground truth.
    {
        volatile int x = 0;
        double start = sysTime();
        for (int i = 0; i < REPETITIONS; ++i) {
            x += i;
        }
        double end = sysTime();

        printf("%d int sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for using OpenMP atomic operation for the addition.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            #pragma omp atomic
            x += i;
        }
        double end = sysTime();

        printf("%d double atomic sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for using atomic operation for the addition.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            __sync_fetch_and_add(&x, i);
        }
        double end = sysTime();

        printf("%d double atomic sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for lock/unlock pairs.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            #pragma omp critical
            {
                x += i;
            }
        }
        double end = sysTime();

        printf("%d critical sum pairs: %f s\n", REPETITIONS, end - start);
    }
}

void measureOmp()
{
    std::cout << "Measuring for OpenMP\n\n";

    measureOmpOneMutex();

    std::cout << "\n\n";
}

<commit_msg>Manual OpenMP locks added.<commit_after>#include <omp.h>

#include "measure_omp.h"
#include "wall_clock.h"

void measureOmpOneMutex()
{
    // Measure time for incrementing doubles as ground truth.
    {
        volatile int x = 0;
        double start = sysTime();
        for (int i = 0; i < REPETITIONS; ++i) {
            x += i;
        }
        double end = sysTime();

        printf("%d int sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for using OpenMP atomic operation for the addition.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            #pragma omp atomic
            x += i;
        }
        double end = sysTime();

        printf("%d double atomic sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for using atomic operation for the addition.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            __sync_fetch_and_add(&x, i);
        }
        double end = sysTime();

        printf("%d double atomic sum: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for lock/unlock pairs.
    {
        volatile int x = 0;
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            #pragma omp critical
            {
                x += i;
            }
        }
        double end = sysTime();

        printf("%d critical sum pairs: %f s\n", REPETITIONS, end - start);
    }

    // Measure time for explicit lock/unlock pairs.
    {
        volatile int x = 0;
        omp_lock_t lock;
        omp_init_lock(&lock);
        double start = sysTime();
        omp_set_num_threads(1);
        #pragma omp parallel for
        for (int i = 0; i < REPETITIONS; ++i) {
            omp_set_lock(&lock);
            x += 1;
            omp_unset_lock(&lock);
        }
        double end = sysTime();
        omp_destroy_lock(&lock);

        printf("%d critical sum pairs: %f s\n", REPETITIONS, end - start);
    }
}

void measureOmp()
{
    std::cout << "Measuring for OpenMP\n\n";

    measureOmpOneMutex();

    std::cout << "\n\n";
}

<|endoftext|>


<commit_before>//===-- SerialQueue.cpp ---------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/Basic/SerialQueue.h"

#include <condition_variable>
#include <deque>
#include <mutex>
#include <thread>

using namespace llbuild;
using namespace llbuild::basic;

namespace {

/// A basic serial queue.
///
/// This implementation has been optimized for simplicity over performance.
//
// FIXME: Optimize.
class SerialQueueImpl {
  /// The thread executing the operations.
  std::unique_ptr<std::thread> operationsThread;

  /// The queue of operations.
  std::deque<std::function<void(void)>> operations;

  /// The mutex protecting access to the queue.
  std::mutex operationsMutex;

  /// Condition variable used to signal when operations are available.
  std::condition_variable readyOperationsCondition;

  /// Thread function to execute operations.
  void run() {
    while (true) {
      // Get the next operation from the queue.
      std::function<void(void)> fn;
      {
        std::unique_lock<std::mutex> lock(operationsMutex);

        // While the queue is empty, wait for an item.
        while (operations.empty()) {
          readyOperationsCondition.wait(lock);
        }

        fn = operations.front();
        operations.pop_front();
      }

      // If we got a nil function, the queue is shutting down.
      if (!fn)
        break;

      // Execute the operation.
      fn();
    }
  }

  void addOperation(std::function<void(void)>&& fn) {
    std::lock_guard<std::mutex> guard(operationsMutex);
    operations.push_back(fn);
    readyOperationsCondition.notify_one();
  }

public:
  SerialQueueImpl() {
    // Ensure the queue is fully initialized before creating the worker thread.
    operationsThread = std::make_unique<std::thread>(
        &SerialQueueImpl::run, this);
  }

  ~SerialQueueImpl() {
    // Signal the worker to shut down.
    addOperation({});

    // Wait for the worker to complete.
    operationsThread->join();
  }

  void sync(std::function<void(void)> fn) {
    assert(fn);

    // Add an operation which will execute the function and signal its
    // completion.
    std::condition_variable cv{};
    std::mutex isCompleteMutex{};
    bool isComplete = false;
    addOperation([&]() {
        fn();
        {
          std::unique_lock<std::mutex> lock(isCompleteMutex);
          isComplete = true;
          cv.notify_one();
        }
      });

    // Wait for the operation to complete.
    while (true) {
      std::unique_lock<std::mutex> lock(isCompleteMutex);
      if (!isComplete) {
        cv.wait(lock);
      }
      if (isComplete)
        break;
    }
  }

  void async(std::function<void(void)> fn) {
    assert(fn);

    // Add the operation.
    addOperation(std::move(fn));
  }
};

}

SerialQueue::SerialQueue()
    : impl(new SerialQueueImpl())
{
}

SerialQueue::~SerialQueue() {
  delete static_cast<SerialQueueImpl*>(impl);
}

void SerialQueue::sync(std::function<void(void)> fn) {
  static_cast<SerialQueueImpl*>(impl)->sync(fn);
}

void SerialQueue::async(std::function<void(void)> fn) {
  static_cast<SerialQueueImpl*>(impl)->async(fn);
}
<commit_msg>[Basic] Simplify SerialQueue::sync()'s wait.<commit_after>//===-- SerialQueue.cpp ---------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/Basic/SerialQueue.h"

#include <condition_variable>
#include <deque>
#include <mutex>
#include <thread>

using namespace llbuild;
using namespace llbuild::basic;

namespace {

/// A basic serial queue.
///
/// This implementation has been optimized for simplicity over performance.
//
// FIXME: Optimize.
class SerialQueueImpl {
  /// The thread executing the operations.
  std::unique_ptr<std::thread> operationsThread;

  /// The queue of operations.
  std::deque<std::function<void(void)>> operations;

  /// The mutex protecting access to the queue.
  std::mutex operationsMutex;

  /// Condition variable used to signal when operations are available.
  std::condition_variable readyOperationsCondition;

  /// Thread function to execute operations.
  void run() {
    while (true) {
      // Get the next operation from the queue.
      std::function<void(void)> fn;
      {
        std::unique_lock<std::mutex> lock(operationsMutex);

        // While the queue is empty, wait for an item.
        while (operations.empty()) {
          readyOperationsCondition.wait(lock);
        }

        fn = operations.front();
        operations.pop_front();
      }

      // If we got a nil function, the queue is shutting down.
      if (!fn)
        break;

      // Execute the operation.
      fn();
    }
  }

  void addOperation(std::function<void(void)>&& fn) {
    std::lock_guard<std::mutex> guard(operationsMutex);
    operations.push_back(fn);
    readyOperationsCondition.notify_one();
  }

public:
  SerialQueueImpl() {
    // Ensure the queue is fully initialized before creating the worker thread.
    operationsThread = std::make_unique<std::thread>(
        &SerialQueueImpl::run, this);
  }

  ~SerialQueueImpl() {
    // Signal the worker to shut down.
    addOperation({});

    // Wait for the worker to complete.
    operationsThread->join();
  }

  void sync(std::function<void(void)> fn) {
    assert(fn);

    // Add an operation which will execute the function and signal its
    // completion.
    std::condition_variable cv{};
    std::mutex isCompleteMutex{};
    bool isComplete = false;
    addOperation([&]() {
        fn();
        {
          std::unique_lock<std::mutex> lock(isCompleteMutex);
          isComplete = true;
          cv.notify_one();
        }
      });

    // Wait for the operation to complete.
    std::unique_lock<std::mutex> lock(isCompleteMutex);
    while (!isComplete) {
      cv.wait(lock);
    }
  }

  void async(std::function<void(void)> fn) {
    assert(fn);

    // Add the operation.
    addOperation(std::move(fn));
  }
};

}

SerialQueue::SerialQueue()
    : impl(new SerialQueueImpl())
{
}

SerialQueue::~SerialQueue() {
  delete static_cast<SerialQueueImpl*>(impl);
}

void SerialQueue::sync(std::function<void(void)> fn) {
  static_cast<SerialQueueImpl*>(impl)->sync(fn);
}

void SerialQueue::async(std::function<void(void)> fn) {
  static_cast<SerialQueueImpl*>(impl)->async(fn);
}
<|endoftext|>


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

#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/AutoTransform>
#include <osg/Geometry>

#include <osgText/Text>

#include <iostream>

osg::Node* createLabel(const osg::Vec3& pos, float size, const std::string& label, osgText::Text::AxisAlignment axisAlignment)
{
    osg::Geode* geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(pos);
        text->setCharacterSize(size);
        text->setAxisAlignment(axisAlignment);
        text->setAlignment(osgText::Text::CENTER_CENTER);
        text->setText(label);

    }

    return geode;
}

osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& label)
{
    osg::Geode* geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(pos);
        text->setFontResolution(40,40);
        text->setCharacterSize(size);
        text->setAlignment(osgText::Text::CENTER_CENTER);
        text->setAutoRotateToScreen(true);
        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
        text->setText(label);

    }

    return geode;
}

osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps, osg::AutoTransform::AutoRotateMode autoRotateMode, osgText::Text::AxisAlignment axisAlignment, const std::string& str)
{
    osg::Group* group = new osg::Group;

    osg::Vec3 dv = e-s;
    dv /= float(numReps-1);

    osg::Vec3 pos = s;

    bool useAuto = true;
    if (useAuto)
    {
        osg::Vec3Array* vertices = new osg::Vec3Array;

        for(int i=0;i<numReps;++i)
        {
            osg::AutoTransform* at = new osg::AutoTransform;
            at->setPosition(pos);
            at->setAutoRotateMode(autoRotateMode);
            at->addChild(createLabel(osg::Vec3(0.0f,0.0f,0.0f),dv.length()*0.2f,str, axisAlignment));
            vertices->push_back(pos);
            pos += dv;

            group->addChild(at);
        }

        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

        osg::Geometry* geom = new osg::Geometry;
        geom->setVertexArray(vertices);
        geom->setColorArray(colors);
        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));

        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geom);

        group->addChild(geode);
    }
    else
    {
        osg::Vec3Array* vertices = new osg::Vec3Array;

        for(int i=0;i<numReps;++i)
        {
            group->addChild(createLabel3(osg::Vec3(pos),dv.length()*0.5f,str));
            vertices->push_back(pos);
            pos += dv;

        }

        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

        osg::Geometry* geom = new osg::Geometry;
        geom->setVertexArray(vertices);
        geom->setColorArray(colors);
        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));

        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geom);

        group->addChild(geode);
    }

    return group;
}

osg::Node* createScene()
{
    osg::Group* root = new osg::Group;

//    int numReps = 3333;
    int numReps = 10;
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(1000.0,0.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_CAMERA,osgText::Text::XY_PLANE, "ROTATE_TO_CAMERA"));
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,1000.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_SCREEN,osgText::Text::XY_PLANE, "ROTATE_TO_SCREEN"));
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,0.0,1000.0),numReps,osg::AutoTransform::NO_ROTATION,osgText::Text::XZ_PLANE, "NO_ROTATION"));

    return root;
}

int main(int, char**)
{
    // construct the viewer.
    osgViewer::Viewer viewer;

    // set the scene to render
    viewer.setSceneData(createScene());

    // run the viewers frame loop
    return viewer.run();
}
<commit_msg>Added example code showing how to set the minimum and maximum scales<commit_after>/* OpenSceneGraph example, osgautotransform.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/AutoTransform>
#include <osg/Geometry>

#include <osgText/Text>

#include <iostream>

osg::Node* createLabel(const osg::Vec3& pos, float size, const std::string& label, osgText::Text::AxisAlignment axisAlignment)
{
    osg::Geode* geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(pos);
        text->setCharacterSize(size);
        text->setAxisAlignment(axisAlignment);
        text->setAlignment(osgText::Text::CENTER_CENTER);
        text->setText(label);

    }

    return geode;
}

osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& label)
{
    osg::Geode* geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(pos);
        text->setFontResolution(40,40);
        text->setCharacterSize(size);
        text->setAlignment(osgText::Text::CENTER_CENTER);
        text->setAutoRotateToScreen(true);
        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
        text->setText(label);

    }

    return geode;
}

osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps, osg::AutoTransform::AutoRotateMode autoRotateMode, osgText::Text::AxisAlignment axisAlignment, const std::string& str)
{
    osg::Group* group = new osg::Group;

    osg::Vec3 dv = e-s;
    dv /= float(numReps-1);

    osg::Vec3 pos = s;

    bool useAuto = true;
    if (useAuto)
    {
        osg::Vec3Array* vertices = new osg::Vec3Array;

        for(int i=0;i<numReps;++i)
        {
            osg::AutoTransform* at = new osg::AutoTransform;
            at->setPosition(pos);
            at->setAutoRotateMode(autoRotateMode);
            at->addChild(createLabel(osg::Vec3(0.0f,0.0f,0.0f),dv.length()*0.2f,str, axisAlignment));
            vertices->push_back(pos);
            pos += dv;

            group->addChild(at);
        }

        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

        osg::Geometry* geom = new osg::Geometry;
        geom->setVertexArray(vertices);
        geom->setColorArray(colors);
        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));

        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geom);

        group->addChild(geode);
    }
    else
    {
        osg::Vec3Array* vertices = new osg::Vec3Array;

        for(int i=0;i<numReps;++i)
        {
            group->addChild(createLabel3(osg::Vec3(pos),dv.length()*0.5f,str));
            vertices->push_back(pos);
            pos += dv;

        }

        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

        osg::Geometry* geom = new osg::Geometry;
        geom->setVertexArray(vertices);
        geom->setColorArray(colors);
        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));

        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geom);

        group->addChild(geode);
    }

    return group;
}

osg::Node* createAutoScale(const osg::Vec3& position, float characterSize, const std::string& message, float minScale=0.0, float maxScale=FLT_MAX)
{
    std::string timesFont("fonts/arial.ttf");

    osgText::Text* text = new osgText::Text;
    text->setCharacterSize(characterSize);
    text->setText(message);
    text->setFont(timesFont);
    text->setAlignment(osgText::Text::CENTER_CENTER);

    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(text);
    geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

    osg::AutoTransform* at = new osg::AutoTransform;
    at->addChild(geode);

    at->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN);
    at->setAutoScaleToScreen(true);
    at->setMinimumScale(minScale);
    at->setMaximumScale(maxScale);
    at->setPosition(position);

    return at;
}

osg::Node* createScene()
{
    osg::Group* root = new osg::Group;

//    int numReps = 3333;
    int numReps = 10;
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(1000.0,0.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_CAMERA,osgText::Text::XY_PLANE, "ROTATE_TO_CAMERA"));
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,1000.0,0.0),numReps,osg::AutoTransform::ROTATE_TO_SCREEN,osgText::Text::XY_PLANE, "ROTATE_TO_SCREEN"));
    root->addChild(createAxis(osg::Vec3(0.0,0.0,0.0),osg::Vec3(0.0,0.0,1000.0),numReps,osg::AutoTransform::NO_ROTATION,osgText::Text::XZ_PLANE, "NO_ROTATION"));

    root->addChild(createAutoScale(osg::Vec3(500.0,500.0,500.0), 25.0, "AutoScale with no min, max limits"));
    root->addChild(createAutoScale(osg::Vec3(500.0,500.0,300.0), 25.0, "AutoScale with minScale = 1, maxScale = 2.0 ", 1, 2.0));
    root->addChild(createAutoScale(osg::Vec3(500.0,500.0,700.0), 25.0, "AutoScale with minScale = 0.0, maxScale = 5.0 ", 0.0, 5.0));
    return root;
}

int main(int, char**)
{
    // construct the viewer.
    osgViewer::Viewer viewer;

    // set the scene to render
    viewer.setSceneData(createScene());

    // run the viewers frame loop
    return viewer.run();
}
<|endoftext|>


<commit_before>// To regenerate this list of includes run the following command from skia/include:
//
//     find core effects pathops  -maxdepth 1 -name "*.h" | sed "s#^[^\/]*\/##g" | sed "s/\(.*\)/#include \"\1\"/" | sort
//
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkAdvancedTypefaceMetrics.h"
#include "SkAlphaThresholdFilter.h"
#include "SkAnnotation.h"
#include "SkArithmeticMode.h"
#include "SkAvoidXfermode.h"
#include "SkBBHFactory.h"
#include "SkBicubicImageFilter.h"
#include "SkBitmapDevice.h"
#include "SkBitmap.h"
#include "SkBitmapSource.h"
#include "SkBlitRow.h"
#include "SkBlurDrawLooper.h"
#include "SkBlurImageFilter.h"
#include "SkBlurMaskFilter.h"
#include "SkBounder.h"
#include "SkCanvas.h"
#include "SkChecksum.h"
#include "SkChunkAlloc.h"
#include "SkClipStack.h"
#include "SkColorFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkColor.h"
#include "SkColorMatrixFilter.h"
#include "SkColorMatrix.h"
#include "SkColorPriv.h"
#include "SkColorShader.h"
#include "SkColorTable.h"
#include "SkComposeImageFilter.h"
#include "SkComposeShader.h"
#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkData.h"
#include "SkDataTable.h"
#include "SkDeque.h"
#include "SkDevice.h"
#include "SkDeviceProperties.h"
#include "SkDiscretePathEffect.h"
#include "SkDisplacementMapEffect.h"
#include "SkDither.h"
#include "SkDocument.h"
#include "SkDrawExtraPathEffect.h"
#include "SkDrawFilter.h"
#include "SkDraw.h"
#include "SkDrawLooper.h"
#include "SkDropShadowImageFilter.h"
#include "SkDynamicAnnotations.h"
#include "SkEmbossMaskFilter.h"
#include "SkEmptyShader.h"
#include "SkEndian.h"
#include "SkError.h"
#include "SkFixed.h"
#include "SkFlate.h"
#include "SkFlattenableBuffers.h"
#include "SkFlattenable.h"
#include "SkFlattenableSerialization.h"
#include "SkFloatBits.h"
#include "SkFloatingPoint.h"
#include "SkFont.h"
#include "SkFontHost.h"
#include "SkFontLCDConfig.h"
#include "SkGeometry.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkImageFilter.h"
#include "SkImageGenerator.h"
#include "SkImage.h"
#include "SkImageInfo.h"
#include "SkInstCnt.h"
#include "SkLayerDrawLooper.h"
#include "SkLayerRasterizer.h"
#include "SkLerpXfermode.h"
#include "SkLightingImageFilter.h"
#include "SkLineClipper.h"
#include "SkLumaColorFilter.h"
#include "SkMagnifierImageFilter.h"
#include "SkMallocPixelRef.h"
#include "SkMaskFilter.h"
#include "SkMask.h"
#include "SkMath.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkMatrix.h"
#include "SkMatrixImageFilter.h"
#include "SkMergeImageFilter.h"
#include "SkMetaData.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkOnce.h"
#include "SkOSFile.h"
#include "SkPackBits.h"
#include "SkPaintFlagsDrawFilter.h"
#include "SkPaint.h"
#include "SkPaintOptionsAndroid.h"
#include "SkPathEffect.h"
#include "SkPath.h"
#include "SkPathMeasure.h"
#include "SkPathOps.h"
#include "SkPathRef.h"
#include "SkPerlinNoiseShader.h"
#include "SkPicture.h"
#include "SkPictureImageFilter.h"
#include "SkPictureRecorder.h"
#include "SkPixelRef.h"
#include "SkPixelXorXfermode.h"
#include "SkPoint.h"
#include "SkPorterDuff.h"
#include "SkPostConfig.h"
#include "SkPreConfig.h"
#include "SkRasterizer.h"
#include "SkReadBuffer.h"
#include "SkReader32.h"
#include "SkRect.h"
#include "SkRectShaderImageFilter.h"
#include "SkRefCnt.h"
#include "SkRegion.h"
#include "SkRRect.h"
#include "SkRTreePicture.h"
#include "SkScalar.h"
#include "SkShader.h"
#include "SkSize.h"
#include "SkStippleMaskFilter.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkStringUtils.h"
#include "SkStrokeRec.h"
#include "SkSurface.h"
#include "SkTableColorFilter.h"
#include "SkTableMaskFilter.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTDict.h"
#include "SkTDStack.h"
#include "SkTemplates.h"
#include "SkTestImageFilters.h"
#include "SkThread.h"
#include "SkTileGridPicture.h"
#include "SkTileImageFilter.h"
#include "SkTime.h"
#include "SkTInternalLList.h"
#include "SkTLazy.h"
#include "SkTransparentShader.h"
#include "SkTRegistry.h"
#include "SkTSearch.h"
#include "SkTypeface.h"
#include "SkTypes.h"
#include "SkUnitMapper.h"
#include "SkUnPreMultiply.h"
#include "SkUtils.h"
#include "SkWeakRefCnt.h"
#include "SkWriteBuffer.h"
#include "SkWriter32.h"
#include "SkXfermode.h"
#include "SkXfermodeImageFilter.h"

{{.Code}}
<commit_msg>Remove unused (by clients) SkUnitMapper (https://codereview.chromium.org/283273002/)<commit_after>// To regenerate this list of includes run the following command from skia/include:
//
//     find core effects pathops  -maxdepth 1 -name "*.h" | sed "s#^[^\/]*\/##g" | sed "s/\(.*\)/#include \"\1\"/" | sort
//
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkAdvancedTypefaceMetrics.h"
#include "SkAlphaThresholdFilter.h"
#include "SkAnnotation.h"
#include "SkArithmeticMode.h"
#include "SkAvoidXfermode.h"
#include "SkBBHFactory.h"
#include "SkBicubicImageFilter.h"
#include "SkBitmapDevice.h"
#include "SkBitmap.h"
#include "SkBitmapSource.h"
#include "SkBlitRow.h"
#include "SkBlurDrawLooper.h"
#include "SkBlurImageFilter.h"
#include "SkBlurMaskFilter.h"
#include "SkBounder.h"
#include "SkCanvas.h"
#include "SkChecksum.h"
#include "SkChunkAlloc.h"
#include "SkClipStack.h"
#include "SkColorFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkColor.h"
#include "SkColorMatrixFilter.h"
#include "SkColorMatrix.h"
#include "SkColorPriv.h"
#include "SkColorShader.h"
#include "SkColorTable.h"
#include "SkComposeImageFilter.h"
#include "SkComposeShader.h"
#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkData.h"
#include "SkDataTable.h"
#include "SkDeque.h"
#include "SkDevice.h"
#include "SkDeviceProperties.h"
#include "SkDiscretePathEffect.h"
#include "SkDisplacementMapEffect.h"
#include "SkDither.h"
#include "SkDocument.h"
#include "SkDrawExtraPathEffect.h"
#include "SkDrawFilter.h"
#include "SkDraw.h"
#include "SkDrawLooper.h"
#include "SkDropShadowImageFilter.h"
#include "SkDynamicAnnotations.h"
#include "SkEmbossMaskFilter.h"
#include "SkEmptyShader.h"
#include "SkEndian.h"
#include "SkError.h"
#include "SkFixed.h"
#include "SkFlate.h"
#include "SkFlattenableBuffers.h"
#include "SkFlattenable.h"
#include "SkFlattenableSerialization.h"
#include "SkFloatBits.h"
#include "SkFloatingPoint.h"
#include "SkFont.h"
#include "SkFontHost.h"
#include "SkFontLCDConfig.h"
#include "SkGeometry.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkImageFilter.h"
#include "SkImageGenerator.h"
#include "SkImage.h"
#include "SkImageInfo.h"
#include "SkInstCnt.h"
#include "SkLayerDrawLooper.h"
#include "SkLayerRasterizer.h"
#include "SkLerpXfermode.h"
#include "SkLightingImageFilter.h"
#include "SkLineClipper.h"
#include "SkLumaColorFilter.h"
#include "SkMagnifierImageFilter.h"
#include "SkMallocPixelRef.h"
#include "SkMaskFilter.h"
#include "SkMask.h"
#include "SkMath.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkMatrix.h"
#include "SkMatrixImageFilter.h"
#include "SkMergeImageFilter.h"
#include "SkMetaData.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkOnce.h"
#include "SkOSFile.h"
#include "SkPackBits.h"
#include "SkPaintFlagsDrawFilter.h"
#include "SkPaint.h"
#include "SkPaintOptionsAndroid.h"
#include "SkPathEffect.h"
#include "SkPath.h"
#include "SkPathMeasure.h"
#include "SkPathOps.h"
#include "SkPathRef.h"
#include "SkPerlinNoiseShader.h"
#include "SkPicture.h"
#include "SkPictureImageFilter.h"
#include "SkPictureRecorder.h"
#include "SkPixelRef.h"
#include "SkPixelXorXfermode.h"
#include "SkPoint.h"
#include "SkPorterDuff.h"
#include "SkPostConfig.h"
#include "SkPreConfig.h"
#include "SkRasterizer.h"
#include "SkReadBuffer.h"
#include "SkReader32.h"
#include "SkRect.h"
#include "SkRectShaderImageFilter.h"
#include "SkRefCnt.h"
#include "SkRegion.h"
#include "SkRRect.h"
#include "SkRTreePicture.h"
#include "SkScalar.h"
#include "SkShader.h"
#include "SkSize.h"
#include "SkStippleMaskFilter.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkStringUtils.h"
#include "SkStrokeRec.h"
#include "SkSurface.h"
#include "SkTableColorFilter.h"
#include "SkTableMaskFilter.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTDict.h"
#include "SkTDStack.h"
#include "SkTemplates.h"
#include "SkTestImageFilters.h"
#include "SkThread.h"
#include "SkTileGridPicture.h"
#include "SkTileImageFilter.h"
#include "SkTime.h"
#include "SkTInternalLList.h"
#include "SkTLazy.h"
#include "SkTransparentShader.h"
#include "SkTRegistry.h"
#include "SkTSearch.h"
#include "SkTypeface.h"
#include "SkTypes.h"
#include "SkUnPreMultiply.h"
#include "SkUtils.h"
#include "SkWeakRefCnt.h"
#include "SkWriteBuffer.h"
#include "SkWriter32.h"
#include "SkXfermode.h"
#include "SkXfermodeImageFilter.h"

{{.Code}}
<|endoftext|>


<commit_before>#include <TTree.h>
#include <TFile.h>
#include <Math/Vector2D.h>
#include <Math/DisplacementVector2D.h>

#include <memory>

// FIXME: these includes should be absolute and provided with installation?
#include "../../src/objects/DepositedCharge.hpp"
#include "../..//src/objects/PixelCharge.hpp"
#include "../../src/objects/PixelHit.hpp"

// FIXME: pixel size should be available in the data
std::shared_ptr<TTree> constructComparisonTree(TFile *file, std::string dut, ROOT::Math::XYVector pixel_size) {
    // Read pixel hit output
    TTree *pixel_hit_tree = static_cast<TTree*>(file->Get("PixelHit"));
    TBranch *pixel_hit_branch = pixel_hit_tree->FindBranch(dut.c_str());
    std::vector<allpix::PixelHit*> input_hits;
    pixel_hit_branch->SetObject(&input_hits);

    // Read pixel charge output
    TTree *pixel_charge_tree = static_cast<TTree*>(file->Get("PixelCharge"));
    TBranch *pixel_charge_branch = pixel_charge_tree->FindBranch(dut.c_str());
    std::vector<allpix::PixelCharge*> input_charges;
    pixel_charge_branch->SetObject(&input_charges);

    // Read deposited charge output
    TTree *deposited_charge_tree = static_cast<TTree*>(file->Get("DepositedCharge"));
    TBranch *deposited_charge_branch = deposited_charge_tree->FindBranch(dut.c_str());
    std::vector<allpix::DepositedCharge*> input_deposits;
    deposited_charge_branch->SetObject(&input_deposits);

    // Initialize output tree and branches
    auto output_tree = std::make_shared<TTree>("clusters", ("Cluster information for " + dut).c_str());
    int event_num;
    // Event number
    output_tree->Branch("eventNr", &event_num);
    // Cluster size
    int output_cluster, output_cluster_x, output_cluster_y; double aspect_ratio;
    output_tree->Branch("size", &output_cluster);
    output_tree->Branch("sizeX", &output_cluster_x);
    output_tree->Branch("sizeY", &output_cluster_y);
    output_tree->Branch("aspectRatio", &aspect_ratio);
    // Charge info
    int output_total_charge; std::vector<int> output_charge;
    output_tree->Branch("totalCharge", &output_total_charge);
    output_tree->Branch("charge", &output_charge);
    // Signal info
    int output_total_signal; std::vector<int> output_signal;
    output_tree->Branch("totalSignal", &output_total_signal);
    output_tree->Branch("signal", &output_signal);
    // Single pixel row / col
    std::vector<int> output_rows; std::vector<int> output_cols;
    output_tree->Branch("row", &output_rows);
    output_tree->Branch("col", &output_cols);
    // Real track information
    int output_track_count; double output_track_x, output_track_y;
    output_tree->Branch("trackCount", &output_track_count); // FIXME: problems arise if not one
    output_tree->Branch("trackLocalX", &output_track_x);
    output_tree->Branch("trackLocalY", &output_track_y);
    // Calculated track information and residuals
    double output_x, output_y, output_res_x, output_res_y;
    output_tree->Branch("localX", &output_track_x);
    output_tree->Branch("localY", &output_track_y);
    output_tree->Branch("resX", &output_res_x);
    output_tree->Branch("resY", &output_res_y);

    // Convert tree for every event
    for(int i = 0; i<pixel_hit_tree->GetEntries(); ++i) {
        pixel_hit_tree->GetEntry(i);
        pixel_charge_tree->GetEntry(i);
        deposited_charge_tree->GetEntry(i);

        // Set event number
        event_num = i+1;

        // Set cluster sizes
        output_cluster = input_hits.size();
        std::set<int> unique_x;
        std::set<int> unique_y;
        for(auto& hit : input_hits) {
            unique_x.insert(hit->getPixel().x());
            unique_y.insert(hit->getPixel().y());
        }
        output_cluster_x = unique_x.size();
        output_cluster_y = unique_y.size();
        aspect_ratio = static_cast<double>(output_cluster_y)/output_cluster_x;

        // Set charge information
        output_charge.clear();
        output_total_charge = 0;
        for(auto& pixel_charge : input_charges) {
            output_charge.push_back(pixel_charge->getCharge());
            output_total_charge += pixel_charge->getCharge();
        }

        // Set signal information
        output_signal.clear();
        output_total_signal = 0;
        for(auto& hit : input_hits) {
            output_signal.push_back(hit->getSignal());
            output_total_signal += hit->getSignal();
        }

        // Set pixel position information
        output_rows.clear();
        output_cols.clear();
        for(auto& hit : input_hits) {
            // FIXME defined order
            output_rows.push_back(hit->getPixel().y());
            output_cols.push_back(hit->getPixel().x());
        }

        // Guess information about the track (should be an extra object)
        double min_position_z = 0;
        for(auto& deposit : input_deposits) {
            min_position_z = std::min(min_position_z, deposit->getPosition().z());
        }
        output_track_count = 0;
        for(auto& deposit : input_deposits) {
            if(std::fabs(min_position_z - deposit->getPosition().z()) < 1e-9) {
                ++output_track_count;
                // FIXME just picks the last 'track' now
                output_track_x = deposit->getPosition().x();
                output_track_y = deposit->getPosition().y();
            }
        }

        // Calculate local x using a simple center of gravity fit
        // FIXME no corrections are applied
        ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<double>> totalPixel;
        double totalSignal = 0;
        for(auto& hit : input_hits) {
            // FIXME: should not use the row / column but their position
            totalPixel += hit->getPixel() * hit->getSignal();
            totalSignal += hit->getSignal();
        }
        totalPixel /= totalSignal;
        output_x = totalPixel.x() * pixel_size.x();
        output_y = totalPixel.y() * pixel_size.y();
        output_res_x = output_track_x - output_x;
        output_res_y = output_track_y - output_y;

        output_tree->Fill();
    }

    return output_tree;
}
<commit_msg>improve comparison macro to use mc particle information<commit_after>#include <TTree.h>
#include <TFile.h>
#include <Math/Vector2D.h>
#include <Math/DisplacementVector2D.h>

#include <memory>

// FIXME: these includes should be absolute and provided with installation?
#include "../../src/objects/DepositedCharge.hpp"
#include "../..//src/objects/PixelCharge.hpp"
#include "../../src/objects/PixelHit.hpp"
#include "../../src/objects/MCParticle.hpp"

// FIXME: pixel size should be available in the data
std::shared_ptr<TTree> constructComparisonTree(TFile *file, std::string dut, ROOT::Math::XYVector pixel_size) {
    // Read pixel hit output
    TTree *pixel_hit_tree = static_cast<TTree*>(file->Get("PixelHit"));
    TBranch *pixel_hit_branch = pixel_hit_tree->FindBranch(dut.c_str());
    std::vector<allpix::PixelHit*> input_hits;
    pixel_hit_branch->SetObject(&input_hits);

    // Read pixel charge output
    TTree *pixel_charge_tree = static_cast<TTree*>(file->Get("PixelCharge"));
    TBranch *pixel_charge_branch = pixel_charge_tree->FindBranch(dut.c_str());
    std::vector<allpix::PixelCharge*> input_charges;
    pixel_charge_branch->SetObject(&input_charges);

    // Read MC truth
    TTree *mc_particle_tree = static_cast<TTree*>(file->Get("MCParticle"));
    TBranch *mc_particle_branch = mc_particle_tree->FindBranch(dut.c_str());
    std::vector<allpix::MCParticle*> input_particles;
    mc_particle_branch->SetObject(&input_particles);

    // Initialize output tree and branches
    auto output_tree = std::make_shared<TTree>("clusters", ("Cluster information for " + dut).c_str());
    int event_num;
    // Event number
    output_tree->Branch("eventNr", &event_num);
    // Cluster size
    int output_cluster, output_cluster_x, output_cluster_y; double aspect_ratio;
    output_tree->Branch("size", &output_cluster);
    output_tree->Branch("sizeX", &output_cluster_x);
    output_tree->Branch("sizeY", &output_cluster_y);
    output_tree->Branch("aspectRatio", &aspect_ratio);
    // Charge info
    int output_total_charge; std::vector<int> output_charge;
    output_tree->Branch("totalCharge", &output_total_charge);
    output_tree->Branch("charge", &output_charge);
    // Signal info
    int output_total_signal; std::vector<int> output_signal;
    output_tree->Branch("totalSignal", &output_total_signal);
    output_tree->Branch("signal", &output_signal);
    // Single pixel row / col
    std::vector<int> output_rows; std::vector<int> output_cols;
    output_tree->Branch("row", &output_rows);
    output_tree->Branch("col", &output_cols);
    // Real track information
    int output_track_count; double output_track_x, output_track_y;
    output_tree->Branch("trackCount", &output_track_count); // FIXME: problems arise if not one
    output_tree->Branch("trackLocalX", &output_track_x);
    output_tree->Branch("trackLocalY", &output_track_y);
    // Calculated track information and residuals
    double output_x, output_y, output_res_x, output_res_y;
    output_tree->Branch("localX", &output_track_x);
    output_tree->Branch("localY", &output_track_y);
    output_tree->Branch("resX", &output_res_x);
    output_tree->Branch("resY", &output_res_y);

    // Convert tree for every event
    for(int i = 0; i<pixel_hit_tree->GetEntries(); ++i) {
        pixel_hit_tree->GetEntry(i);
        pixel_charge_tree->GetEntry(i);
        mc_particle_tree->GetEntry(i);

        // Skip all events with multiple particles
        // FIXME: until we handle the mc particle better
        if(input_particles.size() > 1) continue;

        // Set event number
        event_num = i+1;

        // Set cluster sizes
        output_cluster = input_hits.size();
        std::set<int> unique_x;
        std::set<int> unique_y;
        for(auto& hit : input_hits) {
            unique_x.insert(hit->getPixel().x());
            unique_y.insert(hit->getPixel().y());
        }
        output_cluster_x = unique_x.size();
        output_cluster_y = unique_y.size();
        aspect_ratio = static_cast<double>(output_cluster_y)/output_cluster_x;

        // Set charge information
        output_charge.clear();
        output_total_charge = 0;
        for(auto& pixel_charge : input_charges) {
            output_charge.push_back(pixel_charge->getCharge());
            output_total_charge += pixel_charge->getCharge();
        }

        // Set signal information
        output_signal.clear();
        output_total_signal = 0;
        for(auto& hit : input_hits) {
            output_signal.push_back(hit->getSignal());
            output_total_signal += hit->getSignal();
        }

        // Set pixel position information
        output_rows.clear();
        output_cols.clear();
        for(auto& hit : input_hits) {
            // FIXME defined order
            output_rows.push_back(hit->getPixel().y());
            output_cols.push_back(hit->getPixel().x());
        }

        // Get information about the actual track
        output_track_count = input_particles.size();
        for(auto& particle : input_particles) {
            // FIXME just use the middle position between the entry point and the exit as the track position
            output_track_x = (particle->getEntryPoint().x() + particle->getExitPoint().x())/ 2.0;
            output_track_y = (particle->getEntryPoint().y() + particle->getExitPoint().y()) / 2.0;
        }

        // Calculate local x using a simple center of gravity fit
        // FIXME no corrections are applied
        ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<double>> totalPixel;
        double totalSignal = 0;
        for(auto& hit : input_hits) {
            // FIXME: should not use the row / column but their position
            totalPixel += hit->getPixel() * hit->getSignal();
            totalSignal += hit->getSignal();
        }
        totalPixel /= totalSignal;
        output_x = totalPixel.x() * pixel_size.x();
        output_y = totalPixel.y() * pixel_size.y();
        output_res_x = output_track_x - output_x;
        output_res_y = output_track_y - output_y;

        output_tree->Fill();
    }

    return output_tree;
}
<|endoftext|>