<commit_before>/*
  This file is part of the KDE project

  Copyright (C) 2004 Michael Brade <brade@kde.org>

  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; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.

  In addition, as a special exception, the copyright holders give
  permission to link the code of this program with any edition of
  the Qt library by Trolltech AS, Norway (or with modified versions
  of Qt that use the same license as Qt), and distribute linked
  combinations including the two.  You must obey the GNU General
  Public License in all respects for all of the code used other than
  Qt.  If you modify this file, you may extend this exception to
  your version of the file, but you are not obligated to do so.  If
  you do not wish to do so, delete this exception statement from
  your version.
*/

#include "knotetip.h"
#include "knotes_part_p.h"

#include <kglobalsettings.h>

#include <QAbstractEventDispatcher>
#include <QApplication>
#include <QToolTip>
#include <QLayout>
#include <QTextEdit>
#include <QEvent>
#include <QTimerEvent>
#include <QResizeEvent>
#include <QVBoxLayout>

KNoteTip::KNoteTip( K3IconView *parent )
  : QFrame( 0, Qt::WX11BypassWM |   // this will make Seli happy >:-P
             Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool | Qt::WStyle_StaysOnTop ),
    mFilter( false ),
    mView( parent ),
    mNoteIVI( 0 ),
    mPreview( new QTextEdit( this ) )
{
  mPreview->setReadOnly( true );
  mPreview->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mPreview->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );

  QBoxLayout *layout = new QVBoxLayout( this );
  layout->addWidget( mPreview );

  setPalette( QToolTip::palette() );
  setFrameStyle( QFrame::Plain | QFrame::Box );
  hide();
}

KNoteTip::~KNoteTip()
{
  delete mPreview;
  mPreview = 0;
}

void KNoteTip::setNote( KNotesIconViewItem *item )
{
  if ( mNoteIVI == item ) {
    return;
  }

  mNoteIVI = item;

  if ( !mNoteIVI ) {
    QAbstractEventDispatcher::instance()->unregisterTimers(this);
    if ( isVisible() ) {
      setFilter( false );
      hide();
    }
  } else {
    KCal::Journal *journal = item->journal();
    if ( journal->customProperty( "KNotes", "RichText" ) == "true" ) {
      mPreview->setTextFormat( Qt::RichText );
    } else {
      mPreview->setTextFormat( Qt::PlainText );
    }

    QColor fg( journal->customProperty( "KNotes", "FgColor" ) );
    QColor bg( journal->customProperty( "KNotes", "BgColor" ) );
    setColor( fg, bg );

    mPreview->setText( journal->description() );
    //mPreview->zoomTo( 8 );
    mPreview->sync();

    int w = 400;
    int h = mPreview->heightForWidth( w );
    while ( w > 60 && h == mPreview->heightForWidth( w - 20 ) ) {
      w -= 20;
    }

    QRect desk = KGlobalSettings::desktopGeometry( mNoteIVI->rect().center() );
    resize( w, qMin( h, desk.height() / 2 - 20 ) );

    hide();
    QAbstractEventDispatcher::instance()->unregisterTimers( this );
    setFilter( true );
    startTimer( 600 );  // delay showing the tooltip for 0.7 sec
  }
}

// protected, virtual methods

void KNoteTip::resizeEvent( QResizeEvent *ev )
{
  QFrame::resizeEvent( ev );
  reposition();
}

void KNoteTip::timerEvent( QTimerEvent * )
{
  QAbstractEventDispatcher::instance()->unregisterTimers( this );

  if ( !isVisible() ) {
    startTimer( 15000 ); // show the tooltip for 15 sec
    reposition();
    show();
  } else {
    setFilter( false );
    hide();
  }
}

bool KNoteTip::eventFilter( QObject *, QEvent *e )
{
  switch ( e->type() ) {
  case QEvent::Leave:
  case QEvent::MouseButtonPress:
  case QEvent::MouseButtonRelease:
  case QEvent::KeyPress:
  case QEvent::KeyRelease:
  case QEvent::FocusIn:
  case QEvent::FocusOut:
  case QEvent::Wheel:
    QAbstractEventDispatcher::instance()->unregisterTimers(this);
    setFilter( false );
    hide();
  default:
    break;
  }

  return false;
}

// private stuff

void KNoteTip::setColor( const QColor &fg, const QColor &bg )
{
  QPalette newpalette = palette();
  newpalette.setColor( QPalette::Background, bg );
  newpalette.setColor( QPalette::Foreground, fg );
  newpalette.setColor( QPalette::Base, bg ); // text background
  newpalette.setColor( QPalette::Text, fg ); // text color
  newpalette.setColor( QPalette::Button, bg );

  // the shadow
  newpalette.setColor( QPalette::Midlight, bg.light(110) );
  newpalette.setColor( QPalette::Shadow, bg.dark(116) );
  newpalette.setColor( QPalette::Light, bg.light(180) );
  newpalette.setColor( QPalette::Dark, bg.dark(108) );
  setPalette( newpalette );

  // set the text color
  mPreview->setColor( fg );
}

void KNoteTip::setFilter( bool enable )
{
  if ( enable == mFilter ) {
    return;
  }

  if ( enable ) {
    qApp->installEventFilter( this );
    QApplication::setGlobalMouseTracking( true );
  } else {
    QApplication::setGlobalMouseTracking( false );
    qApp->removeEventFilter( this );
  }

  mFilter = enable;
}

void KNoteTip::reposition()
{
  if ( !mNoteIVI ) {
    return;
  }

  QRect rect = mNoteIVI->rect();
  QPoint off = mView->mapToGlobal( mView->contentsToViewport( QPoint( 0, 0 ) ) );
  rect.translate( off.x(), off.y() );

  QPoint pos = rect.center();

  // should the tooltip be shown to the left or to the right of the ivi?
  QRect desk = KGlobalSettings::desktopGeometry( pos );
  if ( rect.center().x() + width() > desk.right() ) {
    // to the left
    if ( pos.x() - width() < 0 ) {
      pos.setX( 0 );
    } else {
      pos.setX( pos.x() - width() );
    }
  }

  // should the tooltip be shown above or below the ivi ?
  if ( rect.bottom() + height() > desk.bottom() ) {
    // above
    pos.setY( rect.top() - height() );
  } else {
    pos.setY( rect.bottom() );
  }

  move( pos );
  update();
}
<commit_msg>Fix layout<commit_after>/*
  This file is part of the KDE project

  Copyright (C) 2004 Michael Brade <brade@kde.org>

  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; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.

  In addition, as a special exception, the copyright holders give
  permission to link the code of this program with any edition of
  the Qt library by Trolltech AS, Norway (or with modified versions
  of Qt that use the same license as Qt), and distribute linked
  combinations including the two.  You must obey the GNU General
  Public License in all respects for all of the code used other than
  Qt.  If you modify this file, you may extend this exception to
  your version of the file, but you are not obligated to do so.  If
  you do not wish to do so, delete this exception statement from
  your version.
*/

#include "knotetip.h"
#include "knotes_part_p.h"

#include <kglobalsettings.h>

#include <QAbstractEventDispatcher>
#include <QApplication>
#include <QToolTip>
#include <QLayout>
#include <QTextEdit>
#include <QEvent>
#include <QTimerEvent>
#include <QResizeEvent>
#include <QVBoxLayout>

KNoteTip::KNoteTip( K3IconView *parent )
  : QFrame( 0, Qt::WX11BypassWM |   // this will make Seli happy >:-P
             Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_Tool | Qt::WStyle_StaysOnTop ),
    mFilter( false ),
    mView( parent ),
    mNoteIVI( 0 ),
    mPreview( new QTextEdit( this ) )
{
  mPreview->setReadOnly( true );
  mPreview->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mPreview->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );

  QBoxLayout *layout = new QVBoxLayout( this );
  layout->addWidget( mPreview );
  layout->setMargin( 1 );
  setPalette( QToolTip::palette() );
  setFrameStyle( QFrame::Plain | QFrame::Box );
  hide();
}

KNoteTip::~KNoteTip()
{
  delete mPreview;
  mPreview = 0;
}

void KNoteTip::setNote( KNotesIconViewItem *item )
{
  if ( mNoteIVI == item ) {
    return;
  }

  mNoteIVI = item;

  if ( !mNoteIVI ) {
    QAbstractEventDispatcher::instance()->unregisterTimers(this);
    if ( isVisible() ) {
      setFilter( false );
      hide();
    }
  } else {
    KCal::Journal *journal = item->journal();
    if ( journal->customProperty( "KNotes", "RichText" ) == "true" ) {
      mPreview->setTextFormat( Qt::RichText );
    } else {
      mPreview->setTextFormat( Qt::PlainText );
    }

    QColor fg( journal->customProperty( "KNotes", "FgColor" ) );
    QColor bg( journal->customProperty( "KNotes", "BgColor" ) );
    setColor( fg, bg );

    mPreview->setText( journal->description() );
    //mPreview->zoomTo( 8 );
    mPreview->sync();

    int w = 400;
    int h = mPreview->heightForWidth( w );
    while ( w > 60 && h == mPreview->heightForWidth( w - 20 ) ) {
      w -= 20;
    }

    QRect desk = KGlobalSettings::desktopGeometry( mNoteIVI->rect().center() );
    resize( w, qMin( h, desk.height() / 2 - 20 ) );

    hide();
    QAbstractEventDispatcher::instance()->unregisterTimers( this );
    setFilter( true );
    startTimer( 600 );  // delay showing the tooltip for 0.7 sec
  }
}

// protected, virtual methods

void KNoteTip::resizeEvent( QResizeEvent *ev )
{
  QFrame::resizeEvent( ev );
  reposition();
}

void KNoteTip::timerEvent( QTimerEvent * )
{
  QAbstractEventDispatcher::instance()->unregisterTimers( this );

  if ( !isVisible() ) {
    startTimer( 15000 ); // show the tooltip for 15 sec
    reposition();
    show();
  } else {
    setFilter( false );
    hide();
  }
}

bool KNoteTip::eventFilter( QObject *, QEvent *e )
{
  switch ( e->type() ) {
  case QEvent::Leave:
  case QEvent::MouseButtonPress:
  case QEvent::MouseButtonRelease:
  case QEvent::KeyPress:
  case QEvent::KeyRelease:
  case QEvent::FocusIn:
  case QEvent::FocusOut:
  case QEvent::Wheel:
    QAbstractEventDispatcher::instance()->unregisterTimers(this);
    setFilter( false );
    hide();
  default:
    break;
  }

  return false;
}

// private stuff

void KNoteTip::setColor( const QColor &fg, const QColor &bg )
{
  QPalette newpalette = palette();
  newpalette.setColor( QPalette::Background, bg );
  newpalette.setColor( QPalette::Foreground, fg );
  newpalette.setColor( QPalette::Base, bg ); // text background
  newpalette.setColor( QPalette::Text, fg ); // text color
  newpalette.setColor( QPalette::Button, bg );

  // the shadow
  newpalette.setColor( QPalette::Midlight, bg.light(110) );
  newpalette.setColor( QPalette::Shadow, bg.dark(116) );
  newpalette.setColor( QPalette::Light, bg.light(180) );
  newpalette.setColor( QPalette::Dark, bg.dark(108) );
  setPalette( newpalette );

  // set the text color
  mPreview->setColor( fg );
}

