<commit_before>#include <unistd.h>

#include <event2/event.h>
#include <event2/thread.h>

#include <process/logging.hpp>

#include "event_loop.hpp"
#include "libevent.hpp"

namespace process {

struct event_base* base = NULL;

void* EventLoop::run(void*)
{
  int result = event_base_loop(base, 0);
  if (result < 0) {
    LOG(FATAL) << "Failed to run event loop";
  } else if (result == 1) {
    VLOG(1) << "Finished running event loop due to lack of events";
  }

  return NULL;
}

void EventLoop::initialize()
{
  if (evthread_use_pthreads() < 0) {
    LOG(FATAL) << "Failed to initialize, evthread_use_pthreads";
  }

  // This enables debugging of libevent calls. We can remove this
  // when the implementation settles and after we gain confidence.
  event_enable_debug_mode();

  base = event_base_new();
  if (base == NULL) {
    LOG(FATAL) << "Failed to initialize, event_base_new";
  }
}

} // namespace process {
<commit_msg>Introduce libevent clock implementation.<commit_after>#include <unistd.h>

#include <event2/event.h>
#include <event2/thread.h>

#include <process/logging.hpp>

#include "event_loop.hpp"
#include "libevent.hpp"
#include "synchronized.hpp"

namespace process {

struct event_base* base = NULL;

void* EventLoop::run(void*)
{
  do {
    int result = event_base_loop(base, EVLOOP_ONCE);
    if (result < 0) {
      LOG(FATAL) << "Failed to run event loop";
    } else if (result == 1) {
      VLOG(1) << "All events handled, continuing event loop";
      continue;
    } else if (event_base_got_break(base)) {
      break;
    } else if (event_base_got_exit(base)) {
      break;
    }
  } while (true);
  return NULL;
}

namespace internal {

struct Delay
{
  void(*function)(void);
  event* timer;
};

void handle_delay(int, short, void* arg)
{
  Delay* delay = reinterpret_cast<Delay*>(arg);
  delay->function();
  delete delay;
}

}  // namespace internal {

void EventLoop::delay(const Duration& duration, void(*function)(void))
{
  internal::Delay* delay = new internal::Delay();
  delay->timer = evtimer_new(base, &internal::handle_delay, delay);
  if (delay->timer == NULL) {
    LOG(FATAL) << "Failed to delay, evtimer_new";
  }

  delay->function = function;

  timeval t{0, 0};
  if (duration > Seconds(0)) {
    t = duration.timeval();
  }

  evtimer_add(delay->timer, &t);
}

double EventLoop::time()
{
  // Get the cached time if running the event loop, or call
  // gettimeofday() to get the current time. Since a lot of logic in
  // libprocess depends on time math, we want to log fatal rather than
  // cause logic errors if the time fails.
  timeval t;
  if (event_base_gettimeofday_cached(base, &t) < 0) {
    LOG(FATAL) << "Failed to get time, event_base_gettimeofday_cached";
  }

  return Duration(t).secs();
}

void EventLoop::initialize()
{
  if (evthread_use_pthreads() < 0) {
    LOG(FATAL) << "Failed to initialize, evthread_use_pthreads";
  }

  // This enables debugging of libevent calls. We can remove this
  // when the implementation settles and after we gain confidence.
  event_enable_debug_mode();

  base = event_base_new();
  if (base == NULL) {
    LOG(FATAL) << "Failed to initialize, event_base_new";
  }
}

} // namespace process {
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <cmath>
#include <memory>

namespace choreograph
{

/// Define our Time type here so it's easier to change out if needed.
/// Float loses precision pretty quickly, but is fast and doesn't take up much space.
/// Also, since only Motions keep playheads, we only need enough precision for our longest Motion.
using Time = float;

template<typename T>
class Sequence;

///
/// A Source of motion.
/// Virtual base class with concept of value and implementation of time.
///
template<typename T>
class Source
{
public:
  Source() = default;

  Source( Time duration ):
    _duration( duration )
  {}

  virtual ~Source() = default;

  /// Override to provide value at requested time.
  /// Returns the interpolated value at the given time.
  virtual T getValue( Time atTime ) const = 0;

  /// Override to provide value at start (and before).
  virtual T getStartValue() const = 0;

  /// Override to provide value at end (and beyond).
  virtual T getEndValue() const = 0;

  /// Override to provide a copy of the derived Source. Needed for phrases to be copy-composable.
  virtual std::unique_ptr<Source<T>> clone() const = 0;

  /// Returns the Source value at \a time, looping past the end from inflection point to the end.
  /// Relies on the subclass implementation of getValue( t ).
  T getValueWrapped( Time time, Time inflectionPoint = 0.0f ) const { return getValue( wrapTime( time, inflectionPoint ) ); }

  /// Returns normalized time if t is in range [start_time, end_time].
  inline Time normalizeTime( Time t ) const { return t / _duration; }
  /// Returns the duration of this source.
  inline Time getDuration() const { return _duration; }

  /// Wrap \a time around \a inflectionPoint in the Sequence.
  Time wrapTime( Time time, Time inflectionPoint = 0.0f ) const
  {
    if( time > getDuration() ) {
      return inflectionPoint + std::fmodf( time, getDuration() - inflectionPoint );
    }
    else {
      return time;
    }
  }

private:
  Time _duration = 1;

  friend class Sequence<T>;
};

template<typename T>
using SourceRef = std::shared_ptr<Source<T>>;

template<typename T>
using SourceUniqueRef = std::unique_ptr<Source<T>>;

} // namespace choreograph
<commit_msg>Note about double by Time alias.<commit_after>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <cmath>
#include <memory>

namespace choreograph
{

/// Define our Time type here so it's easier to change out if needed.
/// Float loses precision pretty quickly, but is fast and doesn't take up much space.
/// Sub in double if you find yourself needing extra precision for time.
/// Also, since only Motions keep playheads, we only need enough precision for our longest Motion.
using Time = float;

template<typename T>
class Sequence;

///
/// A Source of motion.
/// Virtual base class with concept of value and implementation of time.
///
template<typename T>
class Source
{
public:
  Source() = default;

  Source( Time duration ):
    _duration( duration )
  {}

  virtual ~Source() = default;

  /// Override to provide value at requested time.
  /// Returns the interpolated value at the given time.
  virtual T getValue( Time atTime ) const = 0;

  /// Override to provide value at start (and before).
  virtual T getStartValue() const = 0;

  /// Override to provide value at end (and beyond).
  virtual T getEndValue() const = 0;

  /// Override to provide a copy of the derived Source. Needed for phrases to be copy-composable.
  virtual std::unique_ptr<Source<T>> clone() const = 0;

  /// Returns the Source value at \a time, looping past the end from inflection point to the end.
  /// Relies on the subclass implementation of getValue( t ).
  T getValueWrapped( Time time, Time inflectionPoint = 0.0f ) const { return getValue( wrapTime( time, inflectionPoint ) ); }

  /// Returns normalized time if t is in range [start_time, end_time].
  inline Time normalizeTime( Time t ) const { return t / _duration; }
  /// Returns the duration of this source.
  inline Time getDuration() const { return _duration; }

  /// Wrap \a time around \a inflectionPoint in the Sequence.
  Time wrapTime( Time time, Time inflectionPoint = 0.0f ) const
  {
    if( time > getDuration() ) {
      return inflectionPoint + std::fmodf( time, getDuration() - inflectionPoint );
    }
    else {
      return time;
    }
  }

private:
  Time _duration = 1;

  friend class Sequence<T>;
};

template<typename T>
using SourceRef = std::shared_ptr<Source<T>>;

template<typename T>
using SourceUniqueRef = std::unique_ptr<Source<T>>;

} // namespace choreograph
<|endoftext|>


<commit_before><commit_msg>planning: fix active_set_spline_2d_solver compile warning.<commit_after><|endoftext|>


<commit_before>/*
 Copyright (c) 2012, The Cinder Project, All rights reserved.
 Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.

 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#define ASIO_STANDALONE 1
#include "asio/asio.hpp"

#include "cinder/app/AppBase.h"
#include "cinder/app/Renderer.h"
#include "cinder/Camera.h"
#include "cinder/System.h"
#include "cinder/Utilities.h"
#include "cinder/Timeline.h"
#include "cinder/Thread.h"
#include "cinder/Log.h"

using namespace std;

namespace cinder { namespace app {

AppBase*					AppBase::sInstance = nullptr;			// Static instance of App, effectively a singleton
AppBase::Settings*			AppBase::sSettingsFromMain;
static std::thread::id		sPrimaryThreadId = std::this_thread::get_id();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// App::Settings
AppBase::Settings::Settings()
{
	mShouldQuit = false;
	mPowerManagement = false;
	mFrameRateEnabled = true;
	mFrameRate = 60.0f;
	mEnableHighDensityDisplay = false;
	mEnableMultiTouch = false;
}

void AppBase::Settings::init( const RendererRef &defaultRenderer, const char *title, int argc, char * const argv[] )
{
	mDefaultRenderer = defaultRenderer;
	if( title )
		mTitle = title;

	for( int arg = 0; arg < argc; ++arg )
		mCommandLineArgs.push_back( argv[arg] );
}

void AppBase::Settings::disableFrameRate()
{
	mFrameRateEnabled = false;
}

void AppBase::Settings::setFrameRate( float frameRate )
{
	mFrameRate = frameRate;
}

void AppBase::Settings::enablePowerManagement( bool powerManagement )
{
	mPowerManagement = powerManagement;
}

void AppBase::Settings::prepareWindow( const Window::Format &format )
{
	mWindowFormats.push_back( format );
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// App::App
AppBase::AppBase()
	: mFrameCount( 0 ), mAverageFps( 0 ), mFpsSampleInterval( 1 ), mTimer( true ), mTimeline( Timeline::create() ),
		mFpsLastSampleFrame( 0 ), mFpsLastSampleTime( 0 )
{
	sInstance = this;

	CI_ASSERT( sSettingsFromMain );
	mDefaultRenderer = sSettingsFromMain->getDefaultRenderer();
	mMultiTouchEnabled = sSettingsFromMain->isMultiTouchEnabled();
	mHighDensityDisplayEnabled = sSettingsFromMain->isHighDensityDisplayEnabled();
	mFrameRateEnabled = sSettingsFromMain->isFrameRateEnabled();

	mIo = shared_ptr<asio::io_service>( new asio::io_service() );
	mIoWork = shared_ptr<asio::io_service::work>( new asio::io_service::work( *mIo ) );

	// due to an issue with boost::filesystem's static initialization on Windows,
	// it's necessary to create a fs::path here in case of secondary threads doing the same thing simultaneously
#if (defined( CINDER_MSW ) || defined ( CINDER_WINRT ))
	fs::path dummyPath( "dummy" );
#endif
}

AppBase::~AppBase()
{
	mIo->stop();
}

void AppBase::privateSetup__()
{
	mTimeline->stepTo( static_cast<float>( getElapsedSeconds() ) );

	setup();
}

void AppBase::privateUpdate__()
{
	mFrameCount++;

	// service asio::io_service
	mIo->poll();

	if( getNumWindows() > 0 ) {
		WindowRef mainWin = getWindowIndex( 0 );
		if( mainWin )
			mainWin->getRenderer()->makeCurrentContext();
	}

	mSignalUpdate();

	update();

	mTimeline->stepTo( static_cast<float>( getElapsedSeconds() ) );

	double now = mTimer.getSeconds();
	if( now > mFpsLastSampleTime + mFpsSampleInterval ) {
		//calculate average Fps over sample interval
		uint32_t framesPassed = mFrameCount - mFpsLastSampleFrame;
		mAverageFps = (float)(framesPassed / (now - mFpsLastSampleTime));

		mFpsLastSampleTime = now;
		mFpsLastSampleFrame = mFrameCount;
	}
}

void AppBase::emitShutdown()
{
	mSignalShutdown();
}

void AppBase::emitWillResignActive()
{
	mSignalWillResignActive();
}

void AppBase::emitDidBecomeActive()
{
	mSignalDidBecomeActive();
}

fs::path AppBase::getOpenFilePath( const fs::path &initialPath, const vector<string> &extensions )
{
	return Platform::get()->getOpenFilePath( initialPath, extensions );
}

fs::path AppBase::getFolderPath( const fs::path &initialPath )
{
	return Platform::get()->getFolderPath( initialPath );
}

fs::path AppBase::getSaveFilePath( const fs::path &initialPath, const vector<string> &extensions )
{
	return Platform::get()->getSaveFilePath( initialPath, extensions );
}

std::ostream& AppBase::console()
{
	return Platform::get()->console();
}

bool AppBase::isPrimaryThread()
{
	return std::this_thread::get_id() == sPrimaryThreadId;
}

void AppBase::dispatchAsync( const std::function<void()> &fn )
{
	io_service().post( fn );
}

Surface	AppBase::copyWindowSurface()
{
	return getWindow()->getRenderer()->copyWindowSurface( getWindow()->toPixels( getWindow()->getBounds() ) );
}

Surface	AppBase::copyWindowSurface( const Area &area )
{
	Area clippedArea = area.getClipBy( getWindowBounds() );
	return getWindow()->getRenderer()->copyWindowSurface( clippedArea );
}

RendererRef AppBase::findSharedRenderer( RendererRef searchRenderer ) const
{
	if( ! searchRenderer )
		return RendererRef();

	for( size_t winIdx = 0; winIdx < getNumWindows(); ++winIdx ) {
		RendererRef thisRenderer = getWindowIndex( winIdx )->getRenderer();
		if( thisRenderer && (typeid( *thisRenderer ) == typeid(*searchRenderer)) )
			return getWindowIndex( winIdx )->getRenderer();
	}

	return RendererRef(); // didn't find one
}

// These are called by application instantiation macros
// static
void AppBase::prepareLaunch()
{
	Platform::get()->prepareLaunch();
}

// static
void AppBase::initialize( Settings *settings, const RendererRef &defaultRenderer, const char *title, int argc, char * const argv[] )
{
	settings->init( defaultRenderer, title, argc, argv );

	sSettingsFromMain = settings;
}

// TODO: try to make this non-static, just calls launch() that is wrapped in try/catch
// - need to get through windows updates first
// static
void AppBase::executeLaunch( const char *title, int argc, char * const argv[] )
{
	try {
		sInstance->launch( title, argc, argv );
	}
	catch( std::exception &exc ) {
		CI_LOG_E( "Uncaught exception, type: " << ci::System::demangleTypeName( typeid( exc ).name() ) << ", what : " << exc.what() );
		throw;
	}
}

// static
void AppBase::cleanupLaunch()
{
	Platform::get()->cleanupLaunch();
}

} } // namespace cinder::app<commit_msg>moved the static instantiation functions higher up in AppBase.cpp, grouping them with the constructor and destructor<commit_after>/*
 Copyright (c) 2012, The Cinder Project, All rights reserved.
 Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.

 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#define ASIO_STANDALONE 1
#include "asio/asio.hpp"

#include "cinder/app/AppBase.h"
#include "cinder/app/Renderer.h"
#include "cinder/Camera.h"
#include "cinder/System.h"
#include "cinder/Utilities.h"
#include "cinder/Timeline.h"
#include "cinder/Thread.h"
#include "cinder/Log.h"

using namespace std;

namespace cinder { namespace app {

AppBase*					AppBase::sInstance = nullptr;			// Static instance of App, effectively a singleton
AppBase::Settings*			AppBase::sSettingsFromMain;
static std::thread::id		sPrimaryThreadId = std::this_thread::get_id();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AppBase::Settings

AppBase::Settings::Settings()
{
	mShouldQuit = false;
	mPowerManagement = false;
	mFrameRateEnabled = true;
	mFrameRate = 60.0f;
	mEnableHighDensityDisplay = false;
	mEnableMultiTouch = false;
}

void AppBase::Settings::init( const RendererRef &defaultRenderer, const char *title, int argc, char * const argv[] )
{
	mDefaultRenderer = defaultRenderer;
	if( title )
		mTitle = title;

	for( int arg = 0; arg < argc; ++arg )
		mCommandLineArgs.push_back( argv[arg] );
}

void AppBase::Settings::disableFrameRate()
{
	mFrameRateEnabled = false;
}

void AppBase::Settings::setFrameRate( float frameRate )
{
	mFrameRate = frameRate;
}

void AppBase::Settings::enablePowerManagement( bool powerManagement )
{
	mPowerManagement = powerManagement;
}

void AppBase::Settings::prepareWindow( const Window::Format &format )
{
	mWindowFormats.push_back( format );
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AppBase

AppBase::AppBase()
	: mFrameCount( 0 ), mAverageFps( 0 ), mFpsSampleInterval( 1 ), mTimer( true ), mTimeline( Timeline::create() ),
		mFpsLastSampleFrame( 0 ), mFpsLastSampleTime( 0 )
{
	sInstance = this;

	CI_ASSERT( sSettingsFromMain );
	mDefaultRenderer = sSettingsFromMain->getDefaultRenderer();
	mMultiTouchEnabled = sSettingsFromMain->isMultiTouchEnabled();
	mHighDensityDisplayEnabled = sSettingsFromMain->isHighDensityDisplayEnabled();
	mFrameRateEnabled = sSettingsFromMain->isFrameRateEnabled();

	mIo = shared_ptr<asio::io_service>( new asio::io_service() );
	mIoWork = shared_ptr<asio::io_service::work>( new asio::io_service::work( *mIo ) );

	// due to an issue with boost::filesystem's static initialization on Windows,
	// it's necessary to create a fs::path here in case of secondary threads doing the same thing simultaneously
#if (defined( CINDER_MSW ) || defined ( CINDER_WINRT ))
	fs::path dummyPath( "dummy" );
#endif
}

AppBase::~AppBase()
{
	mIo->stop();
}

// These are called by application instantiation main functions
// static
void AppBase::prepareLaunch()
{
	Platform::get()->prepareLaunch();
}

// static
void AppBase::initialize( Settings *settings, const RendererRef &defaultRenderer, const char *title, int argc, char * const argv[] )
{
	settings->init( defaultRenderer, title, argc, argv );

	sSettingsFromMain = settings;
}

// TODO: try to make this non-static, just calls launch() that is wrapped in try/catch
// - need to get through windows updates first
// static
void AppBase::executeLaunch( const char *title, int argc, char * const argv[] )
{
	try {
		sInstance->launch( title, argc, argv );
	}
	catch( std::exception &exc ) {
		CI_LOG_E( "Uncaught exception, type: " << ci::System::demangleTypeName( typeid( exc ).name() ) << ", what : " << exc.what() );
		throw;
	}
}

// static
void AppBase::cleanupLaunch()
{
	Platform::get()->cleanupLaunch();
}

void AppBase::privateSetup__()
{
	mTimeline->stepTo( static_cast<float>( getElapsedSeconds() ) );

	setup();
}

void AppBase::privateUpdate__()
{
	mFrameCount++;

	// service asio::io_service
	mIo->poll();

	if( getNumWindows() > 0 ) {
		WindowRef mainWin = getWindowIndex( 0 );
		if( mainWin )
			mainWin->getRenderer()->makeCurrentContext();
	}

	mSignalUpdate();

	update();

	mTimeline->stepTo( static_cast<float>( getElapsedSeconds() ) );

	double now = mTimer.getSeconds();
	if( now > mFpsLastSampleTime + mFpsSampleInterval ) {
		//calculate average Fps over sample interval
		uint32_t framesPassed = mFrameCount - mFpsLastSampleFrame;
		mAverageFps = (float)(framesPassed / (now - mFpsLastSampleTime));

		mFpsLastSampleTime = now;
		mFpsLastSampleFrame = mFrameCount;
	}
}

void AppBase::emitShutdown()
{
	mSignalShutdown();
}

void AppBase::emitWillResignActive()
{
	mSignalWillResignActive();
}

void AppBase::emitDidBecomeActive()
{
	mSignalDidBecomeActive();
}

fs::path AppBase::getOpenFilePath( const fs::path &initialPath, const vector<string> &extensions )
{
	return Platform::get()->getOpenFilePath( initialPath, extensions );
}

fs::path AppBase::getFolderPath( const fs::path &initialPath )
{
	return Platform::get()->getFolderPath( initialPath );
}

fs::path AppBase::getSaveFilePath( const fs::path &initialPath, const vector<string> &extensions )
{
	return Platform::get()->getSaveFilePath( initialPath, extensions );
}

std::ostream& AppBase::console()
{
	return Platform::get()->console();
}

bool AppBase::isPrimaryThread()
{
	return std::this_thread::get_id() == sPrimaryThreadId;
}

void AppBase::dispatchAsync( const std::function<void()> &fn )
{
	io_service().post( fn );
}

Surface	AppBase::copyWindowSurface()
{
	return getWindow()->getRenderer()->copyWindowSurface( getWindow()->toPixels( getWindow()->getBounds() ) );
}

Surface	AppBase::copyWindowSurface( const Area &area )
{
	Area clippedArea = area.getClipBy( getWindowBounds() );
	return getWindow()->getRenderer()->copyWindowSurface( clippedArea );
}

RendererRef AppBase::findSharedRenderer( RendererRef searchRenderer ) const
{
	if( ! searchRenderer )
		return RendererRef();

	for( size_t winIdx = 0; winIdx < getNumWindows(); ++winIdx ) {
		RendererRef thisRenderer = getWindowIndex( winIdx )->getRenderer();
		if( thisRenderer && (typeid( *thisRenderer ) == typeid(*searchRenderer)) )
			return getWindowIndex( winIdx )->getRenderer();
	}

	return RendererRef(); // didn't find one
}

} } // namespace cinder::app<|endoftext|>


<commit_before>/*
    This file is part of the KDE alarm daemon.
    Copyright (c) 2000 Cornelius Schumacher <schumacher@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; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

// $Id$

#include <qhbox.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qfile.h>
#include <qspinbox.h>

#include <klocale.h>
#include <kprocess.h>
#include <kaudioplayer.h>
#include <kdebug.h>
#include <knotifyclient.h>

#include <libkcal/event.h>

#include "koeventviewer.h"

#include "alarmdialog.h"
#include "alarmdialog.moc"

AlarmDialog::AlarmDialog(QWidget *parent,const char *name)
  : KDialogBase(parent,name,false,i18n("Alarm"),Ok|User1,Ok,false,
                i18n("Suspend"))
{
  QVBox *topBox = new QVBox(this);
  topBox->setSpacing(spacingHint());
  setMainWidget(topBox);

  (void)new QLabel(i18n("The following events triggered alarms:"),topBox);

  mIncidences.setAutoDelete(true);

  mEventViewer = new KOEventViewer(topBox);

  QHBox *suspendBox = new QHBox(topBox);
  suspendBox->setSpacing(spacingHint());

  (void)new QLabel(i18n("Suspend duration (minutes):"),suspendBox);
  mSuspendSpin = new QSpinBox(1,60,1,suspendBox);
  mSuspendSpin->setValue(5);  // default suspend duration

  setMinimumSize(300,200);
}

AlarmDialog::~AlarmDialog()
{
}

void AlarmDialog::appendEvent(Event *event)
{
  mEventViewer->appendEvent(event);
  mIncidences.append(event->clone());
}

void AlarmDialog::appendTodo(Todo *todo)
{
  mEventViewer->appendTodo(todo);
  mIncidences.append(todo->clone());
}

void AlarmDialog::clearEvents()
{
  mEventViewer->clearEvents();

  mIncidences.clear();
}

void AlarmDialog::slotOk()
{
  clearEvents();
  accept();
}

void AlarmDialog::slotUser1()
{
  emit suspendSignal(mSuspendSpin->value());
  accept();
}

void AlarmDialog::eventNotification()
{
  bool beeped = false;

  Incidence *in;
  for (in = mIncidences.first(); in; in = mIncidences.next()) {
    QPtrList<Alarm> alarms = in->alarms();
    const Alarm* alarm;
    for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
// TODO: Check whether this should be done for all multiple alarms
      QString program = alarm->programFile();
      if (!program.isEmpty()) {
        kdDebug() << "Starting program: '" << program << "'" << endl;
        KProcess proc;
        proc << QFile::encodeName(alarm->programFile());
        proc.start(KProcess::DontCare);
      }

      if (!alarm->audioFile().isEmpty()) {
        beeped = true;
        KAudioPlayer::play(QFile::encodeName(alarm->audioFile()));
      }
    }
  }

  if ( !beeped ) {
    KNotifyClient::beep();
  }
}
<commit_msg>disable defaultbutton to prevent the windows being closed accidentally<commit_after>/*
    This file is part of the KDE alarm daemon.
    Copyright (c) 2000 Cornelius Schumacher <schumacher@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; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

// $Id$

#include <qhbox.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qfile.h>
#include <qspinbox.h>

#include <klocale.h>
#include <kprocess.h>
#include <kaudioplayer.h>
#include <kdebug.h>
#include <knotifyclient.h>

#include <libkcal/event.h>

#include "koeventviewer.h"

#include "alarmdialog.h"
#include "alarmdialog.moc"

AlarmDialog::AlarmDialog(QWidget *parent,const char *name)
  : KDialogBase(parent,name,false,i18n("Alarm"),Ok|User1|User2,User2,false,
                i18n("Suspend"))
{
  QVBox *topBox = new QVBox(this);
  topBox->setSpacing(spacingHint());
  setMainWidget(topBox);

  (void)new QLabel(i18n("The following events triggered alarms:"),topBox);

  mIncidences.setAutoDelete(true);

  mEventViewer = new KOEventViewer(topBox);

  QHBox *suspendBox = new QHBox(topBox);
  suspendBox->setSpacing(spacingHint());

  (void)new QLabel(i18n("Suspend duration (minutes):"),suspendBox);
  mSuspendSpin = new QSpinBox(1,60,1,suspendBox);
  mSuspendSpin->setValue(5);  // default suspend duration

  showButton(User2, false);

  setMinimumSize(300,200);
}

AlarmDialog::~AlarmDialog()
{
}

void AlarmDialog::appendEvent(Event *event)
{
  mEventViewer->appendEvent(event);
  mIncidences.append(event->clone());
}

void AlarmDialog::appendTodo(Todo *todo)
{
  mEventViewer->appendTodo(todo);
  mIncidences.append(todo->clone());
}

void AlarmDialog::clearEvents()
{
  mEventViewer->clearEvents();

  mIncidences.clear();
}

void AlarmDialog::slotOk()
{
  clearEvents();
  accept();
}

void AlarmDialog::slotUser1()
{
  emit suspendSignal(mSuspendSpin->value());
  accept();
}

void AlarmDialog::eventNotification()
{
  bool beeped = false;

  Incidence *in;
  for (in = mIncidences.first(); in; in = mIncidences.next()) {
    QPtrList<Alarm> alarms = in->alarms();
    const Alarm* alarm;
    for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
// TODO: Check whether this should be done for all multiple alarms
      QString program = alarm->programFile();
      if (!program.isEmpty()) {
        kdDebug() << "Starting program: '" << program << "'" << endl;
        KProcess proc;
        proc << QFile::encodeName(alarm->programFile());
        proc.start(KProcess::DontCare);
      }

      if (!alarm->audioFile().isEmpty()) {
        beeped = true;
        KAudioPlayer::play(QFile::encodeName(alarm->audioFile()));
      }
    }
  }

  if ( !beeped ) {
    KNotifyClient::beep();
  }
}
<|endoftext|>


<commit_before>/*
 * File:   ILocalizer.hpp
 * Author: sgaspari
 *
 * Created on November 18, 2015, 12:01 PM
 */

#pragma once

#include "LocalizationResult.hpp"

#include <openMVG/image/image_container.hpp>
#include <openMVG/features/image_describer.hpp>
#include <openMVG/cameras/Camera_Pinhole_Radial.hpp>
#include <openMVG/robust_estimation/robust_estimators.hpp>
#include <openMVG/numeric/numeric.h>

namespace openMVG {
namespace localization {

struct LocalizerParameters
{
  LocalizerParameters() :
  _visualDebug(""),
  _refineIntrinsics(false),
  _fDistRatio(0.8),
  _featurePreset(features::EDESCRIBER_PRESET::ULTRA_PRESET),
  _errorMax(std::numeric_limits<double>::infinity()),
  _resectionEstimator(robust::ROBUST_ESTIMATOR_ACRANSAC),
  _matchingEstimator(robust::ROBUST_ESTIMATOR_ACRANSAC),
  _useLocalizeRigNaive(false),
  _angularThreshold(D2R(0.1)) { }

  virtual ~LocalizerParameters() = 0;

  /// enable visual debugging options
  std::string _visualDebug;
  /// whether or not the Intrinsics of the query camera has to be refined
  bool _refineIntrinsics;
  /// the distance ratio to use when matching feature with the ratio test
  float _fDistRatio;
  /// the preset to use for feature extraction of the query image
  features::EDESCRIBER_PRESET _featurePreset;
  /// maximum reprojection error allowed for resectioning
  double _errorMax;
  /// the type of *sac framework to use for resection
  robust::EROBUST_ESTIMATOR _resectionEstimator;
  /// the type of *sac framework to use for matching
  robust::EROBUST_ESTIMATOR _matchingEstimator;
  /// force the use of the rig localization without openGV
  bool _useLocalizeRigNaive;
  /// in rad, it is the maximum angular error for the opengv rig resection
  double _angularThreshold;
};

inline LocalizerParameters::~LocalizerParameters() {}

using OccurenceKey = IndMatch3D2D;
using OccurenceMap = std::map<OccurenceKey, std::size_t>;

class ILocalizer
{
public:
    ILocalizer() : _isInit(false) { };

    // Only relevant for CCTagLocalizer
    virtual void setCudaPipe(int) { }

    bool isInit() {return _isInit;}

    const sfm::SfM_Data& getSfMData() const {return _sfm_data; }

    /**
   * @brief Localize one image
   *
   * @param[in] imageGrey The input greyscale image.
   * @param[in] param The parameters for the localization.
   * @param[in] useInputIntrinsics Uses the \p queryIntrinsics as known calibration.
   * @param[in,out] queryIntrinsics Intrinsic parameters of the camera, they are used if the
   * flag useInputIntrinsics is set to true, otherwise they are estimated from the correspondences.
   * @param[out] localizationResult The localization result containing the pose and the associations.
   * @param[in] imagePath Optional complete path to the image, used only for debugging purposes.
   * @return  true if the image has been successfully localized.
   */
  virtual bool localize(const image::Image<unsigned char> & imageGrey,
                        const LocalizerParameters *param,
                        bool useInputIntrinsics,
                        cameras::Pinhole_Intrinsic_Radial_K3 &queryIntrinsics,
                        LocalizationResult & localizationResult,
                        const std::string& imagePath = std::string()) = 0;

  virtual bool localize(const features::MapRegionsPerDesc &queryRegions,
                        const std::pair<std::size_t, std::size_t> &imageSize,
                        const LocalizerParameters *param,
                        bool useInputIntrinsics,
                        cameras::Pinhole_Intrinsic_Radial_K3 &queryIntrinsics,
                        LocalizationResult & localizationResult,
                        const std::string& imagePath = std::string()) = 0;

  virtual bool localizeRig(const std::vector<image::Image<unsigned char> > & vec_imageGrey,
                           const LocalizerParameters *param,
                           std::vector<cameras::Pinhole_Intrinsic_Radial_K3 > &vec_queryIntrinsics,
                           const std::vector<geometry::Pose3 > &vec_subPoses,
                           geometry::Pose3 &rigPose,
                           std::vector<LocalizationResult>& vec_locResults)=0;

  virtual bool localizeRig(const std::vector<features::MapRegionsPerDesc> & vec_queryRegions,
                           const std::vector<std::pair<std::size_t, std::size_t> > &imageSize,
                           const LocalizerParameters *param,
                           std::vector<cameras::Pinhole_Intrinsic_Radial_K3 > &vec_queryIntrinsics,
                           const std::vector<geometry::Pose3 > &vec_subPoses,
                           geometry::Pose3 &rigPose,
                           std::vector<LocalizationResult>& vec_locResults)=0;

  virtual ~ILocalizer( ) {}

protected:
  bool _isInit;
  sfm::SfM_Data _sfm_data;

};

} //namespace openMVG
} //namespace localization

<commit_msg>[localization] Add 'const' for ILocalizer 'isInit' method<commit_after>/*
 * File:   ILocalizer.hpp
 * Author: sgaspari
 *
 * Created on November 18, 2015, 12:01 PM
 */

#pragma once

#include "LocalizationResult.hpp"

#include <openMVG/image/image_container.hpp>
#include <openMVG/features/image_describer.hpp>
#include <openMVG/cameras/Camera_Pinhole_Radial.hpp>
#include <openMVG/robust_estimation/robust_estimators.hpp>
#include <openMVG/numeric/numeric.h>

namespace openMVG {
namespace localization {

struct LocalizerParameters
{
  LocalizerParameters() :
  _visualDebug(""),
  _refineIntrinsics(false),
  _fDistRatio(0.8),
  _featurePreset(features::EDESCRIBER_PRESET::ULTRA_PRESET),
  _errorMax(std::numeric_limits<double>::infinity()),
  _resectionEstimator(robust::ROBUST_ESTIMATOR_ACRANSAC),
  _matchingEstimator(robust::ROBUST_ESTIMATOR_ACRANSAC),
  _useLocalizeRigNaive(false),
  _angularThreshold(D2R(0.1)) { }

  virtual ~LocalizerParameters() = 0;

  /// enable visual debugging options
  std::string _visualDebug;
  /// whether or not the Intrinsics of the query camera has to be refined
  bool _refineIntrinsics;
  /// the distance ratio to use when matching feature with the ratio test
  float _fDistRatio;
  /// the preset to use for feature extraction of the query image
  features::EDESCRIBER_PRESET _featurePreset;
  /// maximum reprojection error allowed for resectioning
  double _errorMax;
  /// the type of *sac framework to use for resection
  robust::EROBUST_ESTIMATOR _resectionEstimator;
  /// the type of *sac framework to use for matching
  robust::EROBUST_ESTIMATOR _matchingEstimator;
  /// force the use of the rig localization without openGV
  bool _useLocalizeRigNaive;
  /// in rad, it is the maximum angular error for the opengv rig resection
  double _angularThreshold;
};

inline LocalizerParameters::~LocalizerParameters() {}

using OccurenceKey = IndMatch3D2D;
using OccurenceMap = std::map<OccurenceKey, std::size_t>;

class ILocalizer
{
public:
    ILocalizer() : _isInit(false) { };

    // Only relevant for CCTagLocalizer
    virtual void setCudaPipe(int) { }

    bool isInit() const {return _isInit;}

    const sfm::SfM_Data& getSfMData() const {return _sfm_data; }

    /**
   * @brief Localize one image
   *
   * @param[in] imageGrey The input greyscale image.
   * @param[in] param The parameters for the localization.
   * @param[in] useInputIntrinsics Uses the \p queryIntrinsics as known calibration.
   * @param[in,out] queryIntrinsics Intrinsic parameters of the camera, they are used if the
   * flag useInputIntrinsics is set to true, otherwise they are estimated from the correspondences.
   * @param[out] localizationResult The localization result containing the pose and the associations.
   * @param[in] imagePath Optional complete path to the image, used only for debugging purposes.
   * @return  true if the image has been successfully localized.
   */
  virtual bool localize(const image::Image<unsigned char> & imageGrey,
                        const LocalizerParameters *param,
                        bool useInputIntrinsics,
                        cameras::Pinhole_Intrinsic_Radial_K3 &queryIntrinsics,
                        LocalizationResult & localizationResult,
                        const std::string& imagePath = std::string()) = 0;

  virtual bool localize(const features::MapRegionsPerDesc &queryRegions,
                        const std::pair<std::size_t, std::size_t> &imageSize,
                        const LocalizerParameters *param,
                        bool useInputIntrinsics,
                        cameras::Pinhole_Intrinsic_Radial_K3 &queryIntrinsics,
                        LocalizationResult & localizationResult,
                        const std::string& imagePath = std::string()) = 0;

  virtual bool localizeRig(const std::vector<image::Image<unsigned char> > & vec_imageGrey,
                           const LocalizerParameters *param,
                           std::vector<cameras::Pinhole_Intrinsic_Radial_K3 > &vec_queryIntrinsics,
                           const std::vector<geometry::Pose3 > &vec_subPoses,
                           geometry::Pose3 &rigPose,
                           std::vector<LocalizationResult>& vec_locResults)=0;

  virtual bool localizeRig(const std::vector<features::MapRegionsPerDesc> & vec_queryRegions,
                           const std::vector<std::pair<std::size_t, std::size_t> > &imageSize,
                           const LocalizerParameters *param,
                           std::vector<cameras::Pinhole_Intrinsic_Radial_K3 > &vec_queryIntrinsics,
                           const std::vector<geometry::Pose3 > &vec_subPoses,
                           geometry::Pose3 &rigPose,
                           std::vector<LocalizationResult>& vec_locResults)=0;

  virtual ~ILocalizer( ) {}

protected:
  bool _isInit;
  sfm::SfM_Data _sfm_data;

};

} //namespace openMVG
} //namespace localization

<|endoftext|>


<commit_before>#include "pass_bits/optimiser/parallel_swarm_search.hpp"
#include "pass_bits/helper/random.hpp"
#include <cmath> // std::pow

pass::parallel_swarm_search::parallel_swarm_search() noexcept
    : optimiser("Parallel_Swarm_Search"),
      swarm_size(40),
      inertia(1.0 / (2.0 * std::log(2.0))),
      cognitive_acceleration(0.5 + std::log(2.0)),
      social_acceleration(cognitive_acceleration),
      neighbourhood_probability(1.0 -
                                std::pow(1.0 - 1.0 / static_cast<double>(swarm_size), 3.0)),
      number_threads(pass::number_of_threads())
#if defined(SUPPORT_MPI)
      ,
      migration_stall(0)
#endif
{
}

pass::optimise_result pass::parallel_swarm_search::optimise(
    const pass::problem &problem)
{
  assert(inertia >= -1.0 && inertia <= 1.0 && "'inertia' should be greater or equal than 0.0");
  assert(cognitive_acceleration >= 0.0 && "'cognitive_acceleration' should be greater or equal than 0.0");
  assert(social_acceleration >= 0.0 && "'social_acceleration' should be greater or equal than 0.0");
  assert(neighbourhood_probability > 0.0 && neighbourhood_probability <= 1.0 &&
         "'neighbourhood_probability' should be a value between 0.0 and 1.0");
  assert(swarm_size > 0 && "Can't generate 0 agents");
  assert(number_threads > 0 && "The number of threads should be greater than 0");
#if defined(SUPPORT_MPI)
  assert(migration_stall >= 0 && "The number of threads should be greater or equal than 0");
#endif

  // Variables used to analyse the behavior of a particle
  arma::mat verbose(maximal_iterations + 1, 3);

  pass::stopwatch stopwatch;
  stopwatch.start();

  // Restart variabel
  arma::uword same_value = 0;

  // Variables needed
  pass::optimise_result result(problem, acceptable_fitness_value);

  arma::mat positions;
  arma::mat velocities(problem.dimension(), swarm_size);

  arma::mat personal_best_positions;
  arma::rowvec personal_best_fitness_values(swarm_size);

  arma::umat topology(swarm_size, swarm_size);

  arma::vec local_best_position;
  double local_best_fitness_value;

  arma::vec attraction_center;
  arma::vec weighted_personal_attraction;
  arma::vec weighted_local_attraction;

  double fitness_value;

restart: // Restart point

  // Initialise the positions and the velocities
  // Particle data, stored column-wise.
  if (result.iterations == 0)
  {
    positions = problem.normalised_hammersley_agents(swarm_size);
  }
  else
  {
    positions = problem.initialise_normalised_agents(swarm_size);
  }

  for (arma::uword col = 0; col < swarm_size; ++col)
  {
    for (arma::uword row = 0; row < problem.dimension(); ++row)
    {
      velocities(row, col) = random_double_uniform_in_range(
          0.0 - positions(row, col),
          1.0 - positions(row, col));
    }
  }

  personal_best_positions = positions;

  // Evaluate the initial positions.
  // Compute the fitness.
  // Begin with the previous best set to this initial position
  for (arma::uword n = 0; n < swarm_size; ++n)
  {
    fitness_value = problem.evaluate_normalised(positions.col(n));
    personal_best_fitness_values(n) = fitness_value;

    if (fitness_value <= result.fitness_value)
    {
      result.normalised_agent = positions.col(n);
      result.fitness_value = fitness_value;
    }
  }
  ++result.iterations;

  /**
   * +------------+---------------+----------+
   * | Iterations | Fitness Value | Position |
   * +------------+---------------+----------+
   * Each Dimension is independent. So, the analysis can be performed
   * on just one dimension
   * NOT VALID FOR Velocity
   */
  if (pass::is_verbose)
  {
    if (maximal_iterations != std::numeric_limits<arma::uword>::max() && maximal_iterations > 0)
    {
      verbose(result.iterations, 0) = result.iterations;
      verbose(result.iterations, 1) = result.fitness_value;
      verbose(result.iterations, 2) = result.normalised_agent[0];
    }
    else
    {
      throw std::runtime_error(
          "Please set - maximal_iterations - to a valid number to analyse the behaviour of the algorithm.");
    }
  }
  //end initialisation

  bool randomize_topology = true;

  // termination criteria.
  while (stopwatch.get_elapsed() < maximal_duration &&
         result.iterations < maximal_iterations && result.evaluations < maximal_evaluations && !result.solved())
  {
    if (randomize_topology)
    {
      topology = (arma::mat(swarm_size, swarm_size,
                            arma::fill::randu) < neighbourhood_probability);
      // When searching for the best neighbour, we begin with the particles
      // personal best value; We don't need to visit it twice.
      topology.diag().fill(0);
    }
    randomize_topology = true;

#if defined(SUPPORT_MPI)
    for (arma::uword ms = 0; ms <= migration_stall; ++ms)
    {
#endif

#if defined(SUPPORT_OPENMP)
#pragma omp parallel proc_bind(close) num_threads(number_threads)
      { //parallel region start
#pragma omp for private(local_best_position, local_best_fitness_value, attraction_center, weighted_personal_attraction, weighted_local_attraction, fitness_value) firstprivate(topology) schedule(static)
#endif

        // iterate over the particles
        for (arma::uword n = 0; n < swarm_size; ++n)
        {
          // l_i^t
          local_best_position = personal_best_positions.col(n);
          local_best_fitness_value = personal_best_fitness_values(n);

          // check the topology to identify with which particle you communicate
          for (arma::uword i = 0; i < swarm_size; i++)
          {
            if (topology(n, i) && personal_best_fitness_values(i) < local_best_fitness_value)
            {
              local_best_fitness_value = personal_best_fitness_values(i);
              local_best_position = personal_best_positions.col(i);
            }
          }

          //p_i
          weighted_personal_attraction = positions.col(n) +
                                         random_double_uniform_in_range(0.0, cognitive_acceleration) *
                                             (personal_best_positions.col(n) - positions.col(n));

          // l_i
          weighted_local_attraction = positions.col(n) +
                                      random_double_uniform_in_range(0.0, social_acceleration) *
                                          (local_best_position - positions.col(n));

          // If the best informant is the particle itself, define the gravity center G as the middle of x-p'
          if (personal_best_fitness_values(n) == local_best_fitness_value)
          {
            attraction_center = 0.5 * (positions.col(n) + weighted_personal_attraction);
          }
          else
          {
            attraction_center = (positions.col(n) + weighted_personal_attraction + weighted_local_attraction) / 3.0;
          }

          velocities.col(n) = inertia * velocities.col(n) +
                              random_neighbour(attraction_center, 0.0, arma::norm(attraction_center - positions.col(n))) -
                              positions.col(n);

          // move by applying this new velocity to the current position
          positions.col(n) = positions.col(n) + velocities.col(n);

          // stay inside the bounds
          for (arma::uword k = 0; k < problem.dimension(); ++k)
          {
            if (positions(k, n) < 0)
            {
              positions(k, n) = 0;
              velocities(k, n) = -0.5 * velocities(k, n);
            }
            else if (positions(k, n) > 1)
            {
              positions(k, n) = 1;
              velocities(k, n) = -0.5 * velocities(k, n);
            }
          }

          // evaluate the new position
          fitness_value = problem.evaluate_normalised(positions.col(n));

          if (fitness_value < personal_best_fitness_values(n))
          {
            personal_best_positions.col(n) = positions.col(n);
            personal_best_fitness_values(n) = fitness_value;

#if defined(SUPPORT_OPENMP)
#pragma omp critical
            { // critical region start
#endif
              // Restart criteria
              if (result.fitness_value - fitness_value > pass::precision)
              {
                result.normalised_agent = positions.col(n);
                result.fitness_value = fitness_value;
                randomize_topology = false;
                same_value = 0;
              }
              else
              {
                same_value++;
              }

#if defined(SUPPORT_OPENMP)
            } // crititcal region end
#endif
          }
        }
#if defined(SUPPORT_OPENMP)
      } //parallel region end
#endif

      ++result.iterations;
      result.evaluations = result.iterations * swarm_size;

#if defined(SUPPORT_MPI)
      if (stopwatch.get_elapsed() > maximal_duration ||
          result.iterations >= maximal_iterations || result.evaluations >= maximal_evaluations || result.solved())
      {
        break;
      }
    } // end migration stall
#endif

#if defined(SUPPORT_MPI)
    // Island model for PSO
    struct
    {
      double fitness_value;
      int best_rank;
    } mpi;

    mpi.best_rank = pass::node_rank();
    mpi.fitness_value = result.fitness_value;

    /**
      * All Reduce returns the minimum value of Fitness_value and the rank of the process that owns it.
      */
    MPI_Allreduce(MPI_IN_PLACE, &mpi, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);

    /**
      * The rank with the minimum Fitness_value broadcast his agent to the others
      */
    MPI_Bcast(result.normalised_agent.memptr(), result.normalised_agent.n_elem, MPI_DOUBLE, mpi.best_rank, MPI_COMM_WORLD);

    result.fitness_value = mpi.fitness_value;

    if (pass::node_rank() != mpi.best_rank)
    {
      // Find the worst agent and replace it with the best one
      arma::uword min_index = personal_best_fitness_values.index_min();

      personal_best_positions.col(min_index) = result.normalised_agent;
      positions.col(min_index) = result.normalised_agent;
      personal_best_fitness_values(min_index) = result.fitness_value;
    }
#endif

    /**
     * Restart the algorithm
     * If the algorithm does not found a better fitness value within 3000 iterations, it restarts.
     * Precision for a better fitness value is 1-e06
     * If it is restarted then choose random through hammersley or random initialisation
     */
    if (same_value >= 3000)
    {
      same_value = 0;
      goto restart;
    }

    /**
     * +------------+---------------+----------+
     * | Iterations | Fitness Value | Position |
     * +------------+---------------+----------+
     * Each Dimension is independent. So, the analysis can be performed
     * on just one dimension
     * NOT VALID FOR Velocity
     */
    if (pass::is_verbose)
    {
      verbose(result.iterations, 0) = result.iterations;
      verbose(result.iterations, 1) = result.fitness_value;
      verbose(result.iterations, 2) = result.normalised_agent[0];
    }
  } // end while for termination criteria

  result.duration = stopwatch.get_elapsed();

  // Save the file
  if (pass::is_verbose)
  {
    verbose.shed_row(0);
    verbose.save("Verbose_Optimiser_" + name + "_Problem_" + problem.name + "_Dim_" +
                     std::to_string(problem.dimension()) +
                     "_Run_" + std::to_string(pass::global_number_of_runs),
                 arma::raw_ascii);
  }

  return result;
}
<commit_msg>bug fix<commit_after>#include "pass_bits/optimiser/parallel_swarm_search.hpp"
#include "pass_bits/helper/random.hpp"
#include <cmath> // std::pow

pass::parallel_swarm_search::parallel_swarm_search() noexcept
    : optimiser("Parallel_Swarm_Search"),
      swarm_size(40),
      inertia(1.0 / (2.0 * std::log(2.0))),
      cognitive_acceleration(0.5 + std::log(2.0)),
      social_acceleration(cognitive_acceleration),
      neighbourhood_probability(1.0 -
                                std::pow(1.0 - 1.0 / static_cast<double>(swarm_size), 3.0)),
      number_threads(pass::number_of_threads())
#if defined(SUPPORT_MPI)
      ,
      migration_stall(0)
#endif
{
}

pass::optimise_result pass::parallel_swarm_search::optimise(
    const pass::problem &problem)
{
  assert(inertia >= -1.0 && inertia <= 1.0 && "'inertia' should be greater or equal than 0.0");
  assert(cognitive_acceleration >= 0.0 && "'cognitive_acceleration' should be greater or equal than 0.0");
  assert(social_acceleration >= 0.0 && "'social_acceleration' should be greater or equal than 0.0");
  assert(neighbourhood_probability > 0.0 && neighbourhood_probability <= 1.0 &&
         "'neighbourhood_probability' should be a value between 0.0 and 1.0");
  assert(swarm_size > 0 && "Can't generate 0 agents");
  assert(number_threads > 0 && "The number of threads should be greater than 0");
#if defined(SUPPORT_MPI)
  assert(migration_stall >= 0 && "The number of threads should be greater or equal than 0");
#endif

  // Variables used to analyse the behavior of a particle
  arma::mat verbose(maximal_iterations + 1, 3);

  pass::stopwatch stopwatch;
  stopwatch.start();

  // Restart variabel
  arma::uword same_value = 0;

  // Variables needed
  pass::optimise_result result(problem, acceptable_fitness_value);

  arma::mat positions;
  arma::mat velocities(problem.dimension(), swarm_size);

  arma::mat personal_best_positions;
  arma::rowvec personal_best_fitness_values(swarm_size);

  arma::umat topology(swarm_size, swarm_size);

  arma::vec local_best_position;
  double local_best_fitness_value;

  arma::vec attraction_center;
  arma::vec weighted_personal_attraction;
  arma::vec weighted_local_attraction;

  double fitness_value;

restart: // Restart point

  // Initialise the positions and the velocities
  // Particle data, stored column-wise.
  if (result.iterations == 0)
  {
    positions = problem.normalised_hammersley_agents(swarm_size);
  }
  else
  {
    positions = problem.initialise_normalised_agents(swarm_size);
  }

  for (arma::uword col = 0; col < swarm_size; ++col)
  {
    for (arma::uword row = 0; row < problem.dimension(); ++row)
    {
      velocities(row, col) = random_double_uniform_in_range(
          0.0 - positions(row, col),
          1.0 - positions(row, col));
    }
  }

  personal_best_positions = positions;

  // Evaluate the initial positions.
  // Compute the fitness.
  // Begin with the previous best set to this initial position
  for (arma::uword n = 0; n < swarm_size; ++n)
  {
    fitness_value = problem.evaluate_normalised(positions.col(n));
    personal_best_fitness_values(n) = fitness_value;

    if (fitness_value <= result.fitness_value)
    {
      result.normalised_agent = positions.col(n);
      result.fitness_value = fitness_value;
    }
  }
  ++result.iterations;

  /**
   * +------------+---------------+----------+
   * | Iterations | Fitness Value | Position |
   * +------------+---------------+----------+
   * Each Dimension is independent. So, the analysis can be performed
   * on just one dimension
   * NOT VALID FOR Velocity
   */
  if (pass::is_verbose)
  {
    if (maximal_iterations != std::numeric_limits<arma::uword>::max() && maximal_iterations > 0)
    {
      verbose(result.iterations, 0) = result.iterations;
      verbose(result.iterations, 1) = result.fitness_value;
      verbose(result.iterations, 2) = result.normalised_agent[0];
    }
    else
    {
      throw std::runtime_error(
          "Please set - maximal_iterations - to a valid number to analyse the behaviour of the algorithm.");
    }
  }
  //end initialisation

  bool randomize_topology = true;

  // termination criteria.
  while (stopwatch.get_elapsed() < maximal_duration &&
         result.iterations < maximal_iterations && result.evaluations < maximal_evaluations && !result.solved())
  {
    if (randomize_topology)
    {
      topology = (arma::mat(swarm_size, swarm_size,
                            arma::fill::randu) < neighbourhood_probability);
      // When searching for the best neighbour, we begin with the particles
      // personal best value; We don't need to visit it twice.
      topology.diag().fill(0);
    }
    randomize_topology = true;

#if defined(SUPPORT_MPI)
    for (arma::uword ms = 0; ms <= migration_stall; ++ms)
    {
#endif

#if defined(SUPPORT_OPENMP)
#pragma omp parallel proc_bind(close) num_threads(number_threads)
      { //parallel region start
#pragma omp for private(local_best_position, local_best_fitness_value, attraction_center, weighted_personal_attraction, weighted_local_attraction, fitness_value) firstprivate(topology) schedule(static)
#endif

        // iterate over the particles
        for (arma::uword n = 0; n < swarm_size; ++n)
        {
          // l_i^t
          local_best_position = personal_best_positions.col(n);
          local_best_fitness_value = personal_best_fitness_values(n);

          // check the topology to identify with which particle you communicate
          for (arma::uword i = 0; i < swarm_size; i++)
          {
            if (topology(n, i) && personal_best_fitness_values(i) < local_best_fitness_value)
            {
              local_best_fitness_value = personal_best_fitness_values(i);
              local_best_position = personal_best_positions.col(i);
            }
          }

          /**
           * Compute the new velocity
           * If OpenMP is activated, make sure the random numbers are thread safe
           */
#if defined(SUPPORT_OPENMP)
          arma::arma_rng::set_seed_random();
#endif

          //p_i
          weighted_personal_attraction = positions.col(n) +
                                         random_double_uniform_in_range(0.0, cognitive_acceleration) *
                                             (personal_best_positions.col(n) - positions.col(n));

          // l_i
          weighted_local_attraction = positions.col(n) +
                                      random_double_uniform_in_range(0.0, social_acceleration) *
                                          (local_best_position - positions.col(n));

          // If the best informant is the particle itself, define the gravity center G as the middle of x-p'
          if (personal_best_fitness_values(n) == local_best_fitness_value)
          {
            attraction_center = 0.5 * (positions.col(n) + weighted_personal_attraction);
          }
          else
          {
            attraction_center = (positions.col(n) + weighted_personal_attraction + weighted_local_attraction) / 3.0;
          }

          velocities.col(n) = inertia * velocities.col(n) +
                              random_neighbour(attraction_center, 0.0, arma::norm(attraction_center - positions.col(n))) -
                              positions.col(n);

          // move by applying this new velocity to the current position
          positions.col(n) = positions.col(n) + velocities.col(n);

          // stay inside the bounds
          for (arma::uword k = 0; k < problem.dimension(); ++k)
          {
            if (positions(k, n) < 0)
            {
              positions(k, n) = 0;
              velocities(k, n) = -0.5 * velocities(k, n);
            }
            else if (positions(k, n) > 1)
            {
              positions(k, n) = 1;
              velocities(k, n) = -0.5 * velocities(k, n);
            }
          }

          // evaluate the new position
          fitness_value = problem.evaluate_normalised(positions.col(n));

          if (fitness_value < personal_best_fitness_values(n))
          {
            personal_best_positions.col(n) = positions.col(n);
            personal_best_fitness_values(n) = fitness_value;

#if defined(SUPPORT_OPENMP)
#pragma omp critical
            { // critical region start
#endif
              // Restart criteria
              if (result.fitness_value - fitness_value > pass::precision)
              {
                result.normalised_agent = positions.col(n);
                result.fitness_value = fitness_value;
                randomize_topology = false;
                same_value = 0;
              }
              else
              {
                same_value++;
              }

#if defined(SUPPORT_OPENMP)
            } // crititcal region end
#endif
          }
        }
#if defined(SUPPORT_OPENMP)
      } //parallel region end
#endif

      ++result.iterations;
      result.evaluations = result.iterations * swarm_size;

#if defined(SUPPORT_MPI)
      if (stopwatch.get_elapsed() > maximal_duration ||
          result.iterations >= maximal_iterations || result.evaluations >= maximal_evaluations || result.solved())
      {
        break;
      }
    } // end migration stall
#endif

#if defined(SUPPORT_MPI)
    // Island model for PSO
    struct
    {
      double fitness_value;
      int best_rank;
    } mpi;

    mpi.best_rank = pass::node_rank();
    mpi.fitness_value = result.fitness_value;

    /**
      * All Reduce returns the minimum value of Fitness_value and the rank of the process that owns it.
      */
    MPI_Allreduce(MPI_IN_PLACE, &mpi, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);

    /**
      * The rank with the minimum Fitness_value broadcast his agent to the others
      */
    MPI_Bcast(result.normalised_agent.memptr(), result.normalised_agent.n_elem, MPI_DOUBLE, mpi.best_rank, MPI_COMM_WORLD);

    result.fitness_value = mpi.fitness_value;

    if (pass::node_rank() != mpi.best_rank)
    {
      // Find the worst agent and replace it with the best one
      arma::uword min_index = personal_best_fitness_values.index_min();

      personal_best_positions.col(min_index) = result.normalised_agent;
      positions.col(min_index) = result.normalised_agent;
      personal_best_fitness_values(min_index) = result.fitness_value;
    }
#endif

    /**
     * Restart the algorithm
     * If the algorithm does not found a better fitness value within 3000 iterations, it restarts.
     * Precision for a better fitness value is 1-e06
     * If it is restarted then choose random through hammersley or random initialisation
     */
    if (same_value >= 3000)
    {
      same_value = 0;
      goto restart;
    }

    /**
     * +------------+---------------+----------+
     * | Iterations | Fitness Value | Position |
     * +------------+---------------+----------+
     * Each Dimension is independent. So, the analysis can be performed
     * on just one dimension
     * NOT VALID FOR Velocity
     */
    if (pass::is_verbose)
    {
      verbose(result.iterations, 0) = result.iterations;
      verbose(result.iterations, 1) = result.fitness_value;
      verbose(result.iterations, 2) = result.normalised_agent[0];
    }
  } // end while for termination criteria

  result.duration = stopwatch.get_elapsed();

  // Save the file
  if (pass::is_verbose)
  {
    verbose.shed_row(0);
    verbose.save("Verbose_Optimiser_" + name + "_Problem_" + problem.name + "_Dim_" +
                     std::to_string(problem.dimension()) +
                     "_Run_" + std::to_string(pass::global_number_of_runs),
                 arma::raw_ascii);
  }

  return result;
}
<|endoftext|>


<commit_before>#include "prog_translator.h"

#include <algorithm>

#include "CoinPackedVector.hpp"
#include "OsiSolverInterface.hpp"

#include "cyc_limits.h"
#include "error.h"
#include "exchange_graph.h"
#include "exchange_solver.h"
#include "logger.h"

namespace cyclus {

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface)
    : g_(g),
      iface_(iface),
      excl_(false),
      pseudo_cost_(std::numeric_limits<double>::max()) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               bool exclusive)
    : g_(g),
      iface_(iface),
      excl_(exclusive),
      pseudo_cost_(std::numeric_limits<double>::max()) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               double pseudo_cost)
    : g_(g),
      iface_(iface),
      excl_(false),
      pseudo_cost_(pseudo_cost) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               bool exclusive, double pseudo_cost)
    : g_(g),
      iface_(iface),
      excl_(exclusive),
      pseudo_cost_(pseudo_cost) {
  Init();
}

void ProgTranslator::Init() {
  arc_offset_ = g_->arcs().size();
  int n_cols = arc_offset_ + g_->request_groups().size();
  ctx_.obj_coeffs.resize(n_cols);
  ctx_.col_ubs.resize(n_cols);
  ctx_.col_lbs.resize(n_cols);
  ctx_.m = CoinPackedMatrix(false, 0, 0);
}

void ProgTranslator::CheckPref(double pref) {
  if (pref <= 0) {
    std::stringstream ss;
    ss << "Preference value found to be nonpositive (" << pref
       << "). Preferences must be positive when using an optimization solver."
       << " If using Cyclus in simulation mode (e.g., from the command line),"
       << " this error is likely a bug in Cyclus. Please report it to the developer's "
       << "list (https://groups.google.com/forum/#!forum/cyclus-dev).";
    throw ValueError(ss.str());
  }
}

void ProgTranslator::Translate() {
  // number of variables = number of arcs + 1 faux arc per request group with arcs
  int nfalse = 0;
  std::vector<RequestGroup::Ptr>& rgs = g_->request_groups();
  for (int i = 0; i != g_->request_groups().size(); ++i)
    nfalse += rgs[i].get()->HasArcs() ? 1 : 0;
  int n_cols = g_->arcs().size() + nfalse;
  ctx_.m.setDimensions(0, n_cols);

  bool request;
  std::vector<ExchangeNodeGroup::Ptr>& sgs = g_->supply_groups();
  for (int i = 0; i != sgs.size(); i++) {
    request = false;
    XlateGrp_(sgs[i].get(), request);
  }

  for (int i = 0; i != rgs.size(); i++) {
    request = true;
    XlateGrp_(rgs[i].get(), request);
  }

  // add each false arc
  CLOG(LEV_DEBUG1) << "Adding " << arc_offset_ - g_->arcs().size()
                   << " false arcs.";
  double inf = iface_->getInfinity();
  for (int i = g_->arcs().size(); i != arc_offset_; i++) {
    ctx_.obj_coeffs[i] = pseudo_cost_;
    ctx_.col_lbs[i] = 0;
    ctx_.col_ubs[i] = inf;
  }
}

void ProgTranslator::Populate() {
  iface_->setObjSense(1.0);  // minimize

  // load er up!
  iface_->loadProblem(ctx_.m, &ctx_.col_lbs[0], &ctx_.col_ubs[0],
                      &ctx_.obj_coeffs[0], &ctx_.row_lbs[0], &ctx_.row_ubs[0]);

  if (excl_) {
    std::vector<Arc>& arcs = g_->arcs();
    for (int i = 0; i != arcs.size(); i++) {
      Arc& a = arcs[i];
      if (a.exclusive()) {
        iface_->setInteger(g_->arc_ids()[a]);
      }
    }
  }

}

void ProgTranslator::ToProg() {
  Translate();
  Populate();
}

void ProgTranslator::XlateGrp_(ExchangeNodeGroup* grp, bool request) {
  double inf = iface_->getInfinity();
  std::vector<double>& caps = grp->capacities();

  if (request && !grp->HasArcs())
    return; // no arcs, no reason to add variables/constraints

  std::vector<CoinPackedVector> cap_rows;
  std::vector<CoinPackedVector> excl_rows;
  for (int i = 0; i != caps.size(); i++) {
    cap_rows.push_back(CoinPackedVector());
  }

  std::vector<ExchangeNode::Ptr>& nodes = grp->nodes();
  for (int i = 0; i != nodes.size(); i++) {
    std::map<Arc, std::vector<double> >& ucap_map = nodes[i]->unit_capacities;
    std::map<Arc, std::vector<double> >::iterator cap_it;

    // add each arc
    for (cap_it = ucap_map.begin(); cap_it != ucap_map.end(); ++cap_it) {
      const Arc& a = cap_it->first;
      std::vector<double>& ucaps = cap_it->second;
      int arc_id = g_->arc_ids()[a];

      // add each unit capacity coefficient
      for (int j = 0; j != ucaps.size(); j++) {
        double coeff = ucaps[j];
        if (excl_ && a.exclusive()) {
          coeff *= a.excl_val();
        }

        cap_rows[j].insert(arc_id, coeff);
      }

      if (request) {
        CheckPref(a.pref());
        ctx_.obj_coeffs[arc_id] = ExchangeSolver::Cost(a, excl_);
        ctx_.col_lbs[arc_id] = 0;
        ctx_.col_ubs[arc_id] = (excl_ && a.exclusive()) ? 1 :
                               std::min(nodes[i]->qty, inf);
      }
    }
  }

  int faux_id;
  if (request) {
    faux_id = arc_offset_++;
  }

  // add all capacity rows
  for (int i = 0; i != cap_rows.size(); i++) {
    if (request) {
      cap_rows[i].insert(faux_id, 1.0);  // faux arc
    }

    // 1e15 is the largest value that doesn't make the solver fall over
    // (by emperical testing)
    double rlb = std::min(caps[i], 1e15);
    ctx_.row_lbs.push_back(request ? rlb : 0);
    ctx_.row_ubs.push_back(request ? inf : caps[i]);
    ctx_.m.appendRow(cap_rows[i]);
  }

  if (excl_) {
    // add exclusive arcs
    std::vector< std::vector<ExchangeNode::Ptr> >& exngs =
        grp->excl_node_groups();
    for (int i = 0; i != exngs.size(); i++) {
      CoinPackedVector excl_row;
      std::vector<ExchangeNode::Ptr>& nodes = exngs[i];
      for (int j = 0; j != nodes.size(); j++) {
        std::vector<Arc>& arcs = g_->node_arc_map()[nodes[j]];
        for (int k = 0; k != arcs.size(); k++) {
          excl_row.insert(g_->arc_ids()[arcs[k]], 1.0);
        }
      }
      if (excl_row.getNumElements() > 0) {
        excl_rows.push_back(excl_row);
      }
    }

    // add all exclusive rows
    for (int i = 0; i != excl_rows.size(); i++) {
      ctx_.row_lbs.push_back(0.0);
      ctx_.row_ubs.push_back(1.0);
      ctx_.m.appendRow(excl_rows[i]);
    }
  }
}

void ProgTranslator::FromProg() {
  const double* sol = iface_->getColSolution();
  std::vector<Arc>& arcs = g_->arcs();
  double flow;
  for (int i = 0; i < arcs.size(); i++) {
    Arc& a = g_->arc_by_id().at(i);
    flow = sol[i];
    flow = (excl_ && a.exclusive()) ? flow * a.excl_val() : flow;
    if (flow > cyclus::eps()) {
      g_->AddMatch(a, flow);
    }
  }
}

ProgTranslator::Context::Context() {
  throw DepricatedApiError("Class ProgTranslator::Context is not deprecated in favor of ProgTranslatorContext.");
}

ProgTranslator::Context::~Context() {
  throw DepricatedApiError("Class ProgTranslator::Context is not deprecated in favor of ProgTranslatorContext.");
}

}  // namespace cyclus
<commit_msg>Fix typo that reverses meaning of error message.<commit_after>#include "prog_translator.h"

#include <algorithm>

#include "CoinPackedVector.hpp"
#include "OsiSolverInterface.hpp"

#include "cyc_limits.h"
#include "error.h"
#include "exchange_graph.h"
#include "exchange_solver.h"
#include "logger.h"

namespace cyclus {

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface)
    : g_(g),
      iface_(iface),
      excl_(false),
      pseudo_cost_(std::numeric_limits<double>::max()) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               bool exclusive)
    : g_(g),
      iface_(iface),
      excl_(exclusive),
      pseudo_cost_(std::numeric_limits<double>::max()) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               double pseudo_cost)
    : g_(g),
      iface_(iface),
      excl_(false),
      pseudo_cost_(pseudo_cost) {
  Init();
}

ProgTranslator::ProgTranslator(ExchangeGraph* g, OsiSolverInterface* iface,
                               bool exclusive, double pseudo_cost)
    : g_(g),
      iface_(iface),
      excl_(exclusive),
      pseudo_cost_(pseudo_cost) {
  Init();
}

void ProgTranslator::Init() {
  arc_offset_ = g_->arcs().size();
  int n_cols = arc_offset_ + g_->request_groups().size();
  ctx_.obj_coeffs.resize(n_cols);
  ctx_.col_ubs.resize(n_cols);
  ctx_.col_lbs.resize(n_cols);
  ctx_.m = CoinPackedMatrix(false, 0, 0);
}

void ProgTranslator::CheckPref(double pref) {
  if (pref <= 0) {
    std::stringstream ss;
    ss << "Preference value found to be nonpositive (" << pref
       << "). Preferences must be positive when using an optimization solver."
       << " If using Cyclus in simulation mode (e.g., from the command line),"
       << " this error is likely a bug in Cyclus. Please report it to the developer's "
       << "list (https://groups.google.com/forum/#!forum/cyclus-dev).";
    throw ValueError(ss.str());
  }
}

void ProgTranslator::Translate() {
  // number of variables = number of arcs + 1 faux arc per request group with arcs
  int nfalse = 0;
  std::vector<RequestGroup::Ptr>& rgs = g_->request_groups();
  for (int i = 0; i != g_->request_groups().size(); ++i)
    nfalse += rgs[i].get()->HasArcs() ? 1 : 0;
  int n_cols = g_->arcs().size() + nfalse;
  ctx_.m.setDimensions(0, n_cols);

  bool request;
  std::vector<ExchangeNodeGroup::Ptr>& sgs = g_->supply_groups();
  for (int i = 0; i != sgs.size(); i++) {
    request = false;
    XlateGrp_(sgs[i].get(), request);
  }

  for (int i = 0; i != rgs.size(); i++) {
    request = true;
    XlateGrp_(rgs[i].get(), request);
  }

  // add each false arc
  CLOG(LEV_DEBUG1) << "Adding " << arc_offset_ - g_->arcs().size()
                   << " false arcs.";
  double inf = iface_->getInfinity();
  for (int i = g_->arcs().size(); i != arc_offset_; i++) {
    ctx_.obj_coeffs[i] = pseudo_cost_;
    ctx_.col_lbs[i] = 0;
    ctx_.col_ubs[i] = inf;
  }
}

void ProgTranslator::Populate() {
  iface_->setObjSense(1.0);  // minimize

  // load er up!
  iface_->loadProblem(ctx_.m, &ctx_.col_lbs[0], &ctx_.col_ubs[0],
                      &ctx_.obj_coeffs[0], &ctx_.row_lbs[0], &ctx_.row_ubs[0]);

  if (excl_) {
    std::vector<Arc>& arcs = g_->arcs();
    for (int i = 0; i != arcs.size(); i++) {
      Arc& a = arcs[i];
      if (a.exclusive()) {
        iface_->setInteger(g_->arc_ids()[a]);
      }
    }
  }

}

void ProgTranslator::ToProg() {
  Translate();
  Populate();
}

void ProgTranslator::XlateGrp_(ExchangeNodeGroup* grp, bool request) {
  double inf = iface_->getInfinity();
  std::vector<double>& caps = grp->capacities();

  if (request && !grp->HasArcs())
    return; // no arcs, no reason to add variables/constraints

  std::vector<CoinPackedVector> cap_rows;
  std::vector<CoinPackedVector> excl_rows;
  for (int i = 0; i != caps.size(); i++) {
    cap_rows.push_back(CoinPackedVector());
  }

  std::vector<ExchangeNode::Ptr>& nodes = grp->nodes();
  for (int i = 0; i != nodes.size(); i++) {
    std::map<Arc, std::vector<double> >& ucap_map = nodes[i]->unit_capacities;
    std::map<Arc, std::vector<double> >::iterator cap_it;

    // add each arc
    for (cap_it = ucap_map.begin(); cap_it != ucap_map.end(); ++cap_it) {
      const Arc& a = cap_it->first;
      std::vector<double>& ucaps = cap_it->second;
      int arc_id = g_->arc_ids()[a];

      // add each unit capacity coefficient
      for (int j = 0; j != ucaps.size(); j++) {
        double coeff = ucaps[j];
        if (excl_ && a.exclusive()) {
          coeff *= a.excl_val();
        }

        cap_rows[j].insert(arc_id, coeff);
      }

      if (request) {
        CheckPref(a.pref());
        ctx_.obj_coeffs[arc_id] = ExchangeSolver::Cost(a, excl_);
        ctx_.col_lbs[arc_id] = 0;
        ctx_.col_ubs[arc_id] = (excl_ && a.exclusive()) ? 1 :
                               std::min(nodes[i]->qty, inf);
      }
    }
  }

  int faux_id;
  if (request) {
    faux_id = arc_offset_++;
  }

  // add all capacity rows
  for (int i = 0; i != cap_rows.size(); i++) {
    if (request) {
      cap_rows[i].insert(faux_id, 1.0);  // faux arc
    }

    // 1e15 is the largest value that doesn't make the solver fall over
    // (by emperical testing)
    double rlb = std::min(caps[i], 1e15);
    ctx_.row_lbs.push_back(request ? rlb : 0);
    ctx_.row_ubs.push_back(request ? inf : caps[i]);
    ctx_.m.appendRow(cap_rows[i]);
  }

  if (excl_) {
    // add exclusive arcs
    std::vector< std::vector<ExchangeNode::Ptr> >& exngs =
        grp->excl_node_groups();
    for (int i = 0; i != exngs.size(); i++) {
      CoinPackedVector excl_row;
      std::vector<ExchangeNode::Ptr>& nodes = exngs[i];
      for (int j = 0; j != nodes.size(); j++) {
        std::vector<Arc>& arcs = g_->node_arc_map()[nodes[j]];
        for (int k = 0; k != arcs.size(); k++) {
          excl_row.insert(g_->arc_ids()[arcs[k]], 1.0);
        }
      }
      if (excl_row.getNumElements() > 0) {
        excl_rows.push_back(excl_row);
      }
    }

    // add all exclusive rows
    for (int i = 0; i != excl_rows.size(); i++) {
      ctx_.row_lbs.push_back(0.0);
      ctx_.row_ubs.push_back(1.0);
      ctx_.m.appendRow(excl_rows[i]);
    }
  }
}

void ProgTranslator::FromProg() {
  const double* sol = iface_->getColSolution();
  std::vector<Arc>& arcs = g_->arcs();
  double flow;
  for (int i = 0; i < arcs.size(); i++) {
    Arc& a = g_->arc_by_id().at(i);
    flow = sol[i];
    flow = (excl_ && a.exclusive()) ? flow * a.excl_val() : flow;
    if (flow > cyclus::eps()) {
      g_->AddMatch(a, flow);
    }
  }
}

ProgTranslator::Context::Context() {
  throw DepricatedApiError("Class ProgTranslator::Context is now deprecated in favor of ProgTranslatorContext.");
}

ProgTranslator::Context::~Context() {
  throw DepricatedApiError("Class ProgTranslator::Context is now deprecated in favor of ProgTranslatorContext.");
}

}  // namespace cyclus
<|endoftext|>


<commit_before>/*
    addaccountwizard.cpp - Kopete Add Account Wizard

    Copyright (c) 2003      by Olivier Goffart       <ogoffart@tiscalinet.be>
    Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@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.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "addaccountwizard.h"

#include <qcheckbox.h>

#include <kcolorbutton.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klistview.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kplugininfo.h>

#include "addaccountwizardpage1.h"
#include "addaccountwizardpage2.h"
#include "addaccountwizardpage3.h"
#include "editaccountwidget.h"
#include "kopeteaccount.h"
#include "kopeteaccountmanager.h"
#include "kopeteprotocol.h"
#include "kopetepluginmanager.h"

AddAccountWizard::AddAccountWizard( QWidget *parent, const char *name, bool modal )
: KWizard( parent, name, modal, WDestructiveClose )
{

	//kdDebug( 14100 ) << k_funcinfo << endl;
	m_accountPage = 0L;
	m_proto = 0L;

	m_intro =         new AddAccountWizardPage1( this );
	m_selectService = new AddAccountWizardPage2( this );
	m_finish =        new AddAccountWizardPage3( this );

	addPage( m_intro,         m_intro->caption() );
	addPage( m_selectService, m_selectService->caption() );
	addPage( m_finish,        m_finish->caption() );

	QListViewItem *pluginItem = 0L;

	QValueList<KPluginInfo *> protocols = KopetePluginManager::self()->availablePlugins( "Protocols" );

	for ( QValueList<KPluginInfo *>::Iterator it = protocols.begin(); it != protocols.end(); ++it )
	{
		pluginItem = new QListViewItem( m_selectService->protocolListView );
		pluginItem->setText( 0, ( *it )->name() );
		pluginItem->setText( 1, ( *it )->comment() );
		pluginItem->setPixmap( 0, SmallIcon( ( *it )->icon() ) );
		m_protocolItems.insert( pluginItem, ( *it ) );
	}

	if ( protocols.count() == 1 )
	{
		pluginItem->setSelected( true );
		// I think it is important to select one protocol to make sure.
		//setAppropriate( m_selectService, false );
	}

	setNextEnabled( m_selectService, ( protocols.count() == 1 ) );
	setFinishEnabled( m_finish, true );

	connect( m_selectService->protocolListView, SIGNAL( clicked( QListViewItem * ) ),
		this, SLOT( slotProtocolListClicked( QListViewItem * ) ) );
	connect( m_selectService->protocolListView, SIGNAL( doubleClicked( QListViewItem * ) ),
		this, SLOT( slotProtocolListDoubleClicked( QListViewItem * ) ) );
	connect( m_selectService->protocolListView, SIGNAL( selectionChanged( QListViewItem * ) ),
		this, SLOT( slotProtocolListClicked( QListViewItem * ) ) );
}

AddAccountWizard::~AddAccountWizard()
{
	//kdDebug( 14100 ) << k_funcinfo << endl;
}

void AddAccountWizard::slotProtocolListClicked( QListViewItem * )
{
	//kdDebug( 14100 ) << k_funcinfo << endl;

	// Make sure only one protocol is selected before allowing the user to continue
	setNextEnabled( m_selectService, ( m_selectService->protocolListView->selectedItem() != 0 ) );
}

void AddAccountWizard::slotProtocolListDoubleClicked( QListViewItem *lvi)
{
	// Make sure the user clicked on an item
	if ( lvi )
		next();
}

void AddAccountWizard::accept()
{
	//kdDebug( 14100 ) << k_funcinfo << endl;
	KopeteAccount *account = m_accountPage->apply();
	if ( account && m_finish->mUseColor->isChecked() )
		account->setColor( m_finish->mColorButton->color() );

	if(m_proto)
	{
		//Make sur the protocol is correctly enabled.  This is not realy needed, but still good
		QString protocol_name=m_proto->pluginId().remove( "Protocol" ).lower();
		KopetePluginManager::self()->setPluginEnabled( protocol_name , true );
	}

	KWizard::accept();

}

void AddAccountWizard::reject()
{
	if(m_proto && KopeteAccountManager::manager()->accounts(m_proto).isEmpty())
	{
		//FIXME: we should use a decent way to do that
		QString protocol_name=m_proto->pluginId().remove( "Protocol" ).lower();

//		KopetePluginManager::self()->setPluginEnabled( protocol_name , false );
		KopetePluginManager::self()->unloadPlugin( protocol_name );

	}

	KWizard::reject();

}

void AddAccountWizard::back()
{
	if ( currentPage() == dynamic_cast<QWidget *>( m_accountPage ) )
	{
		kdDebug( 14100 ) << k_funcinfo << "Deleting m_accountPage" << endl;

		// Deletes the accountPage, KWizard does not like deleting pages
		// using different pointers, it only seems to watch its own pointer
		delete currentPage();
		//removePage( dynamic_cast<QWidget *>( m_accountPage ) );
		//delete m_accountPage;
		m_accountPage = 0L;
		m_proto = 0L;

		// removePage() already goes back to previous page, no back() needed
	}
	else
	{
		KWizard::back();
	}
}

void AddAccountWizard::next()
{
	if ( currentPage() == m_selectService ||
		( currentPage() == m_intro && !appropriate( m_selectService ) ) )
	{
		if ( m_accountPage )
		{
			kdDebug( 14100 ) << k_funcinfo << "AccountPage still valid, part1!" << endl;
/*
			// FIXME: Why is this commented out? Is this buggy or obsolete? - Martijn
			kdDebug( 14100 ) << k_funcinfo << "Deleting accountPage, first part" << endl;
			removePage( dynamic_cast<QWidget *>( m_accountPage ) );
			delete m_accountPage;
			m_accountPage = 0L;
*/
		}

		QListViewItem *lvi = m_selectService->protocolListView->selectedItem();
		if ( lvi )
		{
			m_proto = dynamic_cast<KopeteProtocol *>( KopetePluginManager::self()->loadPlugin( m_protocolItems[ lvi ]->pluginName() ) );
			if ( m_proto )
			{
				if ( m_accountPage )
				{
					kdDebug( 14100 ) << k_funcinfo << "AccountPage still valid, part2!" << endl;
/*
					// FIXME: Why is this commented out? Is this buggy or obsolete? - Martijn
					kdDebug( 14100 ) << k_funcinfo << "Deleting accountPage after finding selected Protocol" << endl;
					removePage( dynamic_cast<QWidget *>( m_accountPage ) );
					delete m_accountPage;
					m_accountPage = 0L;
*/
				}

				m_accountPage = m_proto->createEditAccountWidget( 0L, this );
				if ( !m_accountPage )
				{
					KMessageBox::queuedMessageBox( this, KMessageBox::Error,
						i18n( "This protocol does not currently support adding accounts." ),
						i18n( "Error While Adding Account" ) );
				}
				else
				{
					kdDebug( 14100 ) << k_funcinfo << "Adding Step Two page and switching to that one" << endl;
					insertPage( dynamic_cast<QWidget *>( m_accountPage ),
						i18n( "Step Two: Account Information" ), indexOf( m_finish ) );
					KWizard::next();
				}
			}
			else
			{
				KMessageBox::queuedMessageBox( this, KMessageBox::Error,
					i18n( "Impossible to load the protocol '%1'." ).arg( m_protocolItems[ lvi ]->name() ), i18n( "Error While Adding Account" ) );
			}
		}
		return;
	}
	else if ( indexOf( currentPage() ) == 2 )
	{
		if ( !m_accountPage->validateData() )
			return;

		QColor col = KopeteAccountManager::manager()->guessColor( m_proto );

		m_finish->mColorButton->setColor( col );
		m_finish->mUseColor->setChecked( col.isValid() );
		KWizard::next();
	}
	else
	{
		KWizard::next();
	}
}

#include "addaccountwizard.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>Clarification.<commit_after>/*
    addaccountwizard.cpp - Kopete Add Account Wizard

    Copyright (c) 2003      by Olivier Goffart       <ogoffart@tiscalinet.be>
    Copyright (c) 2003      by Martijn Klingens      <klingens@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers <kopete-devel@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.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "addaccountwizard.h"

#include <qcheckbox.h>

#include <kcolorbutton.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klistview.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kplugininfo.h>

#include "addaccountwizardpage1.h"
#include "addaccountwizardpage2.h"
#include "addaccountwizardpage3.h"
#include "editaccountwidget.h"
#include "kopeteaccount.h"
#include "kopeteaccountmanager.h"
#include "kopeteprotocol.h"
#include "kopetepluginmanager.h"

AddAccountWizard::AddAccountWizard( QWidget *parent, const char *name, bool modal )
: KWizard( parent, name, modal, WDestructiveClose )
{

	//kdDebug( 14100 ) << k_funcinfo << endl;
	m_accountPage = 0L;
	m_proto = 0L;

	m_intro =         new AddAccountWizardPage1( this );
	m_selectService = new AddAccountWizardPage2( this );
	m_finish =        new AddAccountWizardPage3( this );

	addPage( m_intro,         m_intro->caption() );
	addPage( m_selectService, m_selectService->caption() );
	addPage( m_finish,        m_finish->caption() );

	QListViewItem *pluginItem = 0L;

	QValueList<KPluginInfo *> protocols = KopetePluginManager::self()->availablePlugins( "Protocols" );

	for ( QValueList<KPluginInfo *>::Iterator it = protocols.begin(); it != protocols.end(); ++it )
	{
		pluginItem = new QListViewItem( m_selectService->protocolListView );
		pluginItem->setText( 0, ( *it )->name() );
		pluginItem->setText( 1, ( *it )->comment() );
		pluginItem->setPixmap( 0, SmallIcon( ( *it )->icon() ) );
		m_protocolItems.insert( pluginItem, ( *it ) );
	}

	if ( protocols.count() == 1 )
	{
		pluginItem->setSelected( true );
		// I think it is important to select one protocol to make sure.
		//setAppropriate( m_selectService, false );
	}

	setNextEnabled( m_selectService, ( protocols.count() == 1 ) );
	setFinishEnabled( m_finish, true );

	connect( m_selectService->protocolListView, SIGNAL( clicked( QListViewItem * ) ),
		this, SLOT( slotProtocolListClicked( QListViewItem * ) ) );
	connect( m_selectService->protocolListView, SIGNAL( doubleClicked( QListViewItem * ) ),
		this, SLOT( slotProtocolListDoubleClicked( QListViewItem * ) ) );
	connect( m_selectService->protocolListView, SIGNAL( selectionChanged( QListViewItem * ) ),
		this, SLOT( slotProtocolListClicked( QListViewItem * ) ) );
}

AddAccountWizard::~AddAccountWizard()
{
	//kdDebug( 14100 ) << k_funcinfo << endl;
}

void AddAccountWizard::slotProtocolListClicked( QListViewItem * )
{
	//kdDebug( 14100 ) << k_funcinfo << endl;

	// Make sure only one protocol is selected before allowing the user to continue
	setNextEnabled( m_selectService, ( m_selectService->protocolListView->selectedItem() != 0 ) );
}

void AddAccountWizard::slotProtocolListDoubleClicked( QListViewItem *lvi)
{
	// Make sure the user clicked on an item
	if ( lvi )
		next();
}

void AddAccountWizard::accept()
{
	//kdDebug( 14100 ) << k_funcinfo << endl;
	KopeteAccount *account = m_accountPage->apply();
	if ( account && m_finish->mUseColor->isChecked() )
		account->setColor( m_finish->mColorButton->color() );

	if(m_proto)
	{
		//Make sur the protocol is correctly enabled.  This is not realy needed, but still good
		QString protocol_name=m_proto->pluginId().remove( "Protocol" ).lower();
		KopetePluginManager::self()->setPluginEnabled( protocol_name , true );
	}

	KWizard::accept();

}

void AddAccountWizard::reject()
{
	if(m_proto && KopeteAccountManager::manager()->accounts(m_proto).isEmpty())
	{
		//FIXME: we should use a decent way to do that
		QString protocol_name=m_proto->pluginId().remove( "Protocol" ).lower();

//		KopetePluginManager::self()->setPluginEnabled( protocol_name , false );
		KopetePluginManager::self()->unloadPlugin( protocol_name );

	}

	KWizard::reject();

}

void AddAccountWizard::back()
{
	if ( currentPage() == dynamic_cast<QWidget *>( m_accountPage ) )
	{
		kdDebug( 14100 ) << k_funcinfo << "Deleting m_accountPage" << endl;

		// Deletes the accountPage, KWizard does not like deleting pages
		// using different pointers, it only seems to watch its own pointer
		delete currentPage();
		//removePage( dynamic_cast<QWidget *>( m_accountPage ) );
		//delete m_accountPage;
		m_accountPage = 0L;
		m_proto = 0L;

		// removePage() already goes back to previous page, no back() needed
	}
	else
	{
		KWizard::back();
	}
}

void AddAccountWizard::next()
{
	if ( currentPage() == m_selectService ||
		( currentPage() == m_intro && !appropriate( m_selectService ) ) )
	{
		if ( m_accountPage )
		{
			kdDebug( 14100 ) << k_funcinfo << "AccountPage still valid, part1!" << endl;
/*
			// FIXME: Why is this commented out? Is this buggy or obsolete? - Martijn
			kdDebug( 14100 ) << k_funcinfo << "Deleting accountPage, first part" << endl;
			removePage( dynamic_cast<QWidget *>( m_accountPage ) );
			delete m_accountPage;
			m_accountPage = 0L;
*/
		}

		QListViewItem *lvi = m_selectService->protocolListView->selectedItem();
		if ( lvi )
		{
			m_proto = dynamic_cast<KopeteProtocol *>( KopetePluginManager::self()->loadPlugin( m_protocolItems[ lvi ]->pluginName() ) );
			if ( m_proto )
			{
				if ( m_accountPage )
				{
					kdDebug( 14100 ) << k_funcinfo << "AccountPage still valid, part2!" << endl;
/*
					// FIXME: Why is this commented out? Is this buggy or obsolete? - Martijn
					kdDebug( 14100 ) << k_funcinfo << "Deleting accountPage after finding selected Protocol" << endl;
					removePage( dynamic_cast<QWidget *>( m_accountPage ) );
					delete m_accountPage;
					m_accountPage = 0L;
*/
				}

				m_accountPage = m_proto->createEditAccountWidget( 0L, this );
				if ( !m_accountPage )
				{
					KMessageBox::queuedMessageBox( this, KMessageBox::Error,
						i18n( "This protocol does not currently support adding accounts." ),
						i18n( "Error While Adding Account" ) );
				}
				else
				{
					kdDebug( 14100 ) << k_funcinfo << "Adding Step Two page and switching to that one" << endl;
					insertPage( dynamic_cast<QWidget *>( m_accountPage ),
						i18n( "Step Two: Account Information" ), indexOf( m_finish ) );
					KWizard::next();
				}
			}
			else
			{
				KMessageBox::queuedMessageBox( this, KMessageBox::Error,
					i18n( "Cannot load the %1 protocol plugin!" ).arg( m_protocolItems[ lvi ]->name() ), i18n( "Error While Adding Account" ) );
			}
		}
		return;
	}
	else if ( indexOf( currentPage() ) == 2 )
	{
		if ( !m_accountPage->validateData() )
			return;

		QColor col = KopeteAccountManager::manager()->guessColor( m_proto );

		m_finish->mColorButton->setColor( col );
		m_finish->mUseColor->setChecked( col.isValid() );
		KWizard::next();
	}
	else
	{
		KWizard::next();
	}
}

#include "addaccountwizard.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>