<commit_before>/*
 *  traywindow.cpp  -  the KDE system tray applet
 *  Program:  kalarm
 *  Copyright © 2002-2007 by David Jarvie <software@astrojar.org.uk>
 *
 *  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.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"

#include <stdlib.h>

#include <QToolTip>
#include <QMouseEvent>
#include <QList>

#include <kactioncollection.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstandardaction.h>
#include <kaboutdata.h>
#include <kmenu.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kstandardaction.h>
#include <KStandardGuiItem>
#include <kconfig.h>
#include <kdebug.h>

#include "alarmcalendar.h"
#include "alarmlistview.h"
#include "alarmresources.h"
#include "alarmtext.h"
#include "daemon.h"
#include "functions.h"
#include "kalarmapp.h"
#include "mainwindow.h"
#include "messagewin.h"
#include "prefdlg.h"
#include "preferences.h"
#include "templatemenuaction.h"
#include "traywindow.moc"

struct TipItem
{
	QDateTime  dateTime;
	QString    text;
};

/*=============================================================================
= Class: TrayWindow
= The KDE system tray window.
=============================================================================*/

TrayWindow::TrayWindow(MainWindow* parent)
	: KSystemTrayIcon((theApp()->wantRunInSystemTray() ? parent : 0)),
	  mAssocMainWindow(parent)
{
	kDebug(5950) << "TrayWindow::TrayWindow()\n";
	// Set up GUI icons
	mIconEnabled  = loadIcon("kalarm");
	mIconDisabled = loadIcon("kalarm_disabled");
	if (mIconEnabled.isNull() || mIconDisabled.isNull())
		KMessageBox::sorry(parent, i18n("Cannot load system tray icon."));
#ifdef __GNUC__
#warning How to implement drag-and-drop?
#endif
	//setAcceptDrops(true);         // allow drag-and-drop onto this window

	// Set up the context menu
	KActionCollection* actions = actionCollection();
	KAction* a = Daemon::createAlarmEnableAction(this);
	actions->addAction(QLatin1String("tAlarmsEnable"), a);
	contextMenu()->addAction(a);
	connect(a, SIGNAL(switched(bool)), SLOT(setEnabledStatus(bool)));
	mActionNew = KAlarm::createNewAlarmAction(i18n("&New Alarm..."), actions, QLatin1String("tNew"));
	contextMenu()->addAction(mActionNew);
	connect(mActionNew, SIGNAL(triggered(bool)), SLOT(slotNewAlarm()));
	mActionNewFromTemplate = KAlarm::createNewFromTemplateAction(i18n("New Alarm From &Template"), actions, QLatin1String("tNewFromTempl"));
	contextMenu()->addAction(mActionNewFromTemplate);
	connect(mActionNewFromTemplate, SIGNAL(selected(const KAEvent&)), SLOT(slotNewFromTemplate(const KAEvent&)));
	contextMenu()->addAction(KStandardAction::preferences(this, SLOT(slotPreferences()), actions));

	// Replace the default handler for the Quit context menu item
	const char* quitName = KStandardAction::name(KStandardAction::Quit);
	delete actions->action(quitName);
	KStandardAction::quit(this, SLOT(slotQuit()), actions);

	// Set icon to correspond with the alarms enabled menu status
	Daemon::checkStatus();
	setEnabledStatus(Daemon::monitoringAlarms());

	connect(AlarmResources::instance(), SIGNAL(resourceStatusChanged(AlarmResource*, AlarmResources::Change)), SLOT(slotResourceStatusChanged()));
	connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(slotActivated(QSystemTrayIcon::ActivationReason)));
}

TrayWindow::~TrayWindow()
{
	kDebug(5950) << "TrayWindow::~TrayWindow()\n";
	theApp()->removeWindow(this);
	emit deleted();
}

/******************************************************************************
* Called just before the context menu is displayed.
* Update the Alarms Enabled item status.
*/
void TrayWindow::contextMenuAboutToShow(KMenu*)
{
	Daemon::checkStatus();
}

/******************************************************************************
* Called when the status of a resource has changed.
* Enable or disable actions appropriately.
*/
void TrayWindow::slotResourceStatusChanged()
{
	// Find whether there are any writable active alarm resources
	bool active = AlarmResources::instance()->activeCount(AlarmResource::ACTIVE, true);
	mActionNew->setEnabled(active);
	mActionNewFromTemplate->setEnabled(active);
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewAlarm()
{
	KAlarm::editNewAlarm();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewFromTemplate(const KAEvent& event)
{
	KAlarm::editNewAlarm(0, &event);
}

/******************************************************************************
*  Called when the "Configure KAlarm" menu item is selected.
*/
void TrayWindow::slotPreferences()
{
	KAlarmPrefDlg prefDlg;
	prefDlg.exec();
}

/******************************************************************************
* Called when the Quit context menu item is selected.
*/
void TrayWindow::slotQuit()
{
	theApp()->doQuit(parentWidget());
}

/******************************************************************************
* Called when the Alarms Enabled action status has changed.
* Updates the alarms enabled menu item check state, and the icon pixmap.
*/
void TrayWindow::setEnabledStatus(bool status)
{
	kDebug(5950) << "TrayWindow::setEnabledStatus(" << (int)status << ")\n";
	setIcon(status ? mIconEnabled : mIconDisabled);
}

/******************************************************************************
*  Called when the mouse is clicked over the panel icon.
*  A left click displays the KAlarm main window.
*  A middle button click displays the New Alarm window.
*/
void TrayWindow::slotActivated(QSystemTrayIcon::ActivationReason reason)
{
	if (reason == QSystemTrayIcon::Trigger)
	{
		// Left click: display/hide the first main window
		if (!theApp()->wantRunInSystemTray())
			mAssocMainWindow = MainWindow::toggleWindow(mAssocMainWindow);
		else if (mAssocMainWindow  &&  mAssocMainWindow->isVisible())
		{
			mAssocMainWindow->raise();
			mAssocMainWindow->activateWindow();
		}
	}
	else if (reason == QSystemTrayIcon::MiddleClick)
	{
		if (mActionNew->isEnabled())
			mActionNew->trigger();    // display a New Alarm dialog
	}
}

/******************************************************************************
*  Called when the drag cursor enters the panel icon.
*/
void TrayWindow::dragEnterEvent(QDragEnterEvent* e)
{
	MainWindow::executeDragEnterEvent(e);
}

/******************************************************************************
*  Called when an object is dropped on the panel icon.
*  If the object is recognised, the edit alarm dialog is opened appropriately.
*/
void TrayWindow::dropEvent(QDropEvent* e)
{
	MainWindow::executeDropEvent(0, e);
}

/******************************************************************************
*  Called when any event occurs.
*  If it's a tooltip event, display the tooltip text showing alarms due in the
*  next 24 hours. The limit of 24 hours is because only times, not dates, are
*  displayed.
*/
bool TrayWindow::event(QEvent* e)
{
	if (e->type() != QEvent::ToolTip)
		return KSystemTrayIcon::event(e);
	QHelpEvent* he = (QHelpEvent*)e;
	QString text;
	if (Daemon::monitoringAlarms())
		text = KGlobal::mainComponent().aboutData()->programName();
	else
		text = i18n("%1 - disabled", KGlobal::mainComponent().aboutData()->programName());
	kDebug(5950) << "TrayWindow::event(): " << text << endl;
	if (Preferences::tooltipAlarmCount())
		tooltipAlarmText(text);
	QToolTip::showText(he->pos(), text);
	return true;
}

/******************************************************************************
*  Return the tooltip text showing alarms due in the next 24 hours.
*  The limit of 24 hours is because only times, not dates, are displayed.
*/
void TrayWindow::tooltipAlarmText(QString& text) const
{
	KAEvent event;
	const QString& prefix = Preferences::tooltipTimeToPrefix();
	int maxCount = Preferences::tooltipAlarmCount();
	KDateTime now = KDateTime::currentLocalDateTime();
	KDateTime tomorrow = now.addDays(1);

	// Get today's and tomorrow's alarms, sorted in time order
	int i, iend;
	QList<TipItem> items;
	KCal::Event::List events = AlarmCalendar::resources()->eventsWithAlarms(KDateTime(now.date(), QTime(0,0,0), KDateTime::LocalZone), tomorrow, KCalEvent::ACTIVE);
	for (i = 0, iend = events.count();  i < iend;  ++i)
	{
		KCal::Event* kcalEvent = events[i];
		event.set(kcalEvent);
		if (event.enabled()  &&  !event.expired()  &&  event.action() == KAEvent::MESSAGE)
		{
			TipItem item;
			QDateTime dateTime = event.nextDateTime(false).effectiveKDateTime().toLocalZone().dateTime();
			if (dateTime > tomorrow.dateTime())
				continue;   // ignore alarms after tomorrow at the current clock time
			item.dateTime = dateTime;

			// The alarm is due today, or early tomorrow
			bool space = false;
			if (Preferences::showTooltipAlarmTime())
			{
				item.text += KGlobal::locale()->formatTime(item.dateTime.time());
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (Preferences::showTooltipTimeToAlarm())
			{
				int mins = (now.dateTime().secsTo(item.dateTime) + 59) / 60;
				if (mins < 0)
					mins = 0;
				char minutes[3] = "00";
				minutes[0] = (mins%60) / 10 + '0';
				minutes[1] = (mins%60) % 10 + '0';
				if (Preferences::showTooltipAlarmTime())
					item.text += i18nc("prefix + hours:minutes", "(%1%2:%3)", prefix, mins/60, minutes);
				else
					item.text += i18nc("prefix + hours:minutes", "%1%2:%3", prefix, mins/60, minutes);
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (space)
				item.text += QLatin1Char(' ');
			item.text += AlarmText::summary(event);

			// Insert the item into the list in time-sorted order
			int it = 0;
			for (int itend = items.count();  it < itend;  ++it)
			{
				if (item.dateTime <= items[it].dateTime)
					break;
			}
			items.insert(it, item);
		}
	}
	kDebug(5950) << "TrayWindow::tooltipAlarmText():\n";
	int count = 0;
	for (i = 0, iend = items.count();  i < iend;  ++i)
	{
		kDebug(5950) << "-- " << (count+1) << ") " << items[i].text << endl;
		text += '\n';
		text += items[i].text;
		if (++count == maxCount)
			break;
	}
}

/******************************************************************************
* Called when the associated main window is closed.
*/
void TrayWindow::removeWindow(MainWindow* win)
{
	if (win == mAssocMainWindow)
		mAssocMainWindow = 0;
}
<commit_msg>Fix position of tooltip<commit_after>/*
 *  traywindow.cpp  -  the KDE system tray applet
 *  Program:  kalarm
 *  Copyright © 2002-2007 by David Jarvie <software@astrojar.org.uk>
 *
 *  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.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"

#include <stdlib.h>

#include <QToolTip>
#include <QMouseEvent>
#include <QList>

#include <kactioncollection.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstandardaction.h>
#include <kaboutdata.h>
#include <kmenu.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kstandardaction.h>
#include <KStandardGuiItem>
#include <kconfig.h>
#include <kdebug.h>

#include "alarmcalendar.h"
#include "alarmlistview.h"
#include "alarmresources.h"
#include "alarmtext.h"
#include "daemon.h"
#include "functions.h"
#include "kalarmapp.h"
#include "mainwindow.h"
#include "messagewin.h"
#include "prefdlg.h"
#include "preferences.h"
#include "templatemenuaction.h"
#include "traywindow.moc"

struct TipItem
{
	QDateTime  dateTime;
	QString    text;
};

/*=============================================================================
= Class: TrayWindow
= The KDE system tray window.
=============================================================================*/

TrayWindow::TrayWindow(MainWindow* parent)
	: KSystemTrayIcon((theApp()->wantRunInSystemTray() ? parent : 0)),
	  mAssocMainWindow(parent)
{
	kDebug(5950) << "TrayWindow::TrayWindow()\n";
	// Set up GUI icons
	mIconEnabled  = loadIcon("kalarm");
	mIconDisabled = loadIcon("kalarm_disabled");
	if (mIconEnabled.isNull() || mIconDisabled.isNull())
		KMessageBox::sorry(parent, i18n("Cannot load system tray icon."));
#ifdef __GNUC__
#warning How to implement drag-and-drop?
#endif
	//setAcceptDrops(true);         // allow drag-and-drop onto this window

	// Set up the context menu
	KActionCollection* actions = actionCollection();
	KAction* a = Daemon::createAlarmEnableAction(this);
	actions->addAction(QLatin1String("tAlarmsEnable"), a);
	contextMenu()->addAction(a);
	connect(a, SIGNAL(switched(bool)), SLOT(setEnabledStatus(bool)));
	mActionNew = KAlarm::createNewAlarmAction(i18n("&New Alarm..."), actions, QLatin1String("tNew"));
	contextMenu()->addAction(mActionNew);
	connect(mActionNew, SIGNAL(triggered(bool)), SLOT(slotNewAlarm()));
	mActionNewFromTemplate = KAlarm::createNewFromTemplateAction(i18n("New Alarm From &Template"), actions, QLatin1String("tNewFromTempl"));
	contextMenu()->addAction(mActionNewFromTemplate);
	connect(mActionNewFromTemplate, SIGNAL(selected(const KAEvent&)), SLOT(slotNewFromTemplate(const KAEvent&)));
	contextMenu()->addAction(KStandardAction::preferences(this, SLOT(slotPreferences()), actions));

	// Replace the default handler for the Quit context menu item
	const char* quitName = KStandardAction::name(KStandardAction::Quit);
	delete actions->action(quitName);
	KStandardAction::quit(this, SLOT(slotQuit()), actions);

	// Set icon to correspond with the alarms enabled menu status
	Daemon::checkStatus();
	setEnabledStatus(Daemon::monitoringAlarms());

	connect(AlarmResources::instance(), SIGNAL(resourceStatusChanged(AlarmResource*, AlarmResources::Change)), SLOT(slotResourceStatusChanged()));
	connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(slotActivated(QSystemTrayIcon::ActivationReason)));
}

TrayWindow::~TrayWindow()
{
	kDebug(5950) << "TrayWindow::~TrayWindow()\n";
	theApp()->removeWindow(this);
	emit deleted();
}

/******************************************************************************
* Called just before the context menu is displayed.
* Update the Alarms Enabled item status.
*/
void TrayWindow::contextMenuAboutToShow(KMenu*)
{
	Daemon::checkStatus();
}

/******************************************************************************
* Called when the status of a resource has changed.
* Enable or disable actions appropriately.
*/
void TrayWindow::slotResourceStatusChanged()
{
	// Find whether there are any writable active alarm resources
	bool active = AlarmResources::instance()->activeCount(AlarmResource::ACTIVE, true);
	mActionNew->setEnabled(active);
	mActionNewFromTemplate->setEnabled(active);
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewAlarm()
{
	KAlarm::editNewAlarm();
}

/******************************************************************************
*  Called when the "New Alarm" menu item is selected to edit a new alarm.
*/
void TrayWindow::slotNewFromTemplate(const KAEvent& event)
{
	KAlarm::editNewAlarm(0, &event);
}

/******************************************************************************
*  Called when the "Configure KAlarm" menu item is selected.
*/
void TrayWindow::slotPreferences()
{
	KAlarmPrefDlg prefDlg;
	prefDlg.exec();
}

/******************************************************************************
* Called when the Quit context menu item is selected.
*/
void TrayWindow::slotQuit()
{
	theApp()->doQuit(parentWidget());
}

/******************************************************************************
* Called when the Alarms Enabled action status has changed.
* Updates the alarms enabled menu item check state, and the icon pixmap.
*/
void TrayWindow::setEnabledStatus(bool status)
{
	kDebug(5950) << "TrayWindow::setEnabledStatus(" << (int)status << ")\n";
	setIcon(status ? mIconEnabled : mIconDisabled);
}

/******************************************************************************
*  Called when the mouse is clicked over the panel icon.
*  A left click displays the KAlarm main window.
*  A middle button click displays the New Alarm window.
*/
void TrayWindow::slotActivated(QSystemTrayIcon::ActivationReason reason)
{
	if (reason == QSystemTrayIcon::Trigger)
	{
		// Left click: display/hide the first main window
		if (!theApp()->wantRunInSystemTray())
			mAssocMainWindow = MainWindow::toggleWindow(mAssocMainWindow);
		else if (mAssocMainWindow  &&  mAssocMainWindow->isVisible())
		{
			mAssocMainWindow->raise();
			mAssocMainWindow->activateWindow();
		}
	}
	else if (reason == QSystemTrayIcon::MiddleClick)
	{
		if (mActionNew->isEnabled())
			mActionNew->trigger();    // display a New Alarm dialog
	}
}

/******************************************************************************
*  Called when the drag cursor enters the panel icon.
*/
void TrayWindow::dragEnterEvent(QDragEnterEvent* e)
{
	MainWindow::executeDragEnterEvent(e);
}

/******************************************************************************
*  Called when an object is dropped on the panel icon.
*  If the object is recognised, the edit alarm dialog is opened appropriately.
*/
void TrayWindow::dropEvent(QDropEvent* e)
{
	MainWindow::executeDropEvent(0, e);
}

/******************************************************************************
*  Called when any event occurs.
*  If it's a tooltip event, display the tooltip text showing alarms due in the
*  next 24 hours. The limit of 24 hours is because only times, not dates, are
*  displayed.
*/
bool TrayWindow::event(QEvent* e)
{
	if (e->type() != QEvent::ToolTip)
		return KSystemTrayIcon::event(e);
	QHelpEvent* he = (QHelpEvent*)e;
	QString text;
	if (Daemon::monitoringAlarms())
		text = KGlobal::mainComponent().aboutData()->programName();
	else
		text = i18n("%1 - disabled", KGlobal::mainComponent().aboutData()->programName());
	kDebug(5950) << "TrayWindow::event(): " << text << endl;
	if (Preferences::tooltipAlarmCount())
		tooltipAlarmText(text);
	QToolTip::showText(he->globalPos(), text);
	return true;
}

/******************************************************************************
*  Return the tooltip text showing alarms due in the next 24 hours.
*  The limit of 24 hours is because only times, not dates, are displayed.
*/
void TrayWindow::tooltipAlarmText(QString& text) const
{
	KAEvent event;
	const QString& prefix = Preferences::tooltipTimeToPrefix();
	int maxCount = Preferences::tooltipAlarmCount();
	KDateTime now = KDateTime::currentLocalDateTime();
	KDateTime tomorrow = now.addDays(1);

	// Get today's and tomorrow's alarms, sorted in time order
	int i, iend;
	QList<TipItem> items;
	KCal::Event::List events = AlarmCalendar::resources()->eventsWithAlarms(KDateTime(now.date(), QTime(0,0,0), KDateTime::LocalZone), tomorrow, KCalEvent::ACTIVE);
	for (i = 0, iend = events.count();  i < iend;  ++i)
	{
		KCal::Event* kcalEvent = events[i];
		event.set(kcalEvent);
		if (event.enabled()  &&  !event.expired()  &&  event.action() == KAEvent::MESSAGE)
		{
			TipItem item;
			QDateTime dateTime = event.nextDateTime(false).effectiveKDateTime().toLocalZone().dateTime();
			if (dateTime > tomorrow.dateTime())
				continue;   // ignore alarms after tomorrow at the current clock time
			item.dateTime = dateTime;

			// The alarm is due today, or early tomorrow
			bool space = false;
			if (Preferences::showTooltipAlarmTime())
			{
				item.text += KGlobal::locale()->formatTime(item.dateTime.time());
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (Preferences::showTooltipTimeToAlarm())
			{
				int mins = (now.dateTime().secsTo(item.dateTime) + 59) / 60;
				if (mins < 0)
					mins = 0;
				char minutes[3] = "00";
				minutes[0] = (mins%60) / 10 + '0';
				minutes[1] = (mins%60) % 10 + '0';
				if (Preferences::showTooltipAlarmTime())
					item.text += i18nc("prefix + hours:minutes", "(%1%2:%3)", prefix, mins/60, minutes);
				else
					item.text += i18nc("prefix + hours:minutes", "%1%2:%3", prefix, mins/60, minutes);
				item.text += QLatin1Char(' ');
				space = true;
			}
			if (space)
				item.text += QLatin1Char(' ');
			item.text += AlarmText::summary(event);

			// Insert the item into the list in time-sorted order
			int it = 0;
			for (int itend = items.count();  it < itend;  ++it)
			{
				if (item.dateTime <= items[it].dateTime)
					break;
			}
			items.insert(it, item);
		}
	}
	kDebug(5950) << "TrayWindow::tooltipAlarmText():\n";
	int count = 0;
	for (i = 0, iend = items.count();  i < iend;  ++i)
	{
		kDebug(5950) << "-- " << (count+1) << ") " << items[i].text << endl;
		text += '\n';
		text += items[i].text;
		if (++count == maxCount)
			break;
	}
}

/******************************************************************************
* Called when the associated main window is closed.
*/
void TrayWindow::removeWindow(MainWindow* win)
{
	if (win == mAssocMainWindow)
		mAssocMainWindow = 0;
}
<|endoftext|>


<commit_before>#include "UnrealEnginePythonPrivatePCH.h"

PyObject *py_ue_asset_import_data(ue_PyUObject * self, PyObject * args) {

	ue_py_check(self);

	UStruct *u_struct = (UStruct *)self->ue_object->GetClass();
	UClassProperty *u_property = (UClassProperty *)u_struct->FindPropertyByName(TEXT("AssetImportData"));
	if (!u_property) {
		return PyErr_Format(PyExc_Exception, "UObject does not have asset import data.");

	}
	UAssetImportData *import_data = (UAssetImportData *)u_property->GetPropertyValue_InContainer(self->ue_object);
	FString absolute_filepath = import_data->ResolveImportFilename(import_data->GetFirstFilename(), NULL);

	PyObject *ret = PyDict_New();
	PyDict_SetItemString(ret, "absolute_filepath", PyUnicode_FromString(TCHAR_TO_UTF8(*absolute_filepath)));
	PyDict_SetItemString(ret, "relative_filepath", PyUnicode_FromString(TCHAR_TO_UTF8(*import_data->GetFirstFilename())));

	return ret;
}
<commit_msg>Refactors get_asset_import_data to return list of dicts.   Previously the data returned was not entirely accurate and   this change is more future proof in case assets were imported   from more than one file.<commit_after>#include "UnrealEnginePythonPrivatePCH.h"

PyObject *py_ue_asset_import_data(ue_PyUObject * self, PyObject * args) {

	ue_py_check(self);

	UStruct *u_struct = (UStruct *)self->ue_object->GetClass();
	UClassProperty *u_property = (UClassProperty *)u_struct->FindPropertyByName(TEXT("AssetImportData"));
	if (!u_property) {
		return PyErr_Format(PyExc_Exception, "UObject does not have asset import data.");

	}
	UAssetImportData *import_data = (UAssetImportData *)u_property->GetPropertyValue_InContainer(self->ue_object);
	FAssetImportInfo *import_info = &import_data->SourceData;
	PyObject *ret = PyList_New(import_info->SourceFiles.Num());
	for (int i=0; i < import_info->SourceFiles.Num(); i++) {
		PyObject *py_source_file = PyDict_New();
		PyDict_SetItemString(py_source_file, "absolute_filepath", PyUnicode_FromString(TCHAR_TO_UTF8(*import_data->ResolveImportFilename(import_info->SourceFiles[i].RelativeFilename, NULL))));
		PyDict_SetItemString(py_source_file, "relative_filepath", PyUnicode_FromString(TCHAR_TO_UTF8(*import_info->SourceFiles[i].RelativeFilename)));
		PyDict_SetItemString(py_source_file, "timestamp", PyLong_FromLong(import_info->SourceFiles[i].Timestamp.ToUnixTimestamp()));
		PyDict_SetItemString(py_source_file, "filehash", PyUnicode_FromString(TCHAR_TO_UTF8(*LexicalConversion::ToString(import_info->SourceFiles[i].FileHash))));
		PyList_SetItem(ret, i, py_source_file);
	}
	return ret;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTubeSpatialObjectTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

/*
* itkTubeSpatialObject test file.
* This test file test also the basic functions of the CompositeSpatialObject class,
* like Add/RemoveSpatialObject(...), Get/SetChildren(...), etc...
*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPoint.h"
#include "itkVector.h"
#include "itkAffineTransform.h"
#include "itkTubeSpatialObjectPoint.h"
#include "itkTubeSpatialObject.h"
#include "itkGroupSpatialObject.h"
#include "itkExceptionObject.h"

#include <vnl/vnl_math.h>

int itkTubeSpatialObjectTest(int, char * [] )
{
  typedef double                                      ScalarType;
  typedef bool                                        OutputType;
  typedef itk::Vector< ScalarType, 3>                 Vector;
  typedef itk::Vector< OutputType, 3>                 OutputVector;
  typedef itk::Point< ScalarType, 3>                  Point;
  typedef itk::Matrix< ScalarType, 3, 3>              Matrix;
  typedef itk::TubeSpatialObject<3>                   TubeType;
  typedef itk::SmartPointer< TubeType >               TubePointer;
  typedef itk::GroupSpatialObject<3>                  GroupType;
  typedef itk::SmartPointer< GroupType >              GroupPointer;
  typedef TubeType::TubePointType                     TubePointType;
  typedef TubeType::PointListType                     TubePointListType;
  typedef std::list< itk::SpatialObject<3>::Pointer > ChildrenListType;
  typedef ChildrenListType *                          ChildrenListPointer;

  Vector axis, translation;
  Point in, out;
  double angle;
  bool passed = true;

  //======================================
  // testing of a single SpatialObject...
  //======================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube1 = TubeType::New();
  tube1->GetProperty()->SetName("Tube 1");
  tube1->SetId(1);

  TubePointListType list;

  TubeType::TransformType::OffsetType offset;
  offset.Fill(10);
  tube1->GetObjectToParentTransform()->SetOffset(offset);
  tube1->ComputeObjectToWorldTransform();

  for( unsigned int i=0; i<10; i++)
    {
    TubePointType p;
    p.SetPosition(i,i,i);
    p.SetRadius(1);
    list.push_back(p);
    }

  // For coverage
  TubePointType p;
  p.SetPosition(1,2,3);
  p.SetRadius(1);
  p.Print(std::cout);

  tube1->SetPoints(list);
  tube1->ComputeBoundingBox();

  in.Fill(15);
  out.Fill(5);

  std::cout<<"IsInside()...";
  if( !tube1->IsInside(in) || tube1->IsInside(out) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  TubeType::OutputVectorType derivative;

  std::cout<<"DerivativeAt()...";
  try
    {
    tube1->DerivativeAt(in,1,derivative);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  TubeType::OutputVectorType expectedDerivative;
  expectedDerivative.Fill(0);

  if( expectedDerivative != derivative )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"itkTubeSpatialObjectTest ";
  if( passed )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  //==============================================
  // testing of a single CompositeSpatialObject...
  //==============================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing GroupSpatialObject:"<<std::endl<<std::endl;

  ChildrenListType childrenList;
  ChildrenListPointer returnedList;
  unsigned int nbChildren;

  TubePointer tube2 = TubeType::New();
  tube2->GetProperty()->SetName("Tube 2");
  tube2->SetId(2);
  tube2->SetPoints(list);
  tube2->ComputeBoundingBox();

  TubePointer tube3 = TubeType::New();
  tube3->GetProperty()->SetName("Tube 3");
  tube3->SetId(3);
  tube3->SetPoints(list);
  tube3->ComputeBoundingBox();

  GroupPointer tubeNet1 = GroupType::New();
  tubeNet1->GetProperty()->SetName("tube network 1");

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the AddSpatialObject() function...
  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"AddSpatialObject()...";
  if( nbChildren != 3 )
    {
    std::cout<<"[FAILED] ["<< nbChildren << "!= 3]" << std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  // testing the RemoveSpatialObject() function...
  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"RemoveSpatialObject()...";
  if( nbChildren != 0 )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the GetChildren() function...
  childrenList.push_back( tube1.GetPointer() );
  childrenList.push_back( tube2.GetPointer() );
  childrenList.push_back( tube3.GetPointer() );

  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }

    }
  else
    {
    passed = false;
    }

  std::cout<<"GetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  delete returnedList;

  // testing the SetChildren() function...
  std::cout << "Set children ..." << std::endl;
  tubeNet1->SetChildren(childrenList);
  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    passed = true;

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }
    }
  else
    {
    passed = false;
    }

  delete returnedList;
  std::cout<<"SetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->ComputeBoundingBox();

  std::cout<<"HasParent()...";
  if( !tube2->HasParent() )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  translation.Fill(10);
  tubeNet1->GetObjectToParentTransform()->Translate(translation,false);
  tubeNet1->ComputeObjectToWorldTransform();

  axis.Fill(0);
  axis[1] = 1;
  angle = vnl_math::pi_over_2;
  tube2->GetObjectToParentTransform()->Rotate3D(axis,angle);
  tube2->ComputeObjectToWorldTransform();

  angle = -vnl_math::pi_over_2;
  tube3->GetObjectToParentTransform()->Rotate3D(axis,angle);
  tube3->ComputeObjectToWorldTransform();

  in.Fill(25);
  out.Fill(15);

  Point p1,p2;
  p1.Fill(15);
  p1[2]=5;
  p2.Fill(15);
  p2[0]=5;

  std::cout<<"IsInside()...";
  if( !tubeNet1->IsInside(in,3) || tubeNet1->IsInside(out,3) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"DerivativeAt()...";
  try
    {
    tubeNet1->DerivativeAt(in,(unsigned short)1,derivative,true);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  if( derivative == expectedDerivative )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  //====================================================
  // testing of references behavior for SpatialObject...
  //====================================================

  std::cout<<"=============================================="<<std::endl;
  std::cout<<"Testing references behavior for SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube = TubeType::New();
  GroupPointer net = GroupType::New();

  unsigned int tubeCount, netCount;
  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  std::cout<<"References test...";
  if( tubeCount != 2 )
    {
    std::cout<<"[FAILED]: Problem in Tube initialization of references count" << tubeCount <<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    TubePointer localTube = tube;
    tubeCount = tube->GetReferenceCount();
    if( tubeCount != 3 )
      {
      std::cout<<"[FAILED]: Problem in Tube with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  if( netCount != 2 )
    {
    std::cout<<"[FAILED]: Problem in TubeNetwork initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    GroupPointer localNet = net;
    netCount = net->GetReferenceCount();
    if( netCount != 3 )
      {
      std::cout<<"[FAILED]: Problem in TubeNetwork with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  if( tubeCount != 2 )
    {
      std::cout<<"[FAILED]: Problem in Tube with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  if( netCount != 2 )
    {
      std::cout<<"[FAILED]: Problem in TubeNetwork with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  std::cout<<"[PASSED]"<<std::endl;

  // Testing Set/GetParentPoint
  std::cout << "Set/GetParentPoint: ";

  tube->SetParentPoint(1);
  if(tube->GetParentPoint() !=1)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  std::cout<<"[PASSED]"<<std::endl;

  return EXIT_SUCCESS;

}
<commit_msg>FIX: Reference counts were not valid<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTubeSpatialObjectTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

/*
* itkTubeSpatialObject test file.
* This test file test also the basic functions of the CompositeSpatialObject class,
* like Add/RemoveSpatialObject(...), Get/SetChildren(...), etc...
*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPoint.h"
#include "itkVector.h"
#include "itkAffineTransform.h"
#include "itkTubeSpatialObjectPoint.h"
#include "itkTubeSpatialObject.h"
#include "itkGroupSpatialObject.h"
#include "itkExceptionObject.h"

#include <vnl/vnl_math.h>

int itkTubeSpatialObjectTest(int, char * [] )
{
  typedef double                                      ScalarType;
  typedef bool                                        OutputType;
  typedef itk::Vector< ScalarType, 3>                 Vector;
  typedef itk::Vector< OutputType, 3>                 OutputVector;
  typedef itk::Point< ScalarType, 3>                  Point;
  typedef itk::Matrix< ScalarType, 3, 3>              Matrix;
  typedef itk::TubeSpatialObject<3>                   TubeType;
  typedef itk::SmartPointer< TubeType >               TubePointer;
  typedef itk::GroupSpatialObject<3>                  GroupType;
  typedef itk::SmartPointer< GroupType >              GroupPointer;
  typedef TubeType::TubePointType                     TubePointType;
  typedef TubeType::PointListType                     TubePointListType;
  typedef std::list< itk::SpatialObject<3>::Pointer > ChildrenListType;
  typedef ChildrenListType *                          ChildrenListPointer;

  Vector axis, translation;
  Point in, out;
  double angle;
  bool passed = true;

  //======================================
  // testing of a single SpatialObject...
  //======================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube1 = TubeType::New();
  tube1->GetProperty()->SetName("Tube 1");
  tube1->SetId(1);

  TubePointListType list;

  TubeType::TransformType::OffsetType offset;
  offset.Fill(10);
  tube1->GetObjectToParentTransform()->SetOffset(offset);
  tube1->ComputeObjectToWorldTransform();

  for( unsigned int i=0; i<10; i++)
    {
    TubePointType p;
    p.SetPosition(i,i,i);
    p.SetRadius(1);
    list.push_back(p);
    }

  // For coverage
  TubePointType p;
  p.SetPosition(1,2,3);
  p.SetRadius(1);
  p.Print(std::cout);

  tube1->SetPoints(list);
  tube1->ComputeBoundingBox();

  in.Fill(15);
  out.Fill(5);

  std::cout<<"IsInside()...";
  if( !tube1->IsInside(in) || tube1->IsInside(out) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  TubeType::OutputVectorType derivative;

  std::cout<<"DerivativeAt()...";
  try
    {
    tube1->DerivativeAt(in,1,derivative);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  TubeType::OutputVectorType expectedDerivative;
  expectedDerivative.Fill(0);

  if( expectedDerivative != derivative )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"itkTubeSpatialObjectTest ";
  if( passed )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  //==============================================
  // testing of a single CompositeSpatialObject...
  //==============================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing GroupSpatialObject:"<<std::endl<<std::endl;

  ChildrenListType childrenList;
  ChildrenListPointer returnedList;
  unsigned int nbChildren;

  TubePointer tube2 = TubeType::New();
  tube2->GetProperty()->SetName("Tube 2");
  tube2->SetId(2);
  tube2->SetPoints(list);
  tube2->ComputeBoundingBox();

  TubePointer tube3 = TubeType::New();
  tube3->GetProperty()->SetName("Tube 3");
  tube3->SetId(3);
  tube3->SetPoints(list);
  tube3->ComputeBoundingBox();

  GroupPointer tubeNet1 = GroupType::New();
  tubeNet1->GetProperty()->SetName("tube network 1");

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the AddSpatialObject() function...
  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"AddSpatialObject()...";
  if( nbChildren != 3 )
    {
    std::cout<<"[FAILED] ["<< nbChildren << "!= 3]" << std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  // testing the RemoveSpatialObject() function...
  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"RemoveSpatialObject()...";
  if( nbChildren != 0 )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the GetChildren() function...
  childrenList.push_back( tube1.GetPointer() );
  childrenList.push_back( tube2.GetPointer() );
  childrenList.push_back( tube3.GetPointer() );

  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }

    }
  else
    {
    passed = false;
    }

  std::cout<<"GetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  delete returnedList;

  // testing the SetChildren() function...
  std::cout << "Set children ..." << std::endl;
  tubeNet1->SetChildren(childrenList);
  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    passed = true;

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }
    }
  else
    {
    passed = false;
    }

  delete returnedList;
  std::cout<<"SetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->ComputeBoundingBox();

  std::cout<<"HasParent()...";
  if( !tube2->HasParent() )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  translation.Fill(10);
  tubeNet1->GetObjectToParentTransform()->Translate(translation,false);
  tubeNet1->ComputeObjectToWorldTransform();

  axis.Fill(0);
  axis[1] = 1;
  angle = vnl_math::pi_over_2;
  tube2->GetObjectToParentTransform()->Rotate3D(axis,angle);
  tube2->ComputeObjectToWorldTransform();

  angle = -vnl_math::pi_over_2;
  tube3->GetObjectToParentTransform()->Rotate3D(axis,angle);
  tube3->ComputeObjectToWorldTransform();

  in.Fill(25);
  out.Fill(15);

  Point p1,p2;
  p1.Fill(15);
  p1[2]=5;
  p2.Fill(15);
  p2[0]=5;

  std::cout<<"IsInside()...";
  if( !tubeNet1->IsInside(in,3) || tubeNet1->IsInside(out,3) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"DerivativeAt()...";
  try
    {
    tubeNet1->DerivativeAt(in,(unsigned short)1,derivative,true);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  if( derivative == expectedDerivative )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  //====================================================
  // testing of references behavior for SpatialObject...
  //====================================================

  std::cout<<"=============================================="<<std::endl;
  std::cout<<"Testing references behavior for SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube = TubeType::New();
  GroupPointer net = GroupType::New();

  unsigned int tubeCount, netCount;
  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  std::cout<<"References test...";
  if( tubeCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in Tube initialization of references count" << tubeCount <<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    TubePointer localTube = tube;
    tubeCount = tube->GetReferenceCount();
    if( tubeCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in Tube with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  if( netCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in TubeNetwork initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    GroupPointer localNet = net;
    netCount = net->GetReferenceCount();
    if( netCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in TubeNetwork with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  if( tubeCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in Tube with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  if( netCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in TubeNetwork with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  std::cout<<"[PASSED]"<<std::endl;

  // Testing Set/GetParentPoint
  std::cout << "Set/GetParentPoint: ";

  tube->SetParentPoint(1);
  if(tube->GetParentPoint() !=1)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  std::cout<<"[PASSED]"<<std::endl;

  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 client クラス
	@copyright Copyright 2017 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"

#include "r_net/ethernet_client.hpp"
#include "sample.hpp"

// #define CLIENT_DEBUG

namespace seeda {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  client クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class client {

#ifdef CLIENT_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		static const uint16_t PORT = 3000;	///< クライアント・ポート

		net::ethernet_client	client_;

		typedef utils::basic_format<net::ether_string<net::ethernet::format_id::client0, 2048> > format;

		enum class recv_task {
			idle,
			sync_time,
			sample_put,
		};
		recv_task	recv_task_;

		enum class send_task {
			idle,
			req_connect,
			wait_req_connect,
			wait_connect,
			make_form,
			url_decode,
			send_data,
			disconnect,
			sync_close,
		};
		send_task	send_task_;

		net::ip_address		ip_;

		uint16_t	port_;
		uint32_t	delay_;
		uint32_t	timeout_;
		uint32_t	re_connect_cnt_;

		time_t		time_org_;
		time_t		time_ref_;
		time_t		time_ofs_;
		time_t		time_;

		uint32_t	idle_count_;

		struct tm	tm_;

		static const uint32_t BUF_SIZE = 64;

		typedef utils::fixed_fifo<sample_t, BUF_SIZE> FIFO;
		FIFO	fifo_;

		char		form_[1024];
		char		data_[2048];

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
		*/
		//-----------------------------------------------------------------//
		client(net::ethernet& eth) : client_(eth, PORT),
			recv_task_(recv_task::idle), send_task_(send_task::idle),
#ifdef SEEDA
			ip_(192, 168, 1, 3),
#else
			ip_(192, 168, 3, 7),
#endif
			port_(PORT),
			delay_(0), timeout_(0), re_connect_cnt_(0),
			time_org_(0), time_ref_(0), time_ofs_(0), time_(0), idle_count_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの取得
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		const net::ip_address& get_ip() const { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの参照
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		net::ip_address& at_ip() { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの取得
			@return ポート
		*/
		//-----------------------------------------------------------------//
		uint16_t get_port() const { return port_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの設定
			@param[in]	port	ポート
		*/
		//-----------------------------------------------------------------//
		void set_port(uint16_t port) { port_ = port; }

		//-----------------------------------------------------------------//
		/*!
			@brief  接続開始
		*/
		//-----------------------------------------------------------------//
		void start_connect()
		{
			recv_task_ = recv_task::sync_time;
			send_task_ = send_task::req_connect;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  動作状態
			@return idle では無い場合[true」
		*/
		//-----------------------------------------------------------------//
		bool probe() const
		{
			if(send_task_ == send_task::req_connect) return false;
			if(send_task_ == send_task::wait_req_connect) return false;
			if(send_task_ == send_task::wait_connect) return false;
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
			@param[in]	cycle	サービス・サイクル（通常１００Ｈｚ）
		*/
		//-----------------------------------------------------------------//
		void service(uint32_t cycle)
		{
			++idle_count_;

			switch(recv_task_) {
			case recv_task::idle:
				break;

			case recv_task::sync_time:
				{
					const sample_data& smd = get_sample_data();
					if(time_ref_ != smd.time_) {
						time_ref_ = smd.time_;
						recv_task_ = recv_task::sample_put;
					}
				}
				break;

			case recv_task::sample_put:
				{
					if((BUF_SIZE - 1 - fifo_.length()) < get_channel_num()) { // スペースが無い場合
						break;
					}
					const sample_data& smd = get_sample_data();
					for(uint32_t i = 0; i < get_channel_num(); ++i) {
						fifo_.put(smd.smp_[i]);
					}
					recv_task_ = recv_task::sync_time;
				}
				break;
			}

			switch(send_task_) {

			case send_task::idle:
				break;

			case send_task::req_connect:
				if(client_.connect(ip_, port_, TMO_NBLK)) {
					re_connect_cnt_ = 0;
					timeout_ = 5 * cycle;  // 再接続待ち時間
					send_task_ = send_task::wait_connect;
				} else {
					timeout_ = 1 * cycle;
					send_task_ = send_task::wait_req_connect;
				}
				break;

			case send_task::wait_req_connect:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					send_task_ = send_task::req_connect;
				}
				break;

			case send_task::wait_connect:
				if(!client_.connected()) {
					if(timeout_ > 0) {
						--timeout_;
					} else {
						++re_connect_cnt_;
						auto st = client_.get_ethernet().get_stat(client_.get_cepid());
						debug_format("TCP Client re_connect(%d): status: %d, desc(%d)\n")
							% re_connect_cnt_ % static_cast<int>(st) % client_.get_cepid();
						// 接続しないので、「re_connect」要求を出してみる
						// ※ re_connect では、タイムアウト（１０分）を無効にする。
						client_.re_connect(ip_, port_);
						timeout_ = 5 * cycle;  // 再接続待ち時間
					}
				} else {
					debug_format("Start SEEDA03 Client: %s port(%d), fd(%d)\n")
						% ip_.c_str() % port_ % client_.get_cepid();
					format::chaout().set_fd(client_.get_cepid());
					// 以前接続してから、4 秒以上、の「間」がある場合、設定初期化
					if(idle_count_ > (cycle * 4)) {
						fifo_.clear();
/// utils::format("Reset fifo\n");
						time_org_ = get_time();
						time_ofs_ = time_ref_;
						time_     = time_ref_;
					}
					send_task_ = send_task::make_form;
				}
				break;

			case send_task::make_form:
				if(fifo_.length() < get_channel_num()) {
					break;
				}
				for(uint32_t ch = 0; ch < get_channel_num(); ++ch) {
					const auto& smd = fifo_.get_at();
					if(ch == 0) {
						time_t t = time_ - time_ofs_ + time_org_;
						struct tm* m = localtime(&t);
						tm_ = *m;
						utils::sformat("%04d/%02d/%02d,%02d:%02d:%02d", form_, sizeof(form_))
							% static_cast<uint32_t>(tm_.tm_year + 1900)
							% static_cast<uint32_t>(tm_.tm_mon + 1)
							% static_cast<uint32_t>(tm_.tm_mday)
							% static_cast<uint32_t>(tm_.tm_hour)
							% static_cast<uint32_t>(tm_.tm_min)
							% static_cast<uint32_t>(tm_.tm_sec);
						++time_;
					}
					utils::sformat(",", form_, sizeof(form_), true);
					smd.make_csv2(form_, sizeof(form_), true);
					fifo_.get_go();
				}
				utils::sformat("\n", form_, sizeof(form_), true);
				send_task_ = send_task::url_decode;
				break;

			case send_task::url_decode:
				utils::str::url_decode_to_str(form_, data_, sizeof(data_));
				send_task_ = send_task::send_data;
				break;

			case send_task::send_data:
				format::chaout().clear();
				format("POST /api/?val=%s HTTP/1.1\n") % data_;
				format("Host: %d.%d.%d.%d\n")
					% static_cast<int>(ip_[0])
					% static_cast<int>(ip_[1])
					% static_cast<int>(ip_[2])
					% static_cast<int>(ip_[3]);
				format("Content-Type: application/x-www-form-urlencoded\n");
				format("User-Agent: SEEDA03 Post Client\n");
				format("Connection: close\n\n");
				format::chaout().flush();
				send_task_ = send_task::disconnect;
				break;

			case send_task::disconnect:
				client_.stop();
				timeout_ = 0;
				send_task_ = send_task::sync_close;
				break;

			case send_task::sync_close:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					idle_count_ = 0;
					debug_format("Client disconnected: %s\n") % ip_.c_str();
					send_task_ = send_task::req_connect;
				}
				break;
			}
		}
	};
}
<commit_msg>fix time stamp<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 client クラス
	@copyright Copyright 2017 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"

#include "r_net/ethernet_client.hpp"
#include "sample.hpp"

// #define CLIENT_DEBUG

namespace seeda {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  client クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class client {

#ifdef CLIENT_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		static const uint16_t PORT = 3000;	///< クライアント・ポート

		net::ethernet_client	client_;

		typedef utils::basic_format<net::ether_string<net::ethernet::format_id::client0, 2048> > format;

		enum class recv_task {
			idle,
			sync_time,
			sample_put,
		};
		recv_task	recv_task_;

		enum class send_task {
			idle,
			req_connect,
			wait_req_connect,
			wait_connect,
			make_form,
			url_decode,
			send_data,
			disconnect,
			sync_close,
		};
		send_task	send_task_;

		net::ip_address		ip_;

		uint16_t	port_;
		uint32_t	delay_;
		uint32_t	timeout_;
		uint32_t	re_connect_cnt_;

		time_t		time_org_;
		time_t		time_ref_;
		time_t		time_ofs_;
		time_t		time_;

		uint32_t	idle_count_;

		struct tm	tm_;

		static const uint32_t BUF_SIZE = 64;

		typedef utils::fixed_fifo<sample_t, BUF_SIZE> FIFO;
		FIFO	fifo_;

		char		form_[1024];
		char		data_[2048];

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
		*/
		//-----------------------------------------------------------------//
		client(net::ethernet& eth) : client_(eth, PORT),
			recv_task_(recv_task::idle), send_task_(send_task::idle),
#ifdef SEEDA
			ip_(192, 168, 1, 3),
#else
			ip_(192, 168, 3, 7),
#endif
			port_(PORT),
			delay_(0), timeout_(0), re_connect_cnt_(0),
			time_org_(0), time_ref_(0), time_ofs_(0), time_(0), idle_count_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの取得
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		const net::ip_address& get_ip() const { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの参照
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		net::ip_address& at_ip() { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの取得
			@return ポート
		*/
		//-----------------------------------------------------------------//
		uint16_t get_port() const { return port_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの設定
			@param[in]	port	ポート
		*/
		//-----------------------------------------------------------------//
		void set_port(uint16_t port) { port_ = port; }

		//-----------------------------------------------------------------//
		/*!
			@brief  接続開始
		*/
		//-----------------------------------------------------------------//
		void start_connect()
		{
			recv_task_ = recv_task::sync_time;
			send_task_ = send_task::req_connect;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  動作状態
			@return idle では無い場合[true」
		*/
		//-----------------------------------------------------------------//
		bool probe() const
		{
			if(send_task_ == send_task::req_connect) return false;
			if(send_task_ == send_task::wait_req_connect) return false;
			if(send_task_ == send_task::wait_connect) return false;
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
			@param[in]	cycle	サービス・サイクル（通常１００Ｈｚ）
		*/
		//-----------------------------------------------------------------//
		void service(uint32_t cycle)
		{
			++idle_count_;

			switch(recv_task_) {
			case recv_task::idle:
				break;

			case recv_task::sync_time:
				{
					const sample_data& smd = get_sample_data();
					if(time_ref_ != smd.time_) {
						time_ref_ = smd.time_;
						recv_task_ = recv_task::sample_put;
					}
				}
				break;

			case recv_task::sample_put:
				{
					if((BUF_SIZE - 1 - fifo_.length()) < get_channel_num()) { // スペースが無い場合
						break;
					}
					const sample_data& smd = get_sample_data();
					for(uint32_t i = 0; i < get_channel_num(); ++i) {
						fifo_.put(smd.smp_[i]);
					}
					recv_task_ = recv_task::sync_time;
				}
				break;
			}

			switch(send_task_) {

			case send_task::idle:
				time_org_ = get_time();
				break;

			case send_task::req_connect:
				if(client_.connect(ip_, port_, TMO_NBLK)) {
					re_connect_cnt_ = 0;
					timeout_ = 5 * cycle;  // 再接続待ち時間
					send_task_ = send_task::wait_connect;
				} else {
					timeout_ = 1 * cycle;
					send_task_ = send_task::wait_req_connect;
				}
				break;

			case send_task::wait_req_connect:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					send_task_ = send_task::req_connect;
				}
				break;

			case send_task::wait_connect:
				if(!client_.connected()) {
					if(timeout_ > 0) {
						--timeout_;
					} else {
						++re_connect_cnt_;
						auto st = client_.get_ethernet().get_stat(client_.get_cepid());
						debug_format("TCP Client re_connect(%d): status: %d, desc(%d)\n")
							% re_connect_cnt_ % static_cast<int>(st) % client_.get_cepid();
						// 接続しないので、「re_connect」要求を出してみる
						// ※ re_connect では、タイムアウト（１０分）を無効にする。
						client_.re_connect(ip_, port_);
						timeout_ = 5 * cycle;  // 再接続待ち時間
					}
				} else {
					time_org_ = get_time();
					debug_format("Start SEEDA03 Client: %s port(%d), fd(%d)\n")
						% ip_.c_str() % port_ % client_.get_cepid();
					format::chaout().set_fd(client_.get_cepid());
					// 以前接続してから、4 秒以上、の「間」がある場合、設定初期化
					if(idle_count_ > (cycle * 4)) {
						fifo_.clear();
/// utils::format("Reset fifo\n");
						time_ofs_ = time_ref_;
						time_     = time_ref_;
					}
					send_task_ = send_task::make_form;
				}
				break;

			case send_task::make_form:
				if(fifo_.length() < get_channel_num()) {
					break;
				}
				for(uint32_t ch = 0; ch < get_channel_num(); ++ch) {
					const auto& smd = fifo_.get_at();
					if(ch == 0) {
						time_t t = time_ - time_ofs_ + time_org_;
						struct tm* m = localtime(&t);
						tm_ = *m;
						utils::sformat("%04d/%02d/%02d,%02d:%02d:%02d", form_, sizeof(form_))
							% static_cast<uint32_t>(tm_.tm_year + 1900)
							% static_cast<uint32_t>(tm_.tm_mon + 1)
							% static_cast<uint32_t>(tm_.tm_mday)
							% static_cast<uint32_t>(tm_.tm_hour)
							% static_cast<uint32_t>(tm_.tm_min)
							% static_cast<uint32_t>(tm_.tm_sec);
						++time_;
					}
					utils::sformat(",", form_, sizeof(form_), true);
					smd.make_csv2(form_, sizeof(form_), true);
					fifo_.get_go();
				}
				utils::sformat("\n", form_, sizeof(form_), true);
				send_task_ = send_task::url_decode;
				break;

			case send_task::url_decode:
				utils::str::url_decode_to_str(form_, data_, sizeof(data_));
				send_task_ = send_task::send_data;
				break;

			case send_task::send_data:
				format::chaout().clear();
				format("POST /api/?val=%s HTTP/1.1\n") % data_;
				format("Host: %d.%d.%d.%d\n")
					% static_cast<int>(ip_[0])
					% static_cast<int>(ip_[1])
					% static_cast<int>(ip_[2])
					% static_cast<int>(ip_[3]);
				format("Content-Type: application/x-www-form-urlencoded\n");
				format("User-Agent: SEEDA03 Post Client\n");
				format("Connection: close\n\n");
				format::chaout().flush();
				send_task_ = send_task::disconnect;
				break;

			case send_task::disconnect:
				client_.stop();
				timeout_ = 0;
				send_task_ = send_task::sync_close;
				break;

			case send_task::sync_close:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					idle_count_ = 0;
					debug_format("Client disconnected: %s\n") % ip_.c_str();
					send_task_ = send_task::req_connect;
				}
				break;
			}
		}
	};
}
<|endoftext|>


<commit_before>/*
* Basic camera class
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>

class Camera
{
private:
	float fov;
	float znear, zfar;

	void updateViewMatrix()
	{
		glm::mat4 rotM = glm::mat4();
		glm::mat4 transM;

		rotM = glm::rotate(rotM, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
		rotM = glm::rotate(rotM, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
		rotM = glm::rotate(rotM, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));

		transM = glm::translate(glm::mat4(), position);

		if (type == CameraType::firstperson)
		{
			matrices.view = rotM * transM;
		}
		else
		{
			matrices.view = transM * rotM;
		}
	};
public:
	enum CameraType { lookat, firstperson };
	CameraType type = CameraType::lookat;

	glm::vec3 rotation = glm::vec3();
	glm::vec3 position = glm::vec3();

	float rotationSpeed = 1.0f;
	float movementSpeed = 1.0f;

	struct
	{
		glm::mat4 perspective;
		glm::mat4 view;
	} matrices;

	struct
	{
		bool left = false;
		bool right = false;
		bool up = false;
		bool down = false;
	} keys;

	bool moving()
	{
		return keys.left || keys.right || keys.up || keys.down;
	}

	void setPerspective(float fov, float aspect, float znear, float zfar)
	{
		this->fov = fov;
		this->znear = znear;
		this->zfar = zfar;
		matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
	};

	void updateAspectRatio(float aspect)
	{
		matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
	}

	void setRotation(glm::vec3 rotation)
	{
		this->rotation = rotation;
		updateViewMatrix();
	};

	void rotate(glm::vec3 delta)
	{
		this->rotation += delta;
		updateViewMatrix();
	}

	void setTranslation(glm::vec3 translation)
	{
		this->position = translation;
		updateViewMatrix();
	};

	void translate(glm::vec3 delta)
	{
		this->position += delta;
		updateViewMatrix();
	}

	void update(float deltaTime)
	{
		if (type == CameraType::firstperson)
		{
			if (moving())
			{
				glm::vec3 camFront;
				camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y));
				camFront.y = sin(glm::radians(rotation.x));
				camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y));
				camFront = glm::normalize(camFront);

				float moveSpeed = deltaTime * movementSpeed;

				if (keys.up)
					position += camFront * moveSpeed;
				if (keys.down)
					position -= camFront * moveSpeed;
				if (keys.left)
					position -= glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;
				if (keys.right)
					position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;

				updateViewMatrix();
			}
		}
	};

	// Update camera passing separate axis data (gamepad)
	// Returns true if view or position has been changed
	bool updatePad(glm::vec2 axisLeft, glm::vec2 axisRight, float deltaTime)
	{
		bool retVal = false;

		if (type == CameraType::firstperson)
		{
			// Use the common console thumbstick layout
			// Left = view, right = move

			const float deadZone = 0.0015f;
			const float range = 1.0f - deadZone;

			glm::vec3 camFront;
			camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y));
			camFront.y = sin(glm::radians(rotation.x));
			camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y));
			camFront = glm::normalize(camFront);

			float moveSpeed = deltaTime * movementSpeed * 2.0f;
			float rotSpeed = deltaTime * 50.0f;

			// Move
			if (fabsf(axisLeft.y) > deadZone)
			{
				float pos = (fabsf(axisLeft.y) - deadZone) / range;
				position -= camFront * pos * ((axisLeft.y < 0.0f) ? -1.0f : 1.0f) * moveSpeed;
				retVal = true;
			}
			if (fabsf(axisLeft.x) > deadZone)
			{
				float pos = (fabsf(axisLeft.x) - deadZone) / range;
				position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * pos * ((axisLeft.x < 0.0f) ? -1.0f : 1.0f) * moveSpeed;
				retVal = true;
			}

			// Rotate
			if (fabsf(axisRight.x) > deadZone)
			{
				float pos = (fabsf(axisRight.x) - deadZone) / range;
				rotation.y += pos * ((axisRight.x < 0.0f) ? -1.0f : 1.0f) * rotSpeed;
				retVal = true;
			}
			if (fabsf(axisRight.y) > deadZone)
			{
				float pos = (fabsf(axisRight.y) - deadZone) / range;
				rotation.x -= pos * ((axisRight.y < 0.0f) ? -1.0f : 1.0f) * rotSpeed;
				retVal = true;
			}
		}
		else
		{
			// todo: move code from example base class for look-at
		}

		if (retVal)
		{
			updateViewMatrix();
		}

		return retVal;
	}

};<commit_msg>Apply rotation speed for mouse input<commit_after>/*
* Basic camera class
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>

class Camera
{
private:
	float fov;
	float znear, zfar;

	void updateViewMatrix()
	{
		glm::mat4 rotM = glm::mat4();
		glm::mat4 transM;

		rotM = glm::rotate(rotM, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
		rotM = glm::rotate(rotM, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
		rotM = glm::rotate(rotM, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));

		transM = glm::translate(glm::mat4(), position);

		if (type == CameraType::firstperson)
		{
			matrices.view = rotM * transM;
		}
		else
		{
			matrices.view = transM * rotM;
		}
	};
public:
	enum CameraType { lookat, firstperson };
	CameraType type = CameraType::lookat;

	glm::vec3 rotation = glm::vec3();
	glm::vec3 position = glm::vec3();

	float rotationSpeed = 1.0f;
	float movementSpeed = 1.0f;

	struct
	{
		glm::mat4 perspective;
		glm::mat4 view;
	} matrices;

	struct
	{
		bool left = false;
		bool right = false;
		bool up = false;
		bool down = false;
	} keys;

	bool moving()
	{
		return keys.left || keys.right || keys.up || keys.down;
	}

	void setPerspective(float fov, float aspect, float znear, float zfar)
	{
		this->fov = fov;
		this->znear = znear;
		this->zfar = zfar;
		matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
	};

	void updateAspectRatio(float aspect)
	{
		matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
	}

	void setRotation(glm::vec3 rotation)
	{
		this->rotation = rotation;
		updateViewMatrix();
	};

	void rotate(glm::vec3 delta)
	{
		this->rotation += delta;
		updateViewMatrix();
	}

	void setTranslation(glm::vec3 translation)
	{
		this->position = translation;
		updateViewMatrix();
	};

	void translate(glm::vec3 delta)
	{
		this->position += delta;
		updateViewMatrix();
	}

	void update(float deltaTime)
	{
		if (type == CameraType::firstperson)
		{
			if (moving())
			{
				glm::vec3 camFront;
				camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y));
				camFront.y = sin(glm::radians(rotation.x));
				camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y));
				camFront = glm::normalize(camFront);

				float moveSpeed = deltaTime * movementSpeed;

				if (keys.up)
					position += camFront * moveSpeed;
				if (keys.down)
					position -= camFront * moveSpeed;
				if (keys.left)
					position -= glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;
				if (keys.right)
					position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;

				updateViewMatrix();
			}
		}
	};

	// Update camera passing separate axis data (gamepad)
	// Returns true if view or position has been changed
	bool updatePad(glm::vec2 axisLeft, glm::vec2 axisRight, float deltaTime)
	{
		bool retVal = false;

		if (type == CameraType::firstperson)
		{
			// Use the common console thumbstick layout
			// Left = view, right = move

			const float deadZone = 0.0015f;
			const float range = 1.0f - deadZone;

			glm::vec3 camFront;
			camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y));
			camFront.y = sin(glm::radians(rotation.x));
			camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y));
			camFront = glm::normalize(camFront);

			float moveSpeed = deltaTime * movementSpeed * 2.0f;
			float rotSpeed = deltaTime * rotationSpeed * 50.0f;

			// Move
			if (fabsf(axisLeft.y) > deadZone)
			{
				float pos = (fabsf(axisLeft.y) - deadZone) / range;
				position -= camFront * pos * ((axisLeft.y < 0.0f) ? -1.0f : 1.0f) * moveSpeed;
				retVal = true;
			}
			if (fabsf(axisLeft.x) > deadZone)
			{
				float pos = (fabsf(axisLeft.x) - deadZone) / range;
				position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * pos * ((axisLeft.x < 0.0f) ? -1.0f : 1.0f) * moveSpeed;
				retVal = true;
			}

			// Rotate
			if (fabsf(axisRight.x) > deadZone)
			{
				float pos = (fabsf(axisRight.x) - deadZone) / range;
				rotation.y += pos * ((axisRight.x < 0.0f) ? -1.0f : 1.0f) * rotSpeed;
				retVal = true;
			}
			if (fabsf(axisRight.y) > deadZone)
			{
				float pos = (fabsf(axisRight.y) - deadZone) / range;
				rotation.x -= pos * ((axisRight.y < 0.0f) ? -1.0f : 1.0f) * rotSpeed;
				retVal = true;
			}
		}
		else
		{
			// todo: move code from example base class for look-at
		}

		if (retVal)
		{
			updateViewMatrix();
		}

		return retVal;
	}

};<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "robot_utils/ros_thread_image.h"
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

static const std::string OPENCV_WINDOW = "Image window";

using namespace cv;
using namespace std;

class ROSThreadImageTester
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Publisher image_pub_;
  std::string name;

public:
  explicit ROSThreadImageTester(std::string _name)
    : it_(nh_), name(_name)
  {
   image_pub_ = it_.advertise("/"+name+"/image", 1);
  }

  ~ROSThreadImageTester() {}

  void sendTestImage()
  {
    cv::Mat img(200, 200, CV_8UC3, cv::Scalar(0,0,0));
    cv::waitKey(30);
    cv::circle(img, cv::Point(100, 100), 20, CV_RGB(255,0,0), -1);
    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", img).toImageMsg();
    image_pub_.publish(msg);
  }
};

class ROSImageInstance: public ROSThreadImage
{
private:
  int xcoord;
  int ycoord;

public:
    explicit ROSImageInstance(std::string namenew): ROSThreadImage(namenew), xcoord(-1), ycoord(-1) {}

    void InternalThreadEntry()
    {
        while(ros::ok())
        {
            cv::Mat img_in;

            if (!_img_empty)
            {
                ROS_INFO("Processing image");
                pthread_mutex_lock(&_mutex_img);
                img_in=_curr_img;
                pthread_mutex_unlock(&_mutex_img);

                cv::Mat gray;
                cv::cvtColor(img_in, gray, CV_BGR2GRAY);
                std::vector<vector<Point>> contours;
                findContours(gray, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0,0));

                //Finds the moments
                vector<Moments> mu(contours.size() );
                for(unsigned int i = 0; i < contours.size(); i++ )
                {
                    mu[i] = moments(contours[i], false );
                }

                //Finds the Centroid
                vector<Point2f> mc( contours.size());
                for( unsigned int i = 0; i < contours.size(); i++ )
                {
                    mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
                    xcoord = mu[i].m10/mu[i].m00;
                    ycoord = mu[i].m01/mu[i].m00;
                }

                break;
            }
            r.sleep();
        }
      }
    int getx() {return xcoord;}
    int gety() {return ycoord;}

    void printx() {std::cout<<"The calculated x-coord of the centroid of the cirlce is " << xcoord<< " [Expected value: 100]"<<std::endl;}
    void printy() {std::cout<<"The calculated y-coord of the centroid of the circle is " << ycoord<< " [Expected value: 100]"<<std::endl;}
};

TEST(rosimagetest, testsetname)
{
    ROSThreadImageTester rtit("test");
    ROSImageInstance rtii("test");

    rtit.sendTestImage();
    ros::Rate rate(100);

    while(ros::ok() && (rtii.getx() == -1 || rtii.gety() == -1))
    {
        ROS_INFO("Waiting for ROSThreadImage loop. [x y]: [%i %i]", rtii.getx(), rtii.gety());
        rate.sleep();
    }

    rtii.printx();
    rtii.printy();

    rtii.setName("newtestname");

    //Checks that x and y coordinates are correct
    EXPECT_TRUE(rtii.getx() == 100);
    EXPECT_TRUE(rtii.gety() == 100);

    //Checks that name is correct
    EXPECT_EQ("newtestname", rtii.getName());
    EXPECT_FALSE("test" == rtii.getName());
}

// Run all the tests that were declared with TEST()
int main(int argc, char **argv)
{
    ros::init(argc, argv, "ros_thread_test");
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<commit_msg>Fixed Codacy issue<commit_after>#include <gtest/gtest.h>
#include "robot_utils/ros_thread_image.h"
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

static const std::string OPENCV_WINDOW = "Image window";

using namespace cv;
using namespace std;

class ROSThreadImageTester
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Publisher image_pub_;
  std::string name;

public:
  explicit ROSThreadImageTester(std::string _name)
    : it_(nh_), name(_name)
  {
   image_pub_ = it_.advertise("/"+name+"/image", 1);
  }

  ~ROSThreadImageTester() {}

  void sendTestImage()
  {
    cv::Mat img(200, 200, CV_8UC3, cv::Scalar(0,0,0));
    cv::waitKey(30);
    cv::circle(img, cv::Point(100, 100), 20, CV_RGB(255,0,0), -1);
    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", img).toImageMsg();
    image_pub_.publish(msg);
  }
};

class ROSImageInstance: public ROSThreadImage
{
private:
  int xcoord;
  int ycoord;

public:
    explicit ROSImageInstance(std::string namenew): ROSThreadImage(namenew), xcoord(-1), ycoord(-1) {}

    void InternalThreadEntry()
    {
        while(ros::ok())
        {
            cv::Mat img_in;

            if (not _img_empty)
            {
                ROS_INFO("Processing image");
                pthread_mutex_lock(&_mutex_img);
                img_in=_curr_img;
                pthread_mutex_unlock(&_mutex_img);

                cv::Mat gray;
                cv::cvtColor(img_in, gray, CV_BGR2GRAY);
                std::vector<vector<Point>> contours;
                findContours(gray, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0,0));

                //Finds the moments
                vector<Moments> mu(contours.size() );
                for(unsigned int i = 0; i < contours.size(); i++ )
                {
                    mu[i] = moments(contours[i], false );
                }

                //Finds the Centroid
                vector<Point2f> mc( contours.size());
                for( unsigned int i = 0; i < contours.size(); i++ )
                {
                    mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
                    xcoord = mu[i].m10/mu[i].m00;
                    ycoord = mu[i].m01/mu[i].m00;
                }

                break;
            }
            r.sleep();
        }
      }
    int getx() {return xcoord;}
    int gety() {return ycoord;}

    void printx() {std::cout<<"The calculated x-coord of the centroid of the cirlce is " << xcoord<< " [Expected value: 100]"<<std::endl;}
    void printy() {std::cout<<"The calculated y-coord of the centroid of the circle is " << ycoord<< " [Expected value: 100]"<<std::endl;}
};

TEST(rosimagetest, testsetname)
{
    ROSThreadImageTester rtit("test");
    ROSImageInstance rtii("test");

    rtit.sendTestImage();
    ros::Rate rate(100);

    while(ros::ok() && (rtii.getx() == -1 || rtii.gety() == -1))
    {
        ROS_INFO("Waiting for ROSThreadImage loop. [x y]: [%i %i]", rtii.getx(), rtii.gety());
        rate.sleep();
    }

    rtii.printx();
    rtii.printy();

    rtii.setName("newtestname");

    //Checks that x and y coordinates are correct
    EXPECT_TRUE(rtii.getx() == 100);
    EXPECT_TRUE(rtii.gety() == 100);

    //Checks that name is correct
    EXPECT_EQ("newtestname", rtii.getName());
    EXPECT_FALSE("test" == rtii.getName());
}

// Run all the tests that were declared with TEST()
int main(int argc, char **argv)
{
    ros::init(argc, argv, "ros_thread_test");
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <boost_common.h>
#include <boilerplate.cpp>
#include <autogen_converters.cpp>

bool VBoostedMaxEnt__wrap_train(VBoostedMaxEnt* inst,
                                PyObject* X_train,
                                PyObject* Y_train)
{
    PyArrayObject *xao = (PyArrayObject*)X_train;
    PyArrayObject *yao = (PyArrayObject*)Y_train;

    if (xao->dimensions[0] != yao->dimensions[0]) {
      printf("oh no, X train has %zu entries but Y train has %zu\n",
             xao->dimensions[0],
             yao->dimensions[0]);
    }

    vector<const vector<double>*> Xvec;
    vector<const vector<double>*> Yvec;

    for (int i=0; i<xao->dimensions[0]; i++) {
      vector<double> *tmp = new vector<double>(((double*)xao->data) + i*xao->dimensions[1],
                                               ((double*)xao->data) + (i+1)*xao->dimensions[1]);
      Xvec.push_back(const_cast<const vector<double>*>(tmp));

      tmp = new vector<double>(&(((double*)yao->data)[i*yao->dimensions[1]]),
                               &(((double*)yao->data)[(i+1)*yao->dimensions[1]]));
      double total_prob = 0.0;
      for (int j=0; j<yao->dimensions[1]; j++) {
          total_prob += (*tmp)[j];
      }
      Yvec.push_back(const_cast<const vector<double>*>(tmp));
    }
    vector<double> w_fold(Xvec.size(), 1.0);
    inst->train(Xvec, Yvec, w_fold, NULL, NULL);

    for (int i=0; i<xao->dimensions[0]; i++) {
      delete Xvec[i];
      delete Yvec[i];
    }
    return false;
}

PyObject* VBoostedMaxEnt__wrap_predict(VBoostedMaxEnt* inst,
                                       vector<double> query)
{
    vector<double> ret(2);
    inst->predict(query, ret);
    return vec_to_numpy(ret);
}

vector<VRandomForest*> VBoostedMaxEnt__get_vec_vrandomforest(VBoostedMaxEnt* inst)
{
  vector<VRandomForest*> ret;
  foreach (it, inst->m_vregressors) {
    /* C++ is beautiful:
     * - the innermost * dereferences the iterator;
     * - the next * dereferences the shared ptr;
     * - the & gets the address of the actual object, because boost can't deal with std
     *     tr1 shared ptrs
     * - it's officially a vector of VRegressors, but we happen to know they're really
     *     VRandomForests, so cast.
     */
    ret.push_back((VRandomForest*)&(*(*it)));
  }
  return ret;
}
/* at some point I gotta figure out how to make readonly properties of pointer
 * fields without this crap
 */
VRandomForest::VTreeNode* VTreeNode__get_left(VRandomForest::VTreeNode* inst)
{
    return inst->left;
}
VRandomForest::VTreeNode* VTreeNode__get_right(VRandomForest::VTreeNode* inst)
{
    return inst->right;
}

void VTreeNode__refill_avg_outputs(VRandomForest::VTreeNode *inst)
{
    if (inst->avg_output.size() > 0)
        return;

    if (inst->left->avg_output.size() == 0)
        VTreeNode__refill_avg_outputs(inst->left);
    if (inst->right->avg_output.size() == 0)
        VTreeNode__refill_avg_outputs(inst->right);

    for (int i=0; i<inst->left->avg_output.size(); i++) {
        inst->avg_output.push_back((inst->left->avg_output[i] +
                                    inst->right->avg_output[i]) / 2.0);
    }
}

void VRandomForest__wrap_train(VRandomForest *inst,
                                 pyarr<double> X,
                                 pyarr<double> Y)
{
    vector<const vector<double>*> Xv, Yv;
    for (int i=0; i<X.dims[0]; i++) {
        vector<double>* Xtmp = new vector<double>(X.dims[1]);
        vector<double>* Ytmp = new vector<double>(Y.dims[1]);
        for (int j=0; j<X.dims[1]; j++) {
            (*Xtmp)[j] = X[ind(i,j)];
        }
        for (int j=0; j<Y.dims[1]; j++) {
            (*Ytmp)[j] = Y[ind(i,j)];
        }
        Xv.push_back(const_cast<const vector<double>*>(Xtmp));
        Yv.push_back(const_cast<const vector<double>*>(Ytmp));
    }
    vector<double> weights(X.dims[0], 1.0), feature_costs;
    vector<size_t> usable_features, required_features;

    inst->train(X.dims[1], Y.dims[1],
                Xv, Yv, weights, usable_features, feature_costs, required_features);
    for (int i=0; i<X.dims[0]; i++) {
        delete Xv[i];
        delete Yv[i];
    }
}

pyarr<double> VRandomForest__wrap_doPredict(VRandomForest *inst,
                                            pyarr<double> X)
{
    long int argh[] = {inst->getDimTarget()};
    pyarr<double> ret(1, argh);

    vector<double> xv(X.dims[0]), yv(ret.dims[0]);
    for (int i=0; i<X.dims[0]; i++) {
        xv[i] = X[ind(i)];
    }
    inst->doPredict(xv, yv);
    for (int i=0; i<ret.dims[0]; i++){
        ret[ind(i)] = yv[i];
    }
    return ret;
}

void set_logger_verbosity(string verbosity)
{
    misc_util::Logger::status_t s;
    if (verbosity == "debug") s = misc_util::Logger::DEBUG;
    else if (verbosity == "info") s = misc_util::Logger::INFO;
    else if (verbosity == "warning") s = misc_util::Logger::WARNING;
    else if (verbosity == "error") s = misc_util::Logger::ERROR;
    else s = misc_util::Logger::INFO;

    misc_util::Logger::setVerbosity(s);
}

static bool boosted_common = false;

void boost_common()
{
    import_array();
    if (0 && boosted_common) return;
    boosted_common = true;

    long int dims[] = {10, 10, 10};
    pyarr<double> d(3, dims);
    pyarr<float> f(3, dims);
    pyarr<int> i(3, dims);
    pyarr<long int> l(3, dims);
    pyarr<unsigned char> uc(3, dims);
    pyarr<unsigned int> ui(3, dims);
    pyarr<char> c(3, dims);

    printf("d %d f %d i %d l %d uc %d ui %d c %d\n",
           d.ao->descr->type_num,
           f.ao->descr->type_num,
           i.ao->descr->type_num,
           l.ao->descr->type_num,
           uc.ao->descr->type_num,
           ui.ao->descr->type_num,
           c.ao->descr->type_num);

    to_python_converter<MatrixMap, MatrixMap_to_numpy_str>();
    MatrixMap_from_numpy_str();

    to_python_converter<d2d::SegmentMap, SegmentMap_to_numpy_str>();
    SegmentMap_from_numpy_str();

    to_python_converter<mxArray, mxArray_to_numpy_str>();
    mxArray_from_numpy_str();

    to_python_converter<f2d::Pixel2DData, Pixel2DData_to_numpy_str>();
    Pixel2DData_from_numpy_str();

    to_python_converter<LRgbImage, LRgbImage_to_numpy_str>();
    LRgbImage_from_numpy_str();

    to_python_converter<vector<double>, vec_to_numpy_str>();
    vec_from_numpy_str();

    register_autogen_converters();

    class_<std::pair<unsigned int, double> >("uint_double_pair")
        .def_readwrite("first", &std::pair<unsigned int, double>::first)
        .def_readwrite("second", &std::pair<unsigned int, double>::second)
        ;
    class_<vector<std::pair<unsigned int, double> > >("uint_double_pair_vec")
        .def(vector_indexing_suite<vector<std::pair<unsigned int, double> > >())
        ;
    class_<vector<vector<std::pair<unsigned int, double> > > >("uint_double_pair_vec_vec")
        .def(vector_indexing_suite<vector<vector<std::pair<unsigned int, double> > > >())
        ;
    def("set_logger_verbosity", set_logger_verbosity);

    class_<vector<string> >("string_vector")
	.def(vector_indexing_suite<vector<string > >() )
	;

}

static bool boosted_ml = false;

void boost_ml()
{
    if (0 && boosted_ml) return;
    boosted_ml = true;

    class_<VRandomForest::VTreeNode>("VTreeNode", init<>())
        .def_readwrite("is_leaf", &VRandomForest::VTreeNode::is_leaf)
        .def_readwrite("count", &VRandomForest::VTreeNode::count)
        .def_readwrite("dim", &VRandomForest::VTreeNode::dim)
        .def_readwrite("avg_output", &VRandomForest::VTreeNode::avg_output)
        .def("get_left", VTreeNode__get_left, return_value_policy<reference_existing_object>())
        .def("get_right", VTreeNode__get_right, return_value_policy<reference_existing_object>())
        .def("refill_avg_outputs", VTreeNode__refill_avg_outputs)

        .def_readonly("thresh", &VRandomForest::VTreeNode::thresh)
        ;

    class_<vector<VRandomForest::VTreeNode> >("VTreeNode_vec")
        .def(vector_indexing_suite<vector<VRandomForest::VTreeNode> >())
        ;

    class_<VRandomForest>("VRandomForest", init<int, int, int, double, double>())
        .def_readwrite("m_nbr_trees", &VRandomForest::m_nbr_trees)
        .def_readwrite("m_max_depth", &VRandomForest::m_max_depth)
        .def_readwrite("m_min_node_size", &VRandomForest::m_min_node_size)
        .def_readwrite("m_rdm_dim_percent", &VRandomForest::m_rdm_dim_percent)
        .def_readwrite("m_rdm_sample_percent", &VRandomForest::m_rdm_sample_percent)
        .def_readwrite("m_seeds", &VRandomForest::m_seeds)
        .def_readwrite("m_trees", &VRandomForest::m_trees)
        .def("save", &VRandomForest::save)
        .def("load", &VRandomForest::load)
        .def("train", VRandomForest__wrap_train)
        .def("doPredict", VRandomForest__wrap_doPredict)
        ;
    class_<vector<VRandomForest*> >("VRandomForest_vec")
        .def(vector_indexing_suite<vector<VRandomForest*> >())
        ;
    class_<VBoostedMaxEnt>("VBoostedMaxEnt", init<double, double, double, int, VRandomForest>())
        .def_readwrite("m_step_sizes", &VBoostedMaxEnt::m_step_sizes)
        .def_readwrite("m_dim", &VBoostedMaxEnt::m_dim)
        .def("get_vec_vrandomforest", VBoostedMaxEnt__get_vec_vrandomforest)
        .def("train", VBoostedMaxEnt__wrap_train)
        .def("predict", VBoostedMaxEnt__wrap_predict)
        .def("save", &VBoostedMaxEnt::save)
        .def("load", &VBoostedMaxEnt::load)
        ;
    class_<vector<VBoostedMaxEnt*> >("VBoostedMaxEnt_vec")
        .def(vector_indexing_suite<vector<VBoostedMaxEnt*> >())
        ;
}

BOOST_PYTHON_MODULE(libboost_common) {
    PyEval_InitThreads();
    import_array();
    ilInit();
    boost_common();
}
<commit_msg>(split) subbox fixes<commit_after>#include <boost_common.h>
#include <boilerplate.cpp>
#include <autogen_converters.cpp>

bool VBoostedMaxEnt__wrap_train(VBoostedMaxEnt* inst,
                                PyObject* X_train,
                                PyObject* Y_train)
{
    PyArrayObject *xao = (PyArrayObject*)X_train;
    PyArrayObject *yao = (PyArrayObject*)Y_train;

    if (xao->dimensions[0] != yao->dimensions[0]) {
      printf("oh no, X train has %zu entries but Y train has %zu\n",
             xao->dimensions[0],
             yao->dimensions[0]);
    }

    vector<const vector<double>*> Xvec;
    vector<const vector<double>*> Yvec;

    for (int i=0; i<xao->dimensions[0]; i++) {
      vector<double> *tmp = new vector<double>(((double*)xao->data) + i*xao->dimensions[1],
                                               ((double*)xao->data) + (i+1)*xao->dimensions[1]);
      Xvec.push_back(const_cast<const vector<double>*>(tmp));

      tmp = new vector<double>(&(((double*)yao->data)[i*yao->dimensions[1]]),
                               &(((double*)yao->data)[(i+1)*yao->dimensions[1]]));
      double total_prob = 0.0;
      for (int j=0; j<yao->dimensions[1]; j++) {
          total_prob += (*tmp)[j];
      }
      Yvec.push_back(const_cast<const vector<double>*>(tmp));
    }
    vector<double> w_fold(Xvec.size(), 1.0);
    inst->train(Xvec, Yvec, w_fold, NULL, NULL);

    for (int i=0; i<xao->dimensions[0]; i++) {
      delete Xvec[i];
      delete Yvec[i];
    }
    return false;
}

PyObject* VBoostedMaxEnt__wrap_predict(VBoostedMaxEnt* inst,
                                       vector<double> query)
{
    vector<double> ret(2);
    inst->predict(query, ret);
    return vec_to_numpy(ret);
}

vector<VRandomForest*> VBoostedMaxEnt__get_vec_vrandomforest(VBoostedMaxEnt* inst)
{
  vector<VRandomForest*> ret;
  foreach (it, inst->m_vregressors) {
    /* C++ is beautiful:
     * - the innermost * dereferences the iterator;
     * - the next * dereferences the shared ptr;
     * - the & gets the address of the actual object, because boost can't deal with std
     *     tr1 shared ptrs
     * - it's officially a vector of VRegressors, but we happen to know they're really
     *     VRandomForests, so cast.
     */
    ret.push_back((VRandomForest*)&(*(*it)));
  }
  return ret;
}
/* at some point I gotta figure out how to make readonly properties of pointer
 * fields without this crap
 */
VRandomForest::VTreeNode* VTreeNode__get_left(VRandomForest::VTreeNode* inst)
{
    return inst->left;
}
VRandomForest::VTreeNode* VTreeNode__get_right(VRandomForest::VTreeNode* inst)
{
    return inst->right;
}

void VTreeNode__refill_avg_outputs(VRandomForest::VTreeNode *inst)
{
    if (inst->avg_output.size() > 0)
        return;

    if (inst->left->avg_output.size() == 0)
        VTreeNode__refill_avg_outputs(inst->left);
    if (inst->right->avg_output.size() == 0)
        VTreeNode__refill_avg_outputs(inst->right);

    for (int i=0; i<inst->left->avg_output.size(); i++) {
        inst->avg_output.push_back((inst->left->avg_output[i] +
                                    inst->right->avg_output[i]) / 2.0);
    }
}

void VRandomForest__wrap_train(VRandomForest *inst,
                                 pyarr<double> X,
                                 pyarr<double> Y)
{
    if (X.dims[0] != Y.dims[0]) {
        printf("OH NO! X.dims[0] = %ld, Y.dims[0] = %ld\n",
               X.dims[0], Y.dims[0]);
        return;
    }
    vector<const vector<double>*> Xv, Yv;
    for (int i=0; i<X.dims[0]; i++) {
        vector<double>* Xtmp = new vector<double>(X.dims[1]);
        vector<double>* Ytmp = new vector<double>(Y.dims[1]);
        for (int j=0; j<X.dims[1]; j++) {
            (*Xtmp)[j] = X[ind(i,j)];
        }
        for (int j=0; j<Y.dims[1]; j++) {
            (*Ytmp)[j] = Y[ind(i,j)];
        }
        Xv.push_back(const_cast<const vector<double>*>(Xtmp));
        Yv.push_back(const_cast<const vector<double>*>(Ytmp));
    }
    vector<double> weights(X.dims[0], 1.0), feature_costs;
    vector<size_t> usable_features, required_features;

    inst->train(X.dims[1], Y.dims[1],
                Xv, Yv, weights, usable_features, feature_costs, required_features);
    for (int i=0; i<X.dims[0]; i++) {
        delete Xv[i];
        delete Yv[i];
    }
}

pyarr<double> VRandomForest__wrap_predict(VRandomForest *inst,
                                            pyarr<double> X)
{
    long int argh[] = {inst->getDimTarget()};
    pyarr<double> ret(1, argh);

    vector<double> xv(X.dims[0]), yv(ret.dims[0]);
    for (int i=0; i<X.dims[0]; i++) {
        xv[i] = X[ind(i)];
    }
    inst->predict(xv, yv);
    for (int i=0; i<ret.dims[0]; i++){
        ret[ind(i)] = yv[i];
    }
    return ret;
}

void set_logger_verbosity(string verbosity)
{
    misc_util::Logger::status_t s;
    if (verbosity == "debug") s = misc_util::Logger::DEBUG;
    else if (verbosity == "info") s = misc_util::Logger::INFO;
    else if (verbosity == "warning") s = misc_util::Logger::WARNING;
    else if (verbosity == "error") s = misc_util::Logger::ERROR;
    else s = misc_util::Logger::INFO;

    misc_util::Logger::setVerbosity(s);
}

static bool boosted_common = false;

void boost_common()
{
    import_array();
    if (0 && boosted_common) return;
    boosted_common = true;

    long int dims[] = {10, 10, 10};
    pyarr<double> d(3, dims);
    pyarr<float> f(3, dims);
    pyarr<int> i(3, dims);
    pyarr<long int> l(3, dims);
    pyarr<unsigned char> uc(3, dims);
    pyarr<unsigned int> ui(3, dims);
    pyarr<char> c(3, dims);

    printf("d %d f %d i %d l %d uc %d ui %d c %d\n",
           d.ao->descr->type_num,
           f.ao->descr->type_num,
           i.ao->descr->type_num,
           l.ao->descr->type_num,
           uc.ao->descr->type_num,
           ui.ao->descr->type_num,
           c.ao->descr->type_num);

    to_python_converter<MatrixMap, MatrixMap_to_numpy_str>();
    MatrixMap_from_numpy_str();

    to_python_converter<d2d::SegmentMap, SegmentMap_to_numpy_str>();
    SegmentMap_from_numpy_str();

    to_python_converter<mxArray, mxArray_to_numpy_str>();
    mxArray_from_numpy_str();

    to_python_converter<f2d::Pixel2DData, Pixel2DData_to_numpy_str>();
    Pixel2DData_from_numpy_str();

    to_python_converter<LRgbImage, LRgbImage_to_numpy_str>();
    LRgbImage_from_numpy_str();

    to_python_converter<vector<double>, vec_to_numpy_str>();
    vec_from_numpy_str();

    register_autogen_converters();

    class_<std::pair<unsigned int, double> >("uint_double_pair")
        .def_readwrite("first", &std::pair<unsigned int, double>::first)
        .def_readwrite("second", &std::pair<unsigned int, double>::second)
        ;
    class_<vector<std::pair<unsigned int, double> > >("uint_double_pair_vec")
        .def(vector_indexing_suite<vector<std::pair<unsigned int, double> > >())
        ;
    class_<vector<vector<std::pair<unsigned int, double> > > >("uint_double_pair_vec_vec")
        .def(vector_indexing_suite<vector<vector<std::pair<unsigned int, double> > > >())
        ;
    def("set_logger_verbosity", set_logger_verbosity);

    class_<vector<string> >("string_vector")
	.def(vector_indexing_suite<vector<string > >() )
	;

}

static bool boosted_ml = false;

void boost_ml()
{
    if (0 && boosted_ml) return;
    boosted_ml = true;

    class_<VRandomForest::VTreeNode>("VTreeNode", init<>())
        .def_readwrite("is_leaf", &VRandomForest::VTreeNode::is_leaf)
        .def_readwrite("count", &VRandomForest::VTreeNode::count)
        .def_readwrite("dim", &VRandomForest::VTreeNode::dim)
        .def_readwrite("avg_output", &VRandomForest::VTreeNode::avg_output)
        .def("get_left", VTreeNode__get_left, return_value_policy<reference_existing_object>())
        .def("get_right", VTreeNode__get_right, return_value_policy<reference_existing_object>())
        .def("refill_avg_outputs", VTreeNode__refill_avg_outputs)

        .def_readonly("thresh", &VRandomForest::VTreeNode::thresh)
        ;

    class_<vector<VRandomForest::VTreeNode> >("VTreeNode_vec")
        .def(vector_indexing_suite<vector<VRandomForest::VTreeNode> >())
        ;

    class_<VRandomForest>("VRandomForest", init<int, int, int, double, double>())
        .def_readwrite("m_nbr_trees", &VRandomForest::m_nbr_trees)
        .def_readwrite("m_max_depth", &VRandomForest::m_max_depth)
        .def_readwrite("m_min_node_size", &VRandomForest::m_min_node_size)
        .def_readwrite("m_rdm_dim_percent", &VRandomForest::m_rdm_dim_percent)
        .def_readwrite("m_rdm_sample_percent", &VRandomForest::m_rdm_sample_percent)
        .def_readwrite("m_seeds", &VRandomForest::m_seeds)
        .def_readwrite("m_trees", &VRandomForest::m_trees)
        .def("save", &VRandomForest::save)
        .def("load", &VRandomForest::load)
        .def("train", VRandomForest__wrap_train)
        .def("predict", VRandomForest__wrap_predict)
        ;
    class_<vector<VRandomForest*> >("VRandomForest_vec")
        .def(vector_indexing_suite<vector<VRandomForest*> >())
        ;
    class_<VBoostedMaxEnt>("VBoostedMaxEnt", init<double, double, double, int, VRandomForest>())
        .def_readwrite("m_step_sizes", &VBoostedMaxEnt::m_step_sizes)
        .def_readwrite("m_dim", &VBoostedMaxEnt::m_dim)
        .def("get_vec_vrandomforest", VBoostedMaxEnt__get_vec_vrandomforest)
        .def("train", VBoostedMaxEnt__wrap_train)
        .def("predict", VBoostedMaxEnt__wrap_predict)
        .def("save", &VBoostedMaxEnt::save)
        .def("load", &VBoostedMaxEnt::load)
        ;
    class_<vector<VBoostedMaxEnt*> >("VBoostedMaxEnt_vec")
        .def(vector_indexing_suite<vector<VBoostedMaxEnt*> >())
        ;
}

BOOST_PYTHON_MODULE(libboost_common) {
    PyEval_InitThreads();
    import_array();
    ilInit();
    boost_common();
}
<|endoftext|>