void KNoteTip::setFilter( bool enable )
{
  if ( enable == mFilter ) {
    return;
  }

  if ( enable ) {
    qApp->installEventFilter( this );
    QApplication::setGlobalMouseTracking( true );
  } else {
    QApplication::setGlobalMouseTracking( false );
    qApp->removeEventFilter( this );
  }

  mFilter = enable;
}

void KNoteTip::reposition()
{
  if ( !mNoteIVI ) {
    return;
  }

  QRect rect = mNoteIVI->rect();
  QPoint off = mView->mapToGlobal( mView->contentsToViewport( QPoint( 0, 0 ) ) );
  rect.translate( off.x(), off.y() );

  QPoint pos = rect.center();

  // should the tooltip be shown to the left or to the right of the ivi?
  QRect desk = KGlobalSettings::desktopGeometry( pos );
  if ( rect.center().x() + width() > desk.right() ) {
    // to the left
    if ( pos.x() - width() < 0 ) {
      pos.setX( 0 );
    } else {
      pos.setX( pos.x() - width() );
    }
  }

  // should the tooltip be shown above or below the ivi ?
  if ( rect.bottom() + height() > desk.bottom() ) {
    // above
    pos.setY( rect.top() - height() );
  } else {
    pos.setY( rect.bottom() );
  }

  move( pos );
  update();
}
<|endoftext|>


<commit_before>#include <yuni/yuni.h>
#include <yuni/string.h>
#include <nany/nany.h>
#include <cassert>
#include "nanyc-utils.h"

using namespace Yuni;

int main(int argc, const char** argv)
{
	const char* const argv0 = argv[0];

	if (argc > 1)
	{
		nyrun_cf_t runcf;
		nyrun_cf_init(&runcf);

		int firstarg = argc; // end of the list

		for (int i = 1; i < argc; ++i)
		{
			const char* const carg = argv[i];
			if (carg[0] == '-')
			{
				if (carg[1] == '-')
				{
					if (carg[2] != '\0') // to handle '--' option
					{
						AnyString arg{carg};

						if (arg == "--help")
							return ny::print::usage(argv[0]);
						if (arg == "--version")
							return ny::print::version();
						if (arg == "--bugreport")
							return ny::print::bugReportInfo();
						if (arg == "--verbose")
						{
							runcf.verbose = nytrue;
							continue;
						}
						return ny::print::unknownOption(argv0, arg);
					}
					else
					{
						// nothing must interpreted after '--'
						firstarg = i + 1;
						break;
					}
				}
				else
				{
					AnyString arg{carg};
					if (arg == "-h")
						return ny::print::usage(argv[0]);
					if (arg == "-v")
						return ny::print::version();
					return ny::print::unknownOption(argv0, arg);
				}
			}
			firstarg = i;
			break;
		}

		//
		// -- execute the script
		//
		int exitstatus = -1;
		if (firstarg < argc)
		{
			// callbacks
			runcf.build.on_error_file_eacces = &ny::print::fileAccessError;

			// the new arguments, after removing all command line arguments
			int nargc = argc - firstarg;
			const char** nargv = argv + firstarg;
			// the nany sript to load, which should be the first new argument
			const char* nargv0 = nargv[0];

			--nargc;
			uint32_t pargc = (nargc > 0) ? static_cast<uint32_t>(nargc) : 0;
			const char** pargv = (!pargc ? nullptr : (++nargv));

			exitstatus = nyrun_file_n(&runcf, nargv0, strlen(nargv0), pargc, pargv);
		}

		nyrun_cf_release(&runcf);
		return exitstatus;
	}
	return ny::print::noInputScript(argv0);
}
<commit_msg>nanyc: removed useless includes<commit_after>#include "nanyc-utils.h"

using namespace Yuni;

int main(int argc, const char** argv)
{
	const char* const argv0 = argv[0];

	if (argc > 1)
	{
		nyrun_cf_t runcf;
		nyrun_cf_init(&runcf);

		int firstarg = argc; // end of the list

		for (int i = 1; i < argc; ++i)
		{
			const char* const carg = argv[i];
			if (carg[0] == '-')
			{
				if (carg[1] == '-')
				{
					if (carg[2] != '\0') // to handle '--' option
					{
						AnyString arg{carg};

						if (arg == "--help")
							return ny::print::usage(argv[0]);
						if (arg == "--version")
							return ny::print::version();
						if (arg == "--bugreport")
							return ny::print::bugReportInfo();
						if (arg == "--verbose")
						{
							runcf.verbose = nytrue;
							continue;
						}
						return ny::print::unknownOption(argv0, arg);
					}
					else
					{
						// nothing must interpreted after '--'
						firstarg = i + 1;
						break;
					}
				}
				else
				{
					AnyString arg{carg};
					if (arg == "-h")
						return ny::print::usage(argv[0]);
					if (arg == "-v")
						return ny::print::version();
					return ny::print::unknownOption(argv0, arg);
				}
			}
			firstarg = i;
			break;
		}

		//
		// -- execute the script
		//
		int exitstatus = -1;
		if (firstarg < argc)
		{
			// callbacks
			runcf.build.on_error_file_eacces = &ny::print::fileAccessError;

			// the new arguments, after removing all command line arguments
			int nargc = argc - firstarg;
			const char** nargv = argv + firstarg;
			// the nany sript to load, which should be the first new argument
			const char* nargv0 = nargv[0];

			--nargc;
			uint32_t pargc = (nargc > 0) ? static_cast<uint32_t>(nargc) : 0;
			const char** pargv = (!pargc ? nullptr : (++nargv));

			exitstatus = nyrun_file_n(&runcf, nargv0, strlen(nargv0), pargc, pargv);
		}

		nyrun_cf_release(&runcf);
		return exitstatus;
	}
	return ny::print::noInputScript(argv0);
}
<|endoftext|>


<commit_before>//
// Created by skgchxngsxyz-leap on 2019/12/28.
//

#include <stddef.h>
#include <stdint.h>

#include "server.h"
#include <misc/files.h>

using namespace ydsh;
using namespace lsp;

static auto openDevNull() { return createFilePtr(fopen, "/dev/null", "wb"); }

static FilePtr newRequest(TempFileFactory &factory, const char *data, unsigned int size) {
  std::string inputName;
  auto input = factory.createTempFilePtr(inputName, (const char *)data, size);

  LSPLogger logger;
  LSPTransport transport(logger, openDevNull(), std::move(input));
  transport.send(size, data);

  return createFilePtr(fopen, inputName.c_str(), "rb");
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  TempFileFactory factory("ydsh_lsp_fuzzer");
  auto req = newRequest(factory, (const char *)data, size);

  LSPLogger logger;
  logger.setSeverity(LogLevel::INFO);
  logger.setAppender(openDevNull());
  LSPServer server(logger, std::move(req), openDevNull());
  server.runOnlyOnce();
  return 0;
}<commit_msg>fix build error<commit_after>//
// Created by skgchxngsxyz-leap on 2019/12/28.
//

#include <stddef.h>
#include <stdint.h>

#include "server.h"
#include <misc/files.h>

using namespace ydsh;
using namespace lsp;

static auto openDevNull() { return createFilePtr(fopen, "/dev/null", "wb"); }

static FilePtr newRequest(TempFileFactory &factory, const char *data, unsigned int size) {
  std::string inputName;
  auto input = factory.createTempFilePtr(inputName, (const char *)data, size);

  LSPLogger logger;
  LSPTransport transport(logger, openDevNull(), std::move(input));
  transport.send(size, data);

  return createFilePtr(fopen, inputName.c_str(), "rb");
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  TempFileFactory factory("ydsh_lsp_fuzzer");
  auto req = newRequest(factory, (const char *)data, size);

  LSPLogger logger;
  logger.setSeverity(LogLevel::INFO);
  logger.setAppender(openDevNull());
  LSPServer server(logger, std::move(req), openDevNull(), 1000);
  server.runOnlyOnce();
  return 0;
}<|endoftext|>


<commit_before>/******************************************************************************/
// Spin adaptor by Foster Brereton.
//
// Distributed under the MIT License. (See accompanying LICENSE.md or copy at
// https://opensource.org/licenses/MIT)
/******************************************************************************/

#ifndef SPIN_ADAPTOR_HPP__
#define SPIN_ADAPTOR_HPP__

/******************************************************************************/

template <typename BasicLockable>
struct spin_adaptor
{
    void lock() {
        thread_local std::size_t count{0};
        thread_local bool        spinout{false};

        while (spin_m.exchange(true)) {
            if (++count >= expected_m) {
                spinout = true;

                mutex_m.lock();
            }
        }

        if (!spinout)
            mutex_m.lock();

        // compute new expected
        expected_m = (count + 7 * expected_m) / 8;
    }

    void unlock() {
        mutex_m.unlock();

        spin_m = false;
    }

private:
    std::atomic<bool>        spin_m{false};
    bool                     spin_out_m{false};
    std::atomic<std::size_t> expected_m{0};
    BasicLockable            mutex_m;
};

/******************************************************************************/

#endif // SPIN_ADAPTOR_HPP__

/******************************************************************************/
<commit_msg>first workable solution.<commit_after>/******************************************************************************/
// Spin adaptor by Foster Brereton.
//
// Distributed under the MIT License. (See accompanying LICENSE.md or copy at
// https://opensource.org/licenses/MIT)
/******************************************************************************/

#ifndef SPIN_ADAPTOR_HPP__
#define SPIN_ADAPTOR_HPP__

/******************************************************************************/

#include <chrono>

/******************************************************************************/

template <typename Lockable>
class spin_adaptor
{
    typedef std::chrono::high_resolution_clock clock_t;
    typedef clock_t::time_point                time_point_t;

    using rep_t = decltype((std::declval<time_point_t>() - std::declval<time_point_t>()).count());

    std::atomic<rep_t> expected_m{0};
    Lockable           mutex_m;

public:
    void lock() {
        thread_local time_point_t  before = clock_t::now();
        thread_local rep_t         elapsed{0};

        while (!mutex_m.try_lock()) {
            elapsed = (clock_t::now() - before).count();

            if (elapsed > expected_m) {
                mutex_m.lock();

                break;
            }
        }

        expected_m = (elapsed + 7 * expected_m) / 8;
    }

    void unlock() {
        mutex_m.unlock();
    }
};

/******************************************************************************/

#endif // SPIN_ADAPTOR_HPP__

/******************************************************************************/
<|endoftext|>


<commit_before><commit_msg>added tests for get/set priority<commit_after>/** @file Test output routines.
 *
 * The overall strategy is to redirect output to
 * a file and then seek/read back file contents to
 * compare with expected output.
 */
#include "CppUTest/TestHarness.h"

extern "C" {
#include <stdio.h>
#include "txtutil.h"
}

TEST_GROUP(logutil){
    void setup(){}

    void teardown(){}
};

TEST(logutil, test_logPri)
{
    CHECK(getLogPri() == 3)
    CHECK(setLogPri(4) == 3)
    CHECK(getLogPri() == 4)
}<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#include "backup_manager.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

///////////////////////////////////////////////////////////////////////////////
//
// backup_manager() -
//
// Description:
//
//     Constructor.
//
backup_manager::backup_manager()
    : m_doing_backup(false),
      m_interpret_writes(false),
      m_doing_copy(false) // <CER> Set to false to turn off copy
{
}

///////////////////////////////////////////////////////////////////////////////
//
// start_backup() -
//
// Description:
//
//     Turns ON boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::start_backup()
{
    assert(m_doing_backup == false);
    int r = 0;
    r = pthread_mutex_init(&m_mutex, NULL);
    if (r) {
        perror("backup mutex creation failed.");
        abort();
    }

    m_doing_backup = true;
    m_interpret_writes = true;

    // Start backing all the files in the directory.
    if (m_doing_copy) {
        m_dir.start_copy();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// stop_backup() -
//
// Description:
//
//     Turns OFF boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::stop_backup()
{
    assert(m_doing_backup == true);

    // TODO: Make this: abort copy?
    m_dir.wait_for_copy_to_finish();

    m_interpret_writes = false;
    m_doing_backup = false;

    int r = 0;
    r = pthread_mutex_destroy(&m_mutex);
    if (r) {
        perror("Cannot destroy backup mutex.");
        abort();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// add_directory() -
//
// Description:
//
//     Adds the given source directory to our set of directories
// to backup.  This also uses the given destination argument as
// the top level of our backup directory.  All files underneath
// each directory tree should match once the backup is complete.
//
void backup_manager::add_directory(const char *source_dir,
                                   const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: assert that the directory's are not the same.
    // TODO: assert that the destination directory is empty.

    // TEMP: We only have one directory object at this point, for now...
    m_dir.set_directories(source_dir, dest_dir);
}

///////////////////////////////////////////////////////////////////////////////
//
// remove_directory() -
//
// Description:
//
//     TBD...
//
void backup_manager::remove_directory(const char *source_dir,
                                      const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: Do we need to pause copy?
    // TODO: Do we want an option to erase the backup?
}

///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     TBD: How is create different from open?  Is the only
// difference that we KNOW the file doesn't yet exist (from
// copy) for the create case?
//
void backup_manager::create(int fd, const char *file)
{
    if (MGR_DBG) printf("entering open() with fd = %d\n", fd);

    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_name(backup_file_name);
    description->create();
}

///////////////////////////////////////////////////////////////////////////////
//
// open() -
//
// Description:
//
//     If the given file is in our source directory, this method
// creates a new file_description object and opens the file in
// the backup directory.  We need the bakcup copy open because
// it may be updated if and when the user updates the original/source
// copy of the file.
//
void backup_manager::open(int fd, const char *file, int oflag)
{
    if (MGR_DBG) printf("entering open() with fd = %d\n", fd);

    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_name(backup_file_name);
    description->open();
}

///////////////////////////////////////////////////////////////////////////////
//
// close() -
//
// Description:
//
//     Find and deallocate file description based on incoming fd.
//
void backup_manager::close(int fd)
{
    if (MGR_DBG) printf("entering close_descriptor() with fd = %d\n", fd);
    file_description *description = m_map.get(fd);
    if (description == NULL) {
        printf("Cannot close the given description: doesn't exist in map.\n");
        return;
    }

    description->close();

    // TODO: ???
    // What happens when we have multiple handles on one file descriptor,
    // but we close only one of them?...
    m_map.erase(fd);
}

///////////////////////////////////////////////////////////////////////////////
//
// write() -
//
// Description:
//
//     Using the given file descriptor, this method updates the
// backup copy of a prevously opened file.
//
void backup_manager::write(int fd, const void *buf, size_t nbyte)
{
    if (MGR_DBG) printf("entering backup write() with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    description->write(buf, nbyte);
}

///////////////////////////////////////////////////////////////////////////////
//
// pwrite() -
//
// Description:
//
//     Same as regular write, but uses additional offset argument
// to write to a particular position in the backup file.
//
void backup_manager::pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
{
    if (MGR_DBG) printf("entering backup pwriter() with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    description->pwrite(buf, nbyte, offset);
}

///////////////////////////////////////////////////////////////////////////////
//
// seek() -
//
// Description:
//
//     Move the backup file descriptor to the new position.  This allows
// upcoming intercepted writes to be backed up properly.
//
void backup_manager::seek(int fd, size_t nbyte)
{
    if (MGR_DBG) printf("entering seek(), with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    // TODO: determine who is seeking...
    description->seek(nbyte);
}

///////////////////////////////////////////////////////////////////////////////
//
// rename() -
//
// Description:
//
//     TBD...
//
void backup_manager::rename(const char *oldpath, const char *newpath)
{
    // TODO:
}

///////////////////////////////////////////////////////////////////////////////
//
// get_directory() -
//
// Description:
//
//     TODO: When there are multiple directories, this method
// will use the given file descriptor to return the backup
// directory associated with that file descriptor.
//
backup_directory* backup_manager::get_directory(int fd)
{
    return &m_dir;
}

///////////////////////////////////////////////////////////////////////////////
//
// get_directory() -
//
// Description:
//
//     TODO: Needs to change for multiple directories.
//
backup_directory* backup_manager::get_directory(const char *file)
{
    if (MGR_DBG) printf("entering create_file() with file name = %s\n", file);

    if (!m_dir.directories_set())
    {
        return NULL;
    }

    // See if file is in backup directory or not...
    if (!m_dir.is_prefix(file)) {
        return NULL;
    }

    return &m_dir;
}
<commit_msg>refs #5599 turned on backup copy.  Needed it off for OSX syscall crash, was blocking testing.<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#include "backup_manager.h"
#include "real_syscalls.h"
#include "backup_debug.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

///////////////////////////////////////////////////////////////////////////////
//
// backup_manager() -
//
// Description:
//
//     Constructor.
//
backup_manager::backup_manager()
    : m_doing_backup(false),
      m_interpret_writes(false),
      m_doing_copy(true) // <CER> Set to false to turn off copy
{
}

///////////////////////////////////////////////////////////////////////////////
//
// start_backup() -
//
// Description:
//
//     Turns ON boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::start_backup()
{
    assert(m_doing_backup == false);
    int r = 0;
    r = pthread_mutex_init(&m_mutex, NULL);
    if (r) {
        perror("backup mutex creation failed.");
        abort();
    }

    m_doing_backup = true;
    m_interpret_writes = true;

    // Start backing all the files in the directory.
    if (m_doing_copy) {
        m_dir.start_copy();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// stop_backup() -
//
// Description:
//
//     Turns OFF boolean flags for both backup and the interpretation
// of writes.
//
void backup_manager::stop_backup()
{
    assert(m_doing_backup == true);

    // TODO: Make this: abort copy?
    m_dir.wait_for_copy_to_finish();

    m_interpret_writes = false;
    m_doing_backup = false;

    int r = 0;
    r = pthread_mutex_destroy(&m_mutex);
    if (r) {
        perror("Cannot destroy backup mutex.");
        abort();
    }
}

///////////////////////////////////////////////////////////////////////////////
//
// add_directory() -
//
// Description:
//
//     Adds the given source directory to our set of directories
// to backup.  This also uses the given destination argument as
// the top level of our backup directory.  All files underneath
// each directory tree should match once the backup is complete.
//
void backup_manager::add_directory(const char *source_dir,
                                   const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: assert that the directory's are not the same.
    // TODO: assert that the destination directory is empty.

    // TEMP: We only have one directory object at this point, for now...
    m_dir.set_directories(source_dir, dest_dir);
}

///////////////////////////////////////////////////////////////////////////////
//
// remove_directory() -
//
// Description:
//
//     TBD...
//
void backup_manager::remove_directory(const char *source_dir,
                                      const char *dest_dir)
{
    assert(source_dir);
    assert(dest_dir);

    // TODO: Do we need to pause copy?
    // TODO: Do we want an option to erase the backup?
}

///////////////////////////////////////////////////////////////////////////////
//
// create() -
//
// Description:
//
//     TBD: How is create different from open?  Is the only
// difference that we KNOW the file doesn't yet exist (from
// copy) for the create case?
//
void backup_manager::create(int fd, const char *file)
{
    if (MGR_DBG) printf("entering open() with fd = %d\n", fd);

    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_name(backup_file_name);
    description->create();
}

///////////////////////////////////////////////////////////////////////////////
//
// open() -
//
// Description:
//
//     If the given file is in our source directory, this method
// creates a new file_description object and opens the file in
// the backup directory.  We need the bakcup copy open because
// it may be updated if and when the user updates the original/source
// copy of the file.
//
void backup_manager::open(int fd, const char *file, int oflag)
{
    if (MGR_DBG) printf("entering open() with fd = %d\n", fd);

    backup_directory *directory = this->get_directory(file);
    if (directory == NULL) {
        return;
    }

    char *backup_file_name = directory->translate_prefix(file);
    directory->open_path(backup_file_name);
    m_map.put(fd);
    file_description *description = m_map.get(fd);
    description->set_name(backup_file_name);
    description->open();
}

///////////////////////////////////////////////////////////////////////////////
//
// close() -
//
// Description:
//
//     Find and deallocate file description based on incoming fd.
//
void backup_manager::close(int fd)
{
    if (MGR_DBG) printf("entering close_descriptor() with fd = %d\n", fd);
    file_description *description = m_map.get(fd);
    if (description == NULL) {
        printf("Cannot close the given description: doesn't exist in map.\n");
        return;
    }

    description->close();

    // TODO: ???
    // What happens when we have multiple handles on one file descriptor,
    // but we close only one of them?...
    m_map.erase(fd);
}

///////////////////////////////////////////////////////////////////////////////
//
// write() -
//
// Description:
//
//     Using the given file descriptor, this method updates the
// backup copy of a prevously opened file.
//
void backup_manager::write(int fd, const void *buf, size_t nbyte)
{
    if (MGR_DBG) printf("entering backup write() with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    description->write(buf, nbyte);
}

///////////////////////////////////////////////////////////////////////////////
//
// pwrite() -
//
// Description:
//
//     Same as regular write, but uses additional offset argument
// to write to a particular position in the backup file.
//
void backup_manager::pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
{
    if (MGR_DBG) printf("entering backup pwriter() with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    description->pwrite(buf, nbyte, offset);
}

///////////////////////////////////////////////////////////////////////////////
//
// seek() -
//
// Description:
//
//     Move the backup file descriptor to the new position.  This allows
// upcoming intercepted writes to be backed up properly.
//
void backup_manager::seek(int fd, size_t nbyte)
{
    if (MGR_DBG) printf("entering seek(), with fd = %d\n", fd);
    if (!m_interpret_writes) {
        return;
    }

    file_description *description = NULL;
    description = m_map.get(fd);
    if (description == NULL) {
        return;
    }

    // TODO: determine who is seeking...
    description->seek(nbyte);
}

///////////////////////////////////////////////////////////////////////////////
//
// rename() -
//
// Description:
//
//     TBD...
//
void backup_manager::rename(const char *oldpath, const char *newpath)
{
    // TODO:
}

///////////////////////////////////////////////////////////////////////////////
//
// get_directory() -
//
// Description:
//
//     TODO: When there are multiple directories, this method
// will use the given file descriptor to return the backup
// directory associated with that file descriptor.
//
backup_directory* backup_manager::get_directory(int fd)
{
    return &m_dir;
}

///////////////////////////////////////////////////////////////////////////////
//
// get_directory() -
//
// Description:
//
//     TODO: Needs to change for multiple directories.
//
backup_directory* backup_manager::get_directory(const char *file)
{
    if (MGR_DBG) printf("entering create_file() with file name = %s\n", file);

    if (!m_dir.directories_set())
    {
        return NULL;
    }

    // See if file is in backup directory or not...
    if (!m_dir.is_prefix(file)) {
        return NULL;
    }

    return &m_dir;
}
<|endoftext|>


<commit_before>// @(#)root/g3d:$Name$:$Id$
// Author: Rene Brun   14/09/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TROOT.h"
#include "TGeometry.h"
#include "TRotMatrix.h"

ClassImp(TRotMatrix)

//______________________________________________________________________________
//
// Manages a detector rotation matrix. See class TGeometry.
//

//______________________________________________________________________________
TRotMatrix::TRotMatrix()
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix default constructor*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

   //do nothing
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t *matrix)
           :TNamed(name,title)
{
  if (!matrix) { Error("ctor","No rotation is supplied"); return; }

  SetMatrix(matrix);
  if (!gGeometry) gGeometry = new TGeometry();
  fNumber = gGeometry->GetListOfMatrices()->GetSize();
  gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t theta, Double_t phi, Double_t psi)
           :TNamed(name,title)
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

   printf("ERROR: This form of TRotMatrix constructor not implemented yet\n");

   Int_t i;
   fTheta  = theta;
   fPhi    = phi;
   fPsi    = psi;
   fType   = 2;
   for (i=0;i<9;i++) fMatrix[i] = 0;
   fMatrix[0] = 1;   fMatrix[4] = 1;   fMatrix[8] = 1;

   if (!gGeometry) gGeometry = new TGeometry();
   fNumber = gGeometry->GetListOfMatrices()->GetSize();
   gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t theta1, Double_t phi1
                                                  , Double_t theta2, Double_t phi2
                                                  , Double_t theta3, Double_t phi3)
                :TNamed(name,title)
{
//*-*-*-*-*-*RotMatrix normal constructor defined a la GEANT*-*-*-*-*-*-*
//*-*        ===============================================
//
// The TRotMatrix constructor with six angles uses the GEANT convention:
//
// theta1 is the polar angle of the x-prim axis in the main reference system
// (MRS), theta2 and theta3 have the same meaning for the y-prim and z-prim
// axis.
//
// Phi1 is the azimuthal angle of the x-prim in the MRS and phi2 and phi3
// have the same meaning for y-prim and z-prim.
//
//
// for example, the unit matrix is defined in the following way.
//
//     x-prim || x, y-prim || y, z-prim || z
//
//     means:  theta1=90, theta2=90, theta3=0, phi1=0, phi2=90, phi3=0

   SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);

   if (!gGeometry) gGeometry = new TGeometry();
   fNumber = gGeometry->GetListOfMatrices()->GetSize();
   gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::~TRotMatrix()
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix default destructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

    gGeometry->GetListOfMatrices()->Remove(this);
}

//______________________________________________________________________________
Double_t  TRotMatrix::Determinant() const
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*
//*-*  Determinant() returns the value of the determiant of this matrix
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
 return
        fMatrix[0] * (fMatrix[4]*fMatrix[8] - fMatrix[7]*fMatrix[5])
      - fMatrix[3] * (fMatrix[1]*fMatrix[8] - fMatrix[7]*fMatrix[2])
      + fMatrix[6] * (fMatrix[1]*fMatrix[5] - fMatrix[4]*fMatrix[2]);
}

//______________________________________________________________________________
Double_t* TRotMatrix::GetGLMatrix(Double_t *rGLMatrix) const
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*  Convert this matrix to the OpenGL [4x4]
//*-*
//*-*  [  fMatrix[0]   fMatrix[1]   fMatrix[2]    0  ]
//*-*  [  fMatrix[3]   fMatrix[4]   fMatrix[5]    0  ]
//*-*  [  fMatrix[6]   fMatrix[7]   fMatrix[8]    0  ]
//*-*  [     0             0           0          1  ]
//*-*
//*-*  Input:
//*-*  -----
//*-*  Double_t *rGLMatrix - pointer to Double_t 4x4 buffer array
//*-*
//*-*  Return:
//*-*  ------
//*-*  Double_t pointer to the input buffer
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

   Double_t *glmatrix = rGLMatrix;
   const Double_t *matrix   = fMatrix;
   if (rGLMatrix)
   {
       for (Int_t i=0;i<3;i++)
       {
           for (Int_t j=0;j<3;j++)
                 memcpy(glmatrix,matrix,3*sizeof(Double_t));
            matrix   += 3;
            glmatrix += 3;
           *glmatrix = 0.0;
            glmatrix++;

       }
       for (Int_t j=0;j<3;j++) {
           *glmatrix = 0.0;
           glmatrix++;
       }
       *glmatrix = 1.0;
   }
       return rGLMatrix;
}

//______________________________________________________________________________
const Double_t* TRotMatrix::SetAngles(Double_t theta1, Double_t phi1,
                Double_t theta2, Double_t phi2,Double_t theta3, Double_t phi3)
{
// theta1 is the polar angle of the x-prim axis in the main reference system
// (MRS), theta2 and theta3 have the same meaning for the y-prim and z-prim
// axis.
//
// Phi1 is the azimuthal angle of the x-prim in the MRS and phi2 and phi3
// have the same meaning for y-prim and z-prim.
//
//
// for example, the unit matrix is defined in the following way.
//
//     x-prim || x, y-prim || y, z-prim || z
//
//     means:  theta1=90, theta2=90, theta3=0, phi1=0, phi2=90, phi3=0

   const Double_t degrad = 0.0174532925199432958;

   fTheta  = theta1;
   fPhi    = phi1;
   fPsi    = theta2;

   fType   = 2;
   if (!strcmp(GetName(),"Identity")) fType = 0;

   fMatrix[0] = TMath::Sin(theta1*degrad)*TMath::Cos(phi1*degrad);
   fMatrix[1] = TMath::Sin(theta1*degrad)*TMath::Sin(phi1*degrad);
   fMatrix[2] = TMath::Cos(theta1*degrad);
   fMatrix[3] = TMath::Sin(theta2*degrad)*TMath::Cos(phi2*degrad);
   fMatrix[4] = TMath::Sin(theta2*degrad)*TMath::Sin(phi2*degrad);
   fMatrix[5] = TMath::Cos(theta2*degrad);
   fMatrix[6] = TMath::Sin(theta3*degrad)*TMath::Cos(phi3*degrad);
   fMatrix[7] = TMath::Sin(theta3*degrad)*TMath::Sin(phi3*degrad);
   fMatrix[8] = TMath::Cos(theta3*degrad);

   SetReflection();
   return fMatrix;
}

//______________________________________________________________________________
void TRotMatrix::SetMatrix(const Double_t *matrix)
{
  // copy predefined 3x3 matrix into TRotMatrix object
   fTheta  = 0;
   fPhi    = 0;
   fPsi    = 0;
   fType   = 0;
   if (!matrix) return;
   fType   = 2;
   memcpy(fMatrix,matrix,9*sizeof(Double_t));
   SetReflection();
}
//______________________________________________________________________________
void TRotMatrix::SetReflection()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*  SetReflection() -  checks whether the determinant of this
//*-*                     matrix defines the reflection transformation
//*-*                     and set the "reflection" flag if any
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
   ResetBit(kReflection);
   if (Determinant() < 0) { fType=1; SetBit(kReflection);}
}
<commit_msg>Protect destructor against case gGeometry = 0<commit_after>// @(#)root/g3d:$Name:  $:$Id: TRotMatrix.cxx,v 1.1.1.1 2000/05/16 17:00:43 rdm Exp $
// Author: Rene Brun   14/09/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TROOT.h"
#include "TGeometry.h"
#include "TRotMatrix.h"

ClassImp(TRotMatrix)

//______________________________________________________________________________
//
// Manages a detector rotation matrix. See class TGeometry.
//

//______________________________________________________________________________
TRotMatrix::TRotMatrix()
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix default constructor*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

   //do nothing
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t *matrix)
           :TNamed(name,title)
{
  if (!matrix) { Error("ctor","No rotation is supplied"); return; }

  SetMatrix(matrix);
  if (!gGeometry) gGeometry = new TGeometry();
  fNumber = gGeometry->GetListOfMatrices()->GetSize();
  gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t theta, Double_t phi, Double_t psi)
           :TNamed(name,title)
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

   printf("ERROR: This form of TRotMatrix constructor not implemented yet\n");

   Int_t i;
   fTheta  = theta;
   fPhi    = phi;
   fPsi    = psi;
   fType   = 2;
   for (i=0;i<9;i++) fMatrix[i] = 0;
   fMatrix[0] = 1;   fMatrix[4] = 1;   fMatrix[8] = 1;

   if (!gGeometry) gGeometry = new TGeometry();
   fNumber = gGeometry->GetListOfMatrices()->GetSize();
   gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::TRotMatrix(const char *name, const char *title, Double_t theta1, Double_t phi1
                                                  , Double_t theta2, Double_t phi2
                                                  , Double_t theta3, Double_t phi3)
                :TNamed(name,title)
{
//*-*-*-*-*-*RotMatrix normal constructor defined a la GEANT*-*-*-*-*-*-*
//*-*        ===============================================
//
// The TRotMatrix constructor with six angles uses the GEANT convention:
//
// theta1 is the polar angle of the x-prim axis in the main reference system
// (MRS), theta2 and theta3 have the same meaning for the y-prim and z-prim
// axis.
//
// Phi1 is the azimuthal angle of the x-prim in the MRS and phi2 and phi3
// have the same meaning for y-prim and z-prim.
//
//
// for example, the unit matrix is defined in the following way.
//
//     x-prim || x, y-prim || y, z-prim || z
//
//     means:  theta1=90, theta2=90, theta3=0, phi1=0, phi2=90, phi3=0

   SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);

   if (!gGeometry) gGeometry = new TGeometry();
   fNumber = gGeometry->GetListOfMatrices()->GetSize();
   gGeometry->GetListOfMatrices()->Add(this);
}

//______________________________________________________________________________
TRotMatrix::~TRotMatrix()
{
//*-*-*-*-*-*-*-*-*-*-*RotMatrix default destructor*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ============================

    if (gGeometry) gGeometry->GetListOfMatrices()->Remove(this);
}

//______________________________________________________________________________
Double_t  TRotMatrix::Determinant() const
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*
//*-*  Determinant() returns the value of the determiant of this matrix
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
 return
        fMatrix[0] * (fMatrix[4]*fMatrix[8] - fMatrix[7]*fMatrix[5])
      - fMatrix[3] * (fMatrix[1]*fMatrix[8] - fMatrix[7]*fMatrix[2])
      + fMatrix[6] * (fMatrix[1]*fMatrix[5] - fMatrix[4]*fMatrix[2]);
}

//______________________________________________________________________________
Double_t* TRotMatrix::GetGLMatrix(Double_t *rGLMatrix) const
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*  Convert this matrix to the OpenGL [4x4]
//*-*
//*-*  [  fMatrix[0]   fMatrix[1]   fMatrix[2]    0  ]
//*-*  [  fMatrix[3]   fMatrix[4]   fMatrix[5]    0  ]
//*-*  [  fMatrix[6]   fMatrix[7]   fMatrix[8]    0  ]
//*-*  [     0             0           0          1  ]
//*-*
//*-*  Input:
//*-*  -----
//*-*  Double_t *rGLMatrix - pointer to Double_t 4x4 buffer array
//*-*
//*-*  Return:
//*-*  ------
//*-*  Double_t pointer to the input buffer
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

   Double_t *glmatrix = rGLMatrix;
   const Double_t *matrix   = fMatrix;
   if (rGLMatrix)
   {
       for (Int_t i=0;i<3;i++)
       {
           for (Int_t j=0;j<3;j++)
                 memcpy(glmatrix,matrix,3*sizeof(Double_t));
            matrix   += 3;
            glmatrix += 3;
           *glmatrix = 0.0;
            glmatrix++;

       }
       for (Int_t j=0;j<3;j++) {
           *glmatrix = 0.0;
           glmatrix++;
       }
       *glmatrix = 1.0;
   }
       return rGLMatrix;
}

//______________________________________________________________________________
const Double_t* TRotMatrix::SetAngles(Double_t theta1, Double_t phi1,
                Double_t theta2, Double_t phi2,Double_t theta3, Double_t phi3)
{
// theta1 is the polar angle of the x-prim axis in the main reference system
// (MRS), theta2 and theta3 have the same meaning for the y-prim and z-prim
// axis.
//
// Phi1 is the azimuthal angle of the x-prim in the MRS and phi2 and phi3
// have the same meaning for y-prim and z-prim.
//
//
// for example, the unit matrix is defined in the following way.
//
//     x-prim || x, y-prim || y, z-prim || z
//
//     means:  theta1=90, theta2=90, theta3=0, phi1=0, phi2=90, phi3=0

   const Double_t degrad = 0.0174532925199432958;

   fTheta  = theta1;
   fPhi    = phi1;
   fPsi    = theta2;

   fType   = 2;
   if (!strcmp(GetName(),"Identity")) fType = 0;

   fMatrix[0] = TMath::Sin(theta1*degrad)*TMath::Cos(phi1*degrad);
   fMatrix[1] = TMath::Sin(theta1*degrad)*TMath::Sin(phi1*degrad);
   fMatrix[2] = TMath::Cos(theta1*degrad);
   fMatrix[3] = TMath::Sin(theta2*degrad)*TMath::Cos(phi2*degrad);
   fMatrix[4] = TMath::Sin(theta2*degrad)*TMath::Sin(phi2*degrad);
   fMatrix[5] = TMath::Cos(theta2*degrad);
   fMatrix[6] = TMath::Sin(theta3*degrad)*TMath::Cos(phi3*degrad);
   fMatrix[7] = TMath::Sin(theta3*degrad)*TMath::Sin(phi3*degrad);
   fMatrix[8] = TMath::Cos(theta3*degrad);

   SetReflection();
   return fMatrix;
}

//______________________________________________________________________________
void TRotMatrix::SetMatrix(const Double_t *matrix)
{
  // copy predefined 3x3 matrix into TRotMatrix object
   fTheta  = 0;
   fPhi    = 0;
   fPsi    = 0;
   fType   = 0;
   if (!matrix) return;
   fType   = 2;
   memcpy(fMatrix,matrix,9*sizeof(Double_t));
   SetReflection();
}
//______________________________________________________________________________
void TRotMatrix::SetReflection()
{
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*  SetReflection() -  checks whether the determinant of this
//*-*                     matrix defines the reflection transformation
//*-*                     and set the "reflection" flag if any
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
   ResetBit(kReflection);
   if (Determinant() < 0) { fType=1; SetBit(kReflection);}
}
<|endoftext|>


<commit_before>#include "pch.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "rdohotkey.h"
#include "rdoparser.h"

namespace rdoParse
{

RDOHotKeyToolkit rdoHotKeyToolkit;

RDOHotKeyToolkit::RDOHotKeyToolkit()
{

	keys.insert(map<string, int>::value_type("ESCAPE", VK_ESCAPE));
	keys.insert(map<string, int>::value_type("TAB", VK_TAB));
	keys.insert(map<string, int>::value_type("SHIFT", VK_SHIFT));
	keys.insert(map<string, int>::value_type("CONTROL", VK_CONTROL));
	keys.insert(map<string, int>::value_type("BACK", VK_BACK));
	keys.insert(map<string, int>::value_type("RETURN", VK_RETURN));
	keys.insert(map<string, int>::value_type("INSERT", VK_INSERT));
	keys.insert(map<string, int>::value_type("HOME", VK_HOME));
	keys.insert(map<string, int>::value_type("PRIOR", VK_PRIOR));
	keys.insert(map<string, int>::value_type("DELETE", VK_DELETE));
	keys.insert(map<string, int>::value_type("END", VK_END));
	keys.insert(map<string, int>::value_type("NEXT", VK_NEXT));
	keys.insert(map<string, int>::value_type("UP", VK_UP));
	keys.insert(map<string, int>::value_type("LEFT", VK_LEFT));
	keys.insert(map<string, int>::value_type("DOWN", VK_DOWN));
	keys.insert(map<string, int>::value_type("RIGHT", VK_RIGHT));
	keys.insert(map<string, int>::value_type("DIVIDE", VK_DIVIDE));
	keys.insert(map<string, int>::value_type("MULTIPLY", VK_MULTIPLY));
	keys.insert(map<string, int>::value_type("SUBTRACT", VK_SUBTRACT));
	keys.insert(map<string, int>::value_type("ADD", VK_ADD));
	keys.insert(map<string, int>::value_type("CLEAR", VK_CLEAR));
	keys.insert(map<string, int>::value_type("SPACE", VK_SPACE));
	keys.insert(map<string, int>::value_type("DECIMAL", VK_DECIMAL));
	keys.insert(map<string, int>::value_type("F2", VK_F2));
	keys.insert(map<string, int>::value_type("F3", VK_F3));
	keys.insert(map<string, int>::value_type("F4", VK_F4));
	keys.insert(map<string, int>::value_type("F5", VK_F5));
	keys.insert(map<string, int>::value_type("F6", VK_F6));
	keys.insert(map<string, int>::value_type("F7", VK_F7));
	keys.insert(map<string, int>::value_type("F8", VK_F8));
	keys.insert(map<string, int>::value_type("F9", VK_F9));
	keys.insert(map<string, int>::value_type("F10", VK_F10));
	keys.insert(map<string, int>::value_type("F11", VK_F11));
	keys.insert(map<string, int>::value_type("F12", VK_F12));
	keys.insert(map<string, int>::value_type("NUMPAD0", VK_NUMPAD0));
	keys.insert(map<string, int>::value_type("NUMPAD1", VK_NUMPAD1));
	keys.insert(map<string, int>::value_type("NUMPAD2", VK_NUMPAD2));
	keys.insert(map<string, int>::value_type("NUMPAD3", VK_NUMPAD3));
	keys.insert(map<string, int>::value_type("NUMPAD4", VK_NUMPAD4));
	keys.insert(map<string, int>::value_type("NUMPAD5", VK_NUMPAD5));
	keys.insert(map<string, int>::value_type("NUMPAD6", VK_NUMPAD6));
	keys.insert(map<string, int>::value_type("NUMPAD7", VK_NUMPAD7));
	keys.insert(map<string, int>::value_type("NUMPAD8", VK_NUMPAD8));
	keys.insert(map<string, int>::value_type("NUMPAD9", VK_NUMPAD9));

	for(char i = '0'; i <= '9'; i++)
		keys.insert(map<string, int>::value_type(string(1, i), (int)i));

	for(i = 'A'; i <= 'Z'; i++)
		keys.insert(map<string, int>::value_type(string(1, i), (int)i));

}

int RDOHotKeyToolkit::codeFromString(string *key)
{
	map<string, int>::iterator it = keys.find(*key);
	if(it == keys.end())
		currParser->error("Unknown key name: " + *key);

	return (*it).second;
}

}		// namespace rdoParse
<commit_msg>no message<commit_after>#include "pch.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "rdohotkey.h"
#include "rdoparser.h"

namespace rdoParse
{

RDOHotKeyToolkit rdoHotKeyToolkit;

RDOHotKeyToolkit::RDOHotKeyToolkit()
{

	keys.insert(map<string, int>::value_type("ESCAPE", VK_ESCAPE));
	keys.insert(map<string, int>::value_type("TAB", VK_TAB));
	keys.insert(map<string, int>::value_type("SHIFT", VK_SHIFT));
	keys.insert(map<string, int>::value_type("CONTROL", VK_CONTROL));
	keys.insert(map<string, int>::value_type("BACK", VK_BACK));
	keys.insert(map<string, int>::value_type("RETURN", VK_RETURN));
	keys.insert(map<string, int>::value_type("INSERT", VK_INSERT));
	keys.insert(map<string, int>::value_type("HOME", VK_HOME));
	keys.insert(map<string, int>::value_type("PRIOR", VK_PRIOR));
	keys.insert(map<string, int>::value_type("DELETE", VK_DELETE));
	keys.insert(map<string, int>::value_type("END", VK_END));
	keys.insert(map<string, int>::value_type("NEXT", VK_NEXT));
	keys.insert(map<string, int>::value_type("UP", VK_UP));
	keys.insert(map<string, int>::value_type("LEFT", VK_LEFT));
	keys.insert(map<string, int>::value_type("DOWN", VK_DOWN));
	keys.insert(map<string, int>::value_type("RIGHT", VK_RIGHT));
	keys.insert(map<string, int>::value_type("DIVIDE", VK_DIVIDE));
	keys.insert(map<string, int>::value_type("MULTIPLY", VK_MULTIPLY));
	keys.insert(map<string, int>::value_type("SUBTRACT", VK_SUBTRACT));
	keys.insert(map<string, int>::value_type("ADD", VK_ADD));
	keys.insert(map<string, int>::value_type("CLEAR", VK_CLEAR));
	keys.insert(map<string, int>::value_type("SPACE", VK_SPACE));
	keys.insert(map<string, int>::value_type("DECIMAL", VK_DECIMAL));
	keys.insert(map<string, int>::value_type("F2", VK_F2));
	keys.insert(map<string, int>::value_type("F3", VK_F3));
	keys.insert(map<string, int>::value_type("F4", VK_F4));
	keys.insert(map<string, int>::value_type("F5", VK_F5));
	keys.insert(map<string, int>::value_type("F6", VK_F6));
	keys.insert(map<string, int>::value_type("F7", VK_F7));
	keys.insert(map<string, int>::value_type("F8", VK_F8));
	keys.insert(map<string, int>::value_type("F9", VK_F9));
	keys.insert(map<string, int>::value_type("F10", VK_F10));
	keys.insert(map<string, int>::value_type("F11", VK_F11));
	keys.insert(map<string, int>::value_type("F12", VK_F12));
	keys.insert(map<string, int>::value_type("NUMPAD0", VK_NUMPAD0));
	keys.insert(map<string, int>::value_type("NUMPAD1", VK_NUMPAD1));
	keys.insert(map<string, int>::value_type("NUMPAD2", VK_NUMPAD2));
	keys.insert(map<string, int>::value_type("NUMPAD3", VK_NUMPAD3));
	keys.insert(map<string, int>::value_type("NUMPAD4", VK_NUMPAD4));
	keys.insert(map<string, int>::value_type("NUMPAD5", VK_NUMPAD5));
	keys.insert(map<string, int>::value_type("NUMPAD6", VK_NUMPAD6));
	keys.insert(map<string, int>::value_type("NUMPAD7", VK_NUMPAD7));
	keys.insert(map<string, int>::value_type("NUMPAD8", VK_NUMPAD8));
	keys.insert(map<string, int>::value_type("NUMPAD9", VK_NUMPAD9));
	keys.insert(map<string, int>::value_type("NOKEY", -1));

	for(char i = '0'; i <= '9'; i++)
		keys.insert(map<string, int>::value_type(string(1, i), (int)i));

	for(i = 'A'; i <= 'Z'; i++)
		keys.insert(map<string, int>::value_type(string(1, i), (int)i));

}

int RDOHotKeyToolkit::codeFromString(string *key)
{
	map<string, int>::iterator it = keys.find(*key);
	if(it == keys.end())
		currParser->error("Unknown key name: " + *key);

	return (*it).second;
}

}		// namespace rdoParse
<|endoftext|>


<commit_before>// vdtllist.cc            see license.txt for copyright and terms of use
// code for vdtllist.h

#include "vdtllist.h"      // this module

void VoidTailList::steal(VoidTailList *src)
{
  if (src) {
    top = src->top;
    tail = src->tail;
    src->top = NULL;    // paranoia
    delete src;
  }
  else {
    top = NULL;
    tail = NULL;
  }
}

void VoidTailList::prepend(void *newitem)
{
  VoidList::prepend(newitem);
  if (!tail) {
    tail = top;
  }
}

void VoidTailList::append(void *newitem)
{
  if (isEmpty()) {
    prepend(newitem);
  }
  else {
    // payoff: constant-time append
    tail->next = new VoidNode(newitem, NULL);
    tail = tail->next;
  }
}

void VoidTailList::insertAt(void *newitem, int index)
{
  VoidList::insertAt(newitem, index);
  adjustTail();
}

void VoidTailList::concat(VoidTailList &srcList)
{
  // grab what will be the tail of the concatenated list
  VoidNode *catTail = srcList.top? srcList.tail : tail;

  // build proper backbone structure
  VoidList::concat(srcList);

  // fix tails
  tail = catTail;
  srcList.tail = NULL;
}

void VoidTailList::adjustTail()
{
  if (!tail) {
    tail = top;
  }
  else if (tail->next) {
    tail = tail->next;
  }
  xassert(tail->next == NULL);
}

void *VoidTailList::removeFirst()
{
  xassert(top);
  if (top == tail) {
    tail = NULL;
  }
  void *retval = top->data;
  VoidNode *tmp = top;
  top = top->next;
  delete tmp;
  return retval;
}

void *VoidTailList::removeLast()
{
  xassert(top);
  if (top == tail) {
    return removeFirst();
  }

  VoidNode *before = top;
  while (before->next != tail) {
    before = before->next;
  }
  void *retval = tail->data;
  delete tail;
  tail = before;
  tail->next = NULL;
  return retval;
}

void *VoidTailList::removeAt(int index)
{
  xassert(top);
  if (index == 0) {
    // If we are removing the only item, reset the tail pointer.
    if (top == tail) {
      tail = NULL;
    }
    return removeFirst();
  }

  VoidNode *before = top;    // will point to node before one to be removed
  index--;
  while (index > 0) {
    before = before->next;
    index--;
  }
  xassert(index == 0);

  // fix 'tail' if necessary
  if (tail == before->next) {
    tail = before;
  }

  // patch around before->next
  VoidNode *toDelete = before->next;
  void *retval = toDelete->data;
  before->next = toDelete->next;
  delete toDelete;

  return retval;
}

// for now, copy of VoidList::removeIfPresent, since the functions it calls
// are not virtual.
bool VoidTailList::removeIfPresent(void *item)
{
  // for now, not a real fast implementation
  int index = indexOf(item);
  if (index == -1) {
    return false;   // not there
  }
  else {
    removeAt(index);
    return true;
  }
}

// for now, copy of VoidList::removeItem, since the functions it calls are not
// virtual.
void VoidTailList::removeItem(void *item)
{
  bool wasThere = removeIfPresent(item);
  xassert(wasThere);
}

void VoidTailList::removeAll()
{
  VoidList::removeAll();
  tail = NULL;
}

bool VoidTailList::prependUnique(void *newitem)
{
  bool retval = VoidList::prependUnique(newitem);
  adjustTail();
  return retval;
}

bool VoidTailList::appendUnique(void *newitem)
{
  bool retval = VoidList::appendUnique(newitem);
  adjustTail();
  return retval;
}

void VoidTailList::selfCheck() const
{
  VoidList::selfCheck();

  if (isNotEmpty()) {
    // get last node
    VoidNode *n = top;
    while (n->next) {
      n = n->next;
    }

    // 'tail' should be the last one
    xassert(tail == n);
  }
  else {
    xassert(tail == NULL);
  }
}

// --------------------- test code ------------------
#ifdef TEST_VDTLLIST

#include <stdio.h>    // printf

int main()
{
  VoidTailList list;
  int zero, one, two, three;

  // This isn't a very exhaustive test; it's mainly to check that
  // selfCheck doesn't do anything really stupid (it used to).

  list.selfCheck();

  list.append(&two);     list.selfCheck();
  list.prepend(&one);    list.selfCheck();
  list.append(&three);   list.selfCheck();
  list.prepend(&zero);   list.selfCheck();

  xassert(list.nth(0) == &zero);
  xassert(list.nth(1) == &one);
  xassert(list.nth(2) == &two);
  xassert(list.nth(3) == &three);

  list.removeAll();
  list.selfCheck();

  printf("vdtllist works\n");

  return 0;
}

#endif // TEST_VDTLLIST
<commit_msg>removeAt: don't need to duplicate removeFirst's work of resetting the 'tail' pointer.<commit_after>// vdtllist.cc            see license.txt for copyright and terms of use
// code for vdtllist.h

#include "vdtllist.h"      // this module

void VoidTailList::steal(VoidTailList *src)
{
  if (src) {
    top = src->top;
    tail = src->tail;
    src->top = NULL;    // paranoia
    delete src;
  }
  else {
    top = NULL;
    tail = NULL;
  }
}

void VoidTailList::prepend(void *newitem)
{
  VoidList::prepend(newitem);
  if (!tail) {
    tail = top;
  }
}

void VoidTailList::append(void *newitem)
{
  if (isEmpty()) {
    prepend(newitem);
  }
  else {
    // payoff: constant-time append
    tail->next = new VoidNode(newitem, NULL);
    tail = tail->next;
  }
}

void VoidTailList::insertAt(void *newitem, int index)
{
  VoidList::insertAt(newitem, index);
  adjustTail();
}

void VoidTailList::concat(VoidTailList &srcList)
{
  // grab what will be the tail of the concatenated list
  VoidNode *catTail = srcList.top? srcList.tail : tail;

  // build proper backbone structure
  VoidList::concat(srcList);

  // fix tails
  tail = catTail;
  srcList.tail = NULL;
}

void VoidTailList::adjustTail()
{
  if (!tail) {
    tail = top;
  }
  else if (tail->next) {
    tail = tail->next;
  }
  xassert(tail->next == NULL);
}

void *VoidTailList::removeFirst()
{
  xassert(top);
  if (top == tail) {
    tail = NULL;
  }
  void *retval = top->data;
  VoidNode *tmp = top;
  top = top->next;
  delete tmp;
  return retval;
}

void *VoidTailList::removeLast()
{
  xassert(top);
  if (top == tail) {
    return removeFirst();
  }

  VoidNode *before = top;
  while (before->next != tail) {
    before = before->next;
  }
  void *retval = tail->data;
  delete tail;
  tail = before;
  tail->next = NULL;
  return retval;
}

void *VoidTailList::removeAt(int index)
{
  xassert(top);
  if (index == 0) {
    // NOTE: removeFirst fixes the 'tail' pointer.
    return removeFirst();
  }

  VoidNode *before = top;    // will point to node before one to be removed
  index--;
  while (index > 0) {
    before = before->next;
    index--;
  }
  xassert(index == 0);

  // fix 'tail' if necessary
  if (tail == before->next) {
    tail = before;
  }

  // patch around before->next
  VoidNode *toDelete = before->next;
  void *retval = toDelete->data;
  before->next = toDelete->next;
  delete toDelete;

  return retval;
}

// for now, copy of VoidList::removeIfPresent, since the functions it calls
// are not virtual.
bool VoidTailList::removeIfPresent(void *item)
{
  // for now, not a real fast implementation
  int index = indexOf(item);
  if (index == -1) {
    return false;   // not there
  }
  else {
    removeAt(index);
    return true;
  }
}

// for now, copy of VoidList::removeItem, since the functions it calls are not
// virtual.
void VoidTailList::removeItem(void *item)
{
  bool wasThere = removeIfPresent(item);
  xassert(wasThere);
}

void VoidTailList::removeAll()
{
  VoidList::removeAll();
  tail = NULL;
}

bool VoidTailList::prependUnique(void *newitem)
{
  bool retval = VoidList::prependUnique(newitem);
  adjustTail();
  return retval;
}

bool VoidTailList::appendUnique(void *newitem)
{
  bool retval = VoidList::appendUnique(newitem);
  adjustTail();
  return retval;
}

void VoidTailList::selfCheck() const
{
  VoidList::selfCheck();

  if (isNotEmpty()) {
    // get last node
    VoidNode *n = top;
    while (n->next) {
      n = n->next;
    }

    // 'tail' should be the last one
    xassert(tail == n);
  }
  else {
    xassert(tail == NULL);
  }
}

// --------------------- test code ------------------
#ifdef TEST_VDTLLIST

#include <stdio.h>    // printf

int main()
{
  VoidTailList list;
  int zero, one, two, three;

  // This isn't a very exhaustive test; it's mainly to check that
  // selfCheck doesn't do anything really stupid (it used to).

  list.selfCheck();

  list.append(&two);     list.selfCheck();
  list.prepend(&one);    list.selfCheck();
  list.append(&three);   list.selfCheck();
  list.prepend(&zero);   list.selfCheck();

  xassert(list.nth(0) == &zero);
  xassert(list.nth(1) == &one);
  xassert(list.nth(2) == &two);
  xassert(list.nth(3) == &three);

  list.removeAll();
  list.selfCheck();

  printf("vdtllist works\n");

  return 0;
}

#endif // TEST_VDTLLIST
<|endoftext|>


<commit_before>/*
 * Ubitrack - Library for Ubiquitous Tracking
 * Copyright 2006, Technische Universitaet Muenchen, and individual
 * contributors as indicated by the @authors tag. See the
 * copyright.txt in the distribution for a full listing of individual
 * contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * @ingroup vision_components
 * @file
 * A component that recives colored images and converts them to grayscale.
 *
 * @author Christian Waechter <christian.waechter@in.tum.de>
 */

#include <string>
#include <list>
#include <iostream>

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/scoped_ptr.hpp>
#include <log4cpp/Category.hh>

#include <utDataflow/PushSupplier.h>
#include <utDataflow/PushConsumer.h>
#include <utDataflow/Component.h>
#include <utDataflow/ComponentFactory.h>
#include <utMeasurement/Measurement.h>
#include <utUtil/OS.h>
#include <utUtil/Exception.h>
#include <utVision/Image.h>
#include <utVision/OpenCLManager.h>

#include <opencv/cv.h>

using namespace Ubitrack;
using namespace Ubitrack::Vision;
using namespace Ubitrack::Measurement;

static log4cpp::Category& logger( log4cpp::Category::getInstance( "Ubitrack.Vision.ImageGPUUpload" ) );

namespace Ubitrack { namespace Drivers {

class ImageGPUUpload
	: public Dataflow::Component
{
public:

	/** constructor */
	ImageGPUUpload( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > );

	/** destructor, waits until thread stops */
	~ImageGPUUpload();

protected:
	// event handler
	void pushImage( const ImageMeasurement& m );

	unsigned m_factor;
	// the ports
	Dataflow::PushSupplier< ImageMeasurement > m_outPort;
	Dataflow::PushConsumer< ImageMeasurement > m_inPort;
};

ImageGPUUpload::ImageGPUUpload( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > subgraph )
	: Dataflow::Component( sName )
	, m_factor ( 0 )
	, m_outPort( "Output", *this )
	, m_inPort( "Input", *this, boost::bind( &ImageGPUUpload::pushImage, this, _1 ) )
{
}

ImageGPUUpload::~ImageGPUUpload()
{
}

void ImageGPUUpload::pushImage( const ImageMeasurement& m )
{
	Vision::OpenCLManager& oclManager = Vision::OpenCLManager::singleton();
	if (oclManager.isInitialized()) {
		//force upload to the GPU
		m->uMat();
	} else {
		LOG4CPP_WARN(logger, "GPU Upload node active, but OpenCL is not enabled.");
	}
	m_outPort.send( m );
}

} } // namespace Ubitrack::Driver

UBITRACK_REGISTER_COMPONENT( Dataflow::ComponentFactory* const cf ) {
	cf->registerComponent< Ubitrack::Drivers::ImageGPUUpload > ( "ImageGPUUpload" );
}
<commit_msg>lttng tracing is working good now with recent version of LTTng<commit_after>/*
 * Ubitrack - Library for Ubiquitous Tracking
 * Copyright 2006, Technische Universitaet Muenchen, and individual
 * contributors as indicated by the @authors tag. See the
 * copyright.txt in the distribution for a full listing of individual
 * contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * @ingroup vision_components
 * @file
 * A component that recives colored images and converts them to grayscale.
 *
 * @author Christian Waechter <christian.waechter@in.tum.de>
 */

#include <string>
#include <list>
#include <iostream>

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/scoped_ptr.hpp>
#include <log4cpp/Category.hh>

#include <utDataflow/PushSupplier.h>
#include <utDataflow/PushConsumer.h>
#include <utDataflow/Component.h>
#include <utDataflow/ComponentFactory.h>
#include <utMeasurement/Measurement.h>
#include <utUtil/OS.h>
#include <utUtil/Exception.h>
#include <utVision/Image.h>
#include <utVision/OpenCLManager.h>

#include <opencv/cv.h>

using namespace Ubitrack;
using namespace Ubitrack::Vision;
using namespace Ubitrack::Measurement;

static log4cpp::Category& logger( log4cpp::Category::getInstance( "Ubitrack.Vision.ImageGPUUpload" ) );

namespace Ubitrack { namespace Drivers {

class ImageGPUUpload
	: public Dataflow::Component
{
public:

	/** constructor */
	ImageGPUUpload( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > );

	/** destructor, waits until thread stops */
	~ImageGPUUpload();

protected:
	// event handler
	void pushImage( const ImageMeasurement& m );

	unsigned m_factor;
	// the ports
	Dataflow::PushSupplier< ImageMeasurement > m_outPort;
	Dataflow::PushConsumer< ImageMeasurement > m_inPort;
};

ImageGPUUpload::ImageGPUUpload( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > subgraph )
	: Dataflow::Component( sName )
	, m_factor ( 0 )
	, m_outPort( "Output", *this )
	, m_inPort( "Input", *this, boost::bind( &ImageGPUUpload::pushImage, this, _1 ) )
{
}

ImageGPUUpload::~ImageGPUUpload()
{
}

void ImageGPUUpload::pushImage( const ImageMeasurement& m )
{
	Vision::OpenCLManager& oclManager = Vision::OpenCLManager::singleton();
	if (oclManager.isInitialized()) {
		//force upload to the GPU
		m->uMat();
	} else {
		LOG4CPP_WARN(logger, "GPU Upload node active, but OpenCL is not initialized.");
	}
	m_outPort.send( m );
}

} } // namespace Ubitrack::Driver

UBITRACK_REGISTER_COMPONENT( Dataflow::ComponentFactory* const cf ) {
	cf->registerComponent< Ubitrack::Drivers::ImageGPUUpload > ( "ImageGPUUpload" );
}
<|endoftext|>


<commit_before>/* Copyright (C) 2008-2011 Xavier Pujol
   (C) 2015 Michael Walter.
   (C) 2016 Marc Stevens. (generic improvements, auxiliary solutions, subsolutions)

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

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

   You should have received a copy of the GNU Lesser General Public License
   along with fplll. If not, see <http://www.gnu.org/licenses/>. */

#include "enumerate.h"

FPLLL_BEGIN_NAMESPACE

template<typename FT>
void EnumerationDyn<FT>::enumerate(int first, int last, FT& fmaxdist, long fmaxdistexpo,
                                const vector<FT>& target_coord,
                                const vector<enumxt>& subtree,
                                const vector<enumf>& pruning,
                                bool _dual)
{
    bool solvingsvp = target_coord.empty();
    dual = _dual;
    pruning_bounds = pruning;
    if (last == -1)
        last = _gso.d;
    d = last - first;
    fx.resize(d);
    FPLLL_CHECK(d < maxdim, "enumerate: dimension is too high");
    FPLLL_CHECK((solvingsvp || !dual), "CVP for dual not implemented! What does that even mean? ");
    FPLLL_CHECK((subtree.empty() || !dual), "Subtree enumeration for dual not implemented!");

    if (solvingsvp)
    {
        for (int i = 0; i < d; ++i)
            center_partsum[i] = 0.0;
    }
    else
    {
        for (int i = 0; i < d; ++i)
            center_partsum[i] = target_coord[i + first].get_d();
    }

    FT fr, fmu, fmaxdistnorm;
    long rexpo, normexp = -1;
    for (int i = 0; i < d; ++i)
    {
        fr = _gso.get_r_exp(i + first, i + first, rexpo);
        normexp = max(normexp, rexpo + fr.exponent());
    }
    fmaxdistnorm.mul_2si(fmaxdist, dual ? normexp-fmaxdistexpo : fmaxdistexpo-normexp);
    maxdist = fmaxdistnorm.get_d(GMP_RNDU);

    _evaluator.set_normexp(normexp);

    if (dual)
    {
        for (int i = 0; i < d; ++i)
        {
            fr = _gso.get_r_exp(i + first, i + first, rexpo);
            fr.mul_2si(fr, rexpo - normexp);
            rdiag[d-i-1] = enumf(1.0)/fr.get_d();
        }
        for (int i = 0; i < d; ++i)
        {
            for (int j = i + 1; j < d; ++j)
            {
                _gso.get_mu(fmu, j + first, i + first);
                mut[d-j-1][d-i-1] = -fmu.get_d();
            }
        }
    }
    else
    {
        for (int i = 0; i < d; ++i)
        {
            fr = _gso.get_r_exp(i + first, i + first, rexpo);
            fr.mul_2si(fr, rexpo - normexp);
            rdiag[i] = fr.get_d();
        }
        for (int i = 0; i < d; ++i)
        {
            for (int j = i + 1; j < d; ++j)
            {
                _gso.get_mu(fmu, j + first, i + first);
                mut[i][j] = fmu.get_d();
            }
        }
    }
    subsoldists = rdiag;

    prepare_enumeration(subtree, solvingsvp);
    do_enumerate();

    fmaxdistnorm = maxdist; // Exact

    fmaxdist.mul_2si(fmaxdistnorm, dual ? fmaxdistexpo-normexp : normexp-fmaxdistexpo);

    if (dual && !_evaluator.sol_coord.empty())
        reverse_by_swap(_evaluator.sol_coord, 0, d-1);
}

template<typename FT>
void EnumerationDyn<FT>::prepare_enumeration(const vector<enumxt>& subtree, bool solvingsvp)
{
    bool svpbeginning = solvingsvp;

    enumf newdist = 0.0;
    k_end = d - subtree.size();
    for (k = d - 1; k >= 0 && newdist <= maxdist; --k)
    {
        enumf newcenter = center_partsum[k];
        if (k >= k_end)
        {
            // use subtree
            x[k] = subtree[k - k_end];

            if (x[k] != 0)
                svpbeginning = false;

            for (int j = 0; j < k; ++j)
                center_partsum[j] -= x[k] * mut[j][k];
        }
        else
        {
            if (dual)
            {
                for (int j = k + 1; j < k_end; ++j)
                    newcenter -= alpha[j] * mut[k][j];
            }
            else
            {
                for (int j = k + 1; j < k_end; ++j)
                    newcenter -= x[j] * mut[k][j];
            }
            roundto(x[k], newcenter); // newX = rint(newCenter) / lrint(newCenter)
            center[k] = newcenter;
            partdist[k] = newdist;
            dx[k] = ddx[k] = (((int)(newcenter >= x[k]) & 1) << 1) - 1;
        }
        alpha[k] = x[k] - newcenter;
        newdist += alpha[k] * alpha[k] * rdiag[k];
    }
    if (!svpbeginning)
    {
        k_max = k_end; // The last non-zero coordinate of x will not stay positive
    }
    else
    {
        k_max = 0;
        x[0] = 1; // Excludes (0,...,0) from the enumeration
    }
    ++k;
}

template<typename FT>
void EnumerationDyn<FT>::set_bounds()
{
    if (pruning_bounds.empty())
    {
        fill(&partdistbounds[0] + 0, &partdistbounds[0] + d, maxdist);
    }
    else
    {
        for (int i = 0; i < d; ++i)
            partdistbounds[i] = pruning_bounds[i] * maxdist;
    }
}

template<typename FT>
void EnumerationDyn<FT>::process_solution(enumf newmaxdist)
{
    for (int j = 0; j < d; ++j)
        fx[j] = x[j];
    _evaluator.eval_sol(fx, newmaxdist, maxdist);

    set_bounds();
}

template<typename FT>
void EnumerationDyn<FT>::process_subsolution(int offset, enumf newdist)
{
    for (int j = 0; j < offset; ++j)
        fx[j] = 0.0;
    for (int j = offset; j < d; ++j)
        fx[j] = x[j];
    _evaluator.eval_sub_sol(k, fx, newdist);
}

template<typename FT>
void EnumerationDyn<FT>::do_enumerate()
{
    nodes = 0;

    save_rounding();

    set_bounds();

    if      ( dual &&  _evaluator.findsubsols)
        enumerate_loop<true,true>();
    else if (!dual &&  _evaluator.findsubsols)
        enumerate_loop<false,true>();
    else if ( dual && !_evaluator.findsubsols)
        enumerate_loop<true,false>();
    else if (!dual && !_evaluator.findsubsols)
        enumerate_loop<false,false>();

    restore_rounding();
}

template class Enumeration<FP_NR<double> >;

#ifdef FPLLL_WITH_LONG_DOUBLE
template class Enumeration<FP_NR<long double> >;
#endif

#ifdef FPLLL_WITH_QD
template class Enumeration<FP_NR<dd_real> >;

template class Enumeration<FP_NR<qd_real> >;
#endif

#ifdef FPLLL_WITH_DPE
template class Enumeration<FP_NR<dpe_t> >;
#endif

template class Enumeration<FP_NR<mpfr_t> >;

FPLLL_END_NAMESPACE
<commit_msg>Ensure that prepare_enumeration also uses the correct floating point rounding mode.<commit_after>/* Copyright (C) 2008-2011 Xavier Pujol
   (C) 2015 Michael Walter.
   (C) 2016 Marc Stevens. (generic improvements, auxiliary solutions, subsolutions)

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

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

   You should have received a copy of the GNU Lesser General Public License
   along with fplll. If not, see <http://www.gnu.org/licenses/>. */

#include "enumerate.h"

FPLLL_BEGIN_NAMESPACE

template<typename FT>
void EnumerationDyn<FT>::enumerate(int first, int last, FT& fmaxdist, long fmaxdistexpo,
                                const vector<FT>& target_coord,
                                const vector<enumxt>& subtree,
                                const vector<enumf>& pruning,
                                bool _dual)
{
    bool solvingsvp = target_coord.empty();
    dual = _dual;
    pruning_bounds = pruning;
    if (last == -1)
        last = _gso.d;
    d = last - first;
    fx.resize(d);
    FPLLL_CHECK(d < maxdim, "enumerate: dimension is too high");
    FPLLL_CHECK((solvingsvp || !dual), "CVP for dual not implemented! What does that even mean? ");
    FPLLL_CHECK((subtree.empty() || !dual), "Subtree enumeration for dual not implemented!");

    if (solvingsvp)
    {
        for (int i = 0; i < d; ++i)
            center_partsum[i] = 0.0;
    }
    else
    {
        for (int i = 0; i < d; ++i)
            center_partsum[i] = target_coord[i + first].get_d();
    }

    FT fr, fmu, fmaxdistnorm;
    long rexpo, normexp = -1;
    for (int i = 0; i < d; ++i)
    {
        fr = _gso.get_r_exp(i + first, i + first, rexpo);
        normexp = max(normexp, rexpo + fr.exponent());
    }
    fmaxdistnorm.mul_2si(fmaxdist, dual ? normexp-fmaxdistexpo : fmaxdistexpo-normexp);
    maxdist = fmaxdistnorm.get_d(GMP_RNDU);

    _evaluator.set_normexp(normexp);

    if (dual)
    {
        for (int i = 0; i < d; ++i)
        {
            fr = _gso.get_r_exp(i + first, i + first, rexpo);
            fr.mul_2si(fr, rexpo - normexp);
            rdiag[d-i-1] = enumf(1.0)/fr.get_d();
        }
        for (int i = 0; i < d; ++i)
        {
            for (int j = i + 1; j < d; ++j)
            {
                _gso.get_mu(fmu, j + first, i + first);
                mut[d-j-1][d-i-1] = -fmu.get_d();
            }
        }
    }
    else
    {
        for (int i = 0; i < d; ++i)
        {
            fr = _gso.get_r_exp(i + first, i + first, rexpo);
            fr.mul_2si(fr, rexpo - normexp);
            rdiag[i] = fr.get_d();
        }
        for (int i = 0; i < d; ++i)
        {
            for (int j = i + 1; j < d; ++j)
            {
                _gso.get_mu(fmu, j + first, i + first);
                mut[i][j] = fmu.get_d();
            }
        }
    }
    subsoldists = rdiag;

    save_rounding();
    prepare_enumeration(subtree, solvingsvp);
    do_enumerate();
    restore_rounding();

    fmaxdistnorm = maxdist; // Exact

    fmaxdist.mul_2si(fmaxdistnorm, dual ? fmaxdistexpo-normexp : normexp-fmaxdistexpo);

    if (dual && !_evaluator.sol_coord.empty())
        reverse_by_swap(_evaluator.sol_coord, 0, d-1);
}

template<typename FT>
void EnumerationDyn<FT>::prepare_enumeration(const vector<enumxt>& subtree, bool solvingsvp)
{
    bool svpbeginning = solvingsvp;

    enumf newdist = 0.0;
    k_end = d - subtree.size();
    for (k = d - 1; k >= 0 && newdist <= maxdist; --k)
    {
        enumf newcenter = center_partsum[k];
        if (k >= k_end)
        {
            // use subtree
            x[k] = subtree[k - k_end];

            if (x[k] != 0)
                svpbeginning = false;

            for (int j = 0; j < k; ++j)
                center_partsum[j] -= x[k] * mut[j][k];
        }
        else
        {
            if (dual)
            {
                for (int j = k + 1; j < k_end; ++j)
                    newcenter -= alpha[j] * mut[k][j];
            }
            else
            {
                for (int j = k + 1; j < k_end; ++j)
                    newcenter -= x[j] * mut[k][j];
            }
            roundto(x[k], newcenter); // newX = rint(newCenter) / lrint(newCenter)
            center[k] = newcenter;
            partdist[k] = newdist;
            dx[k] = ddx[k] = (((int)(newcenter >= x[k]) & 1) << 1) - 1;
        }
        alpha[k] = x[k] - newcenter;
        newdist += alpha[k] * alpha[k] * rdiag[k];
    }
    if (!svpbeginning)
    {
        k_max = k_end; // The last non-zero coordinate of x will not stay positive
    }
    else
    {
        k_max = 0;
        x[0] = 1; // Excludes (0,...,0) from the enumeration
    }
    ++k;
}

template<typename FT>
void EnumerationDyn<FT>::set_bounds()
{
    if (pruning_bounds.empty())
    {
        fill(&partdistbounds[0] + 0, &partdistbounds[0] + d, maxdist);
    }
    else
    {
        for (int i = 0; i < d; ++i)
            partdistbounds[i] = pruning_bounds[i] * maxdist;
    }
}

template<typename FT>
void EnumerationDyn<FT>::process_solution(enumf newmaxdist)
{
    for (int j = 0; j < d; ++j)
        fx[j] = x[j];
    _evaluator.eval_sol(fx, newmaxdist, maxdist);

    set_bounds();
}

template<typename FT>
void EnumerationDyn<FT>::process_subsolution(int offset, enumf newdist)
{
    for (int j = 0; j < offset; ++j)
        fx[j] = 0.0;
    for (int j = offset; j < d; ++j)
        fx[j] = x[j];
    _evaluator.eval_sub_sol(k, fx, newdist);
}

template<typename FT>
void EnumerationDyn<FT>::do_enumerate()
{
    nodes = 0;

    set_bounds();

    if      ( dual &&  _evaluator.findsubsols)
        enumerate_loop<true,true>();
    else if (!dual &&  _evaluator.findsubsols)
        enumerate_loop<false,true>();
    else if ( dual && !_evaluator.findsubsols)
        enumerate_loop<true,false>();
    else if (!dual && !_evaluator.findsubsols)
        enumerate_loop<false,false>();
}

template class Enumeration<FP_NR<double> >;

#ifdef FPLLL_WITH_LONG_DOUBLE
template class Enumeration<FP_NR<long double> >;
#endif

#ifdef FPLLL_WITH_QD
template class Enumeration<FP_NR<dd_real> >;

template class Enumeration<FP_NR<qd_real> >;
#endif

#ifdef FPLLL_WITH_DPE
template class Enumeration<FP_NR<dpe_t> >;
#endif

template class Enumeration<FP_NR<mpfr_t> >;

FPLLL_END_NAMESPACE
<|endoftext|>


<commit_before><commit_msg>mandoline: fix key accelerators on linux.<commit_after><|endoftext|>


<commit_before>
/// PROJECT
#include <csapex/model/tickable_node.h>
#include <csapex/msg/io.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/any_message.h>
#include <csapex/model/token.h>

using namespace csapex;
using namespace csapex::connection_types;

namespace csapex
{

class Throttle : public TickableNode
{
public:
    Throttle()
    {
    }

    void setup(csapex::NodeModifier& modifier) override
    {
        modifier.addTypedSlot<AnyMessage>("Message", [this](const TokenPtr& token) {
            data_ = token->getTokenData();
        });
        out_ = modifier.addOutput<AnyMessage>("Throttled");
    }

    void setupParameters(csapex::Parameterizable& params) override
    {
        params.addParameter(param::ParameterFactory::declareRange("frequency", 0.1, 100.0, 10.0, 0.1),
                            [this](param::Parameter* p) {
            setTickFrequency(std::max(0.1, p->as<double>()));
        });
    }

    bool canTick() override
    {
        return data_ != nullptr;
    }

    void tick() override
    {
        msg::publish(out_, data_);
        data_.reset();
    }

private:
    Output* out_;

    TokenDataConstPtr data_;
};

} // csapex

CSAPEX_REGISTER_CLASS(csapex::Throttle, csapex::Node)

<commit_msg>ported throttle<commit_after>
/// PROJECT
#include <csapex/model/throttled_node.h>
#include <csapex/msg/io.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/any_message.h>
#include <csapex/model/token.h>
#include <csapex/model/node_handle.h>
#include <csapex/model/node_state.h>

using namespace csapex;
using namespace csapex::connection_types;

namespace csapex
{

class Throttle : public ThrottledNode
{
public:
    Throttle()
    {
    }

    void setup(csapex::NodeModifier& modifier) override
    {
        modifier.addTypedSlot<AnyMessage>("Message", [this](const TokenPtr& token) {
            data_ = token->getTokenData();
            yield();
        });
        out_ = modifier.addOutput<AnyMessage>("Throttled");
    }

    void setupParameters(csapex::Parameterizable& params) override
    {
       ThrottledNode::setupParameter(params, "frequency");
    }

    bool canProcess() const override
    {
        return data_ != nullptr;
    }

    void process() override
    {
        msg::publish(out_, data_);
        data_.reset();
    }

private:
    Output* out_;

    TokenDataConstPtr data_;
};

} // csapex

CSAPEX_REGISTER_CLASS(csapex::Throttle, csapex::Node)

<|endoftext|>


<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "drivers/TimerEvent.h"
#include "cmsis.h"

#include <stddef.h>
#include "hal/ticker_api.h"
#include "hal/us_ticker_api.h"

namespace mbed {

TimerEvent::TimerEvent() : event(), _ticker_data(get_us_ticker_data()) {
    ticker_set_handler(_ticker_data, (&TimerEvent::irq));
}

TimerEvent::TimerEvent(const ticker_data_t *data) : event(), _ticker_data(data) {
    ticker_set_handler(_ticker_data, (&TimerEvent::irq));
}

void TimerEvent::irq(uint32_t id) {
    TimerEvent *timer_event = (TimerEvent*)id;
    timer_event->handler();
}

TimerEvent::~TimerEvent() {
    remove();
}

// insert in to linked list
void TimerEvent::insert(timestamp_t timestamp) {
    ticker_insert_event(_ticker_data, &event, timestamp, (uint32_t)this);
}

void TimerEvent::insert_absolute(us_timestamp_t timestamp) {
    ticker_insert_event(_ticker_data, &event, timestamp, (uint32_t)this);
}

void TimerEvent::remove() {
    ticker_remove_event(_ticker_data, &event);
}

} // namespace mbed
<commit_msg>TimerEvent: Use ticker_insert_event_us instead of the old API in insert_absolute.<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "drivers/TimerEvent.h"
#include "cmsis.h"

#include <stddef.h>
#include "hal/ticker_api.h"
#include "hal/us_ticker_api.h"

namespace mbed {

TimerEvent::TimerEvent() : event(), _ticker_data(get_us_ticker_data()) {
    ticker_set_handler(_ticker_data, (&TimerEvent::irq));
}

TimerEvent::TimerEvent(const ticker_data_t *data) : event(), _ticker_data(data) {
    ticker_set_handler(_ticker_data, (&TimerEvent::irq));
}

void TimerEvent::irq(uint32_t id) {
    TimerEvent *timer_event = (TimerEvent*)id;
    timer_event->handler();
}

TimerEvent::~TimerEvent() {
    remove();
}

// insert in to linked list
void TimerEvent::insert(timestamp_t timestamp) {
    ticker_insert_event(_ticker_data, &event, timestamp, (uint32_t)this);
}

void TimerEvent::insert_absolute(us_timestamp_t timestamp) {
    ticker_insert_event_us(_ticker_data, &event, timestamp, (uint32_t)this);
}

void TimerEvent::remove() {
    ticker_remove_event(_ticker_data, &event);
}

} // namespace mbed
<|endoftext|>