<commit_before>#include <QuickTime/QuickTime.h>
#include "OgreLogManager.h"
#include "OgreConfigDialog.h"

namespace Ogre {

	ConfigDialog* dlg = NULL;
	static EventHandlerUPP WindowEventHandlerUPP;

	ConfigDialog::ConfigDialog() : iSelectedRenderSystem( NULL ), iVideoModeRef( NULL ), iLogoViewRef( NULL ), iWindowRef( NULL ), iNibRef( NULL ), iMenuRef( NULL )
	{
		dlg = this;
	}

	ConfigDialog::~ConfigDialog()
	{
	}

	void ConfigDialog::initialise()
	{
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();
		ConfigOptionMap config = renderer->getConfigOptions();

		ConfigOptionMap::iterator cfi;

		cfi = config.find( "Full Screen" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "Yes" )
			{
				SetControlValue( iFullScreenRef, 1 );
			}
			else
			{
				SetControlValue( iFullScreenRef, 2 );
			}
		}

		cfi = config.find( "FSAA" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "0" )
			{
				SetControlValue( iFSAARef, 1 );
			}
			else if( cfi->second.currentValue == "2" )
			{
				SetControlValue( iFSAARef, 2 );
			}
			else if( cfi->second.currentValue == "4" )
			{
				SetControlValue( iFSAARef, 3 );
			}
			else if( cfi->second.currentValue == "6" )
			{
				SetControlValue( iFSAARef, 4 );
			}
		}

		cfi = config.find( "Colour Depth" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "32" )
			{
				SetControlValue( iColorDepthRef, 1 );
			}
			else
			{
				SetControlValue( iColorDepthRef, 2 );
			}
		}

		cfi = config.find( "RTT Preferred Mode" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "FBO" )
			{
				SetControlValue( iRTTPrefModeRef, 1 );
			}
			else if( cfi->second.currentValue == "PBuffer" )
			{
				SetControlValue( iRTTPrefModeRef, 2 );
			}
			else if( cfi->second.currentValue == "Copy" )
			{
				SetControlValue( iRTTPrefModeRef, 3 );
			}
		}
	}

	void ConfigDialog::run()
	{
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();

		SInt16 value = 0;

		// temp
		value = GetControlValue( iVideoModeRef );
		renderer->setConfigOption( "Video Mode", "800 x 600" );

		// full screen
		value = GetControlValue( iFullScreenRef );
		if( value == 1 ) // Yes
		{
			LogManager::getSingleton().logMessage( "CONFIG => FullScreen [ Yes ]" );
			renderer->setConfigOption( "Full Screen", "Yes" );
		}
		else
		{
			LogManager::getSingleton().logMessage( "CONFIG => FullScreen [ No ]" );
			renderer->setConfigOption( "Full Screen", "No" );
		}

		// fsaa
		value = GetControlValue( iFSAARef );
		switch( value )
		{
			case 1:
				renderer->setConfigOption( "FSAA", "0" );
				break;
			case 2:
				renderer->setConfigOption( "FSAA", "2" );
				break;
			case 3:
				renderer->setConfigOption( "FSAA", "4" );
				break;
			case 4:
				LogManager::getSingleton().logMessage( "CONFIG => FSAA [ 6 ]" );
				renderer->setConfigOption( "FSAA", "6" );
				break;
			default:
				renderer->setConfigOption( "FSAA", "0" );
				break;
		}

		// fsaa
		value = GetControlValue( iColorDepthRef );
		if( value == 1 )
		{
			renderer->setConfigOption( "Colour Depth", "32" );
		}
		else
		{
			renderer->setConfigOption( "Colour Depth", "16" );
		}

		// rtt pref mode
		value = GetControlValue( iRTTPrefModeRef );
		switch( value )
		{
			case 1:
				renderer->setConfigOption( "RTT Preferred Mode", "FBO" );
				break;
			case 2:
				renderer->setConfigOption( "RTT Preferred Mode", "PBuffer" );
				break;
			case 3:
				renderer->setConfigOption( "RTT Preferred Mode", "Copy" );
				break;
		}

		Root::getSingleton().setRenderSystem( renderer );

		iDisplayStatus = true;

		QuitAppModalLoopForWindow( iWindowRef );
	}

	void ConfigDialog::cancel()
	{
		iDisplayStatus = false;
		QuitAppModalLoopForWindow( iWindowRef );
	}

	pascal OSStatus ConfigDialog::windowEventHandler( EventHandlerCallRef aNextHandler, EventRef aEvent, void* aUserData )
	{
		#pragma unused ( inCallRef )
		OSStatus status	= eventNotHandledErr;
		UInt32 eventKind = GetEventKind( aEvent );
		UInt32 eventClass = GetEventClass( aEvent );
		WindowRef window = ( WindowRef ) aUserData;
		HICommand command;
		if( eventClass == kEventClassWindow && eventKind == kEventWindowClose )
		{
			QuitAppModalLoopForWindow( window );
		}
		else if( eventClass == kEventClassCommand && eventKind == kEventCommandProcess )
		{
			GetEventParameter( aEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( HICommand ), NULL, &command );
			switch( command.commandID )
			{
				case 'run!':
					{
					dlg->run();
					break;
					}
				case 'not!':
					{
					dlg->cancel();
					break;
					}
				default:
					break;
			}
		}
		return ( status );
	}

	bool ConfigDialog::display()
	{
		// TODO: Fix OS X Config dialog
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();

		// WARNING: restoreConfig() should not be invoked here as Root calls
		// it before this method anyway, and invoking restoreConfig() here
		// forces the client application to use Ogre.cfg, while it may have
		// different plans.
		if(!Root::getSingleton().restoreConfig())
		{
			// Set some defaults
			renderer->setConfigOption("Video Mode", "800 x 600");
			renderer->setConfigOption("Colour Depth", "32");
			renderer->setConfigOption("FSAA", "0");
			renderer->setConfigOption("Full Screen", "No");
			renderer->setConfigOption("RTT Preferred Mode", "PBuffer");
			// Set the rendersystem and save the config.
			Root::getSingleton().setRenderSystem(renderer);
		}
		return true;
	/*
		iDisplayStatus = false;
		OSStatus status;
		CFStringRef logoRef = NULL;
		CFURLRef logoUrlRef = NULL;
		OSType dataRefType;
		GraphicsImportComponent	ci = NULL;
		CGImageRef cgImageRef = NULL;
		Handle dataRef = NULL;

		HIViewID logoViewID = { 'CONF', 100 };
		HIViewID videoModeViewID = { 'CONF', 104 };
		HIViewID colorDepthViewID = { 'CONF', 105 };
		HIViewID fsaaViewID = { 'CONF', 106 };
		HIViewID rttPrefModeViewID = { 'CONF', 107 };
		HIViewID fullScreenViewID = { 'CONF', 108 };

		const EventTypeSpec windowEvents[] =
		{
			{ kEventClassCommand, kEventCommandProcess },
			{ kEventClassWindow, kEventWindowClose }
		};

		// We need to get the Ogre Bundle
		CFBundleRef baseBundle = CFBundleGetBundleWithIdentifier(CFSTR("org.ogre3d.Ogre"));
		status	= CreateNibReferenceWithCFBundle(baseBundle, CFSTR("main"), &iNibRef );
		require_noerr( status, CantGetNibRef );

		status	= CreateWindowFromNib( iNibRef, CFSTR( "ConfigWindow" ), &iWindowRef );
		require_noerr( status, CantCreateWindow );

		if( WindowEventHandlerUPP == NULL )
			WindowEventHandlerUPP = NewEventHandlerUPP( windowEventHandler );

		status = InstallWindowEventHandler( iWindowRef, WindowEventHandlerUPP, GetEventTypeCount( windowEvents ), windowEvents, iWindowRef, NULL );
		//status = InstallStandardEventHandler(GetWindowEventTarget(iWindowRef));
		require_noerr( status, CantInstallWindowEventHandler );

		//logoRef = CFStringCreateWithCString( kCFAllocatorDefault, "file:///Users/aljen/Code/OSXConfig/logo.bmp", NULL );
		//logoUrlRef = CFURLCreateWithString( kCFAllocatorDefault, logoRef, NULL );

		//status = QTNewDataReferenceFromCFURL( logoUrlRef, 0, &dataRef, &dataRefType );
		//status	= GetGraphicsImporterForDataRef( dataRef, dataRefType, &ci );
		//require( ci != NULL, ImporterError );
		//status	= GraphicsImportCreateCGImage( ci, &cgImageRef, kGraphicsImportCreateCGImageUsingCurrentSettings );

		// logo view
		status	= HIViewFindByID( HIViewGetRoot( iWindowRef ), logoViewID, &iLogoViewRef );
		require_noerr( status, LogoViewNotFound );
		status	= HIImageViewSetImage( iLogoViewRef, cgImageRef );
		require_noerr( status, SetImageFailed );
		status	= HIImageViewSetScaleToFit( iLogoViewRef, false );
		require_noerr( status, ScaleFailed );
		status	= HIViewSetVisible( iLogoViewRef, true );
		require_noerr( status, SetVisibleFailed );

		// video mode view
		status	= HIViewFindByID( HIViewGetRoot( iWindowRef ), videoModeViewID, &iVideoModeRef );

		CreateNewMenu( iMenuID, 0, &iMenuRef );

		if( iMenuRef != NULL )
		{
			CFStringRef itemNames[] =
			{
				CFSTR( "640 x 480" ),
				CFSTR( "800 x 600" ),
				CFSTR( "1024 x 768" )
			};

			MenuItemIndex numItems = ( sizeof( itemNames ) / sizeof( CFStringRef ) );
			for( int i = 0; i < numItems; i++ )
			{
				MenuItemIndex newItem;
				AppendMenuItemTextWithCFString( iMenuRef, itemNames[ i ], 0, 0, &newItem );
			}

			SetControlData( iVideoModeRef, kControlEntireControl, kControlPopupButtonMenuRefTag, sizeof( MenuRef ), &iMenuRef );
		}

		// color depth view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), colorDepthViewID, &iColorDepthRef );

		// fsaa view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), fsaaViewID, &iFSAARef );

		// rtt pref mode view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), rttPrefModeViewID, &iRTTPrefModeRef );

		// full screen view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), fullScreenViewID, &iFullScreenRef );

		DisposeNibReference( iNibRef );

		initialise();

		RepositionWindow( iWindowRef, NULL, kWindowCenterOnMainScreen );
		TransitionWindow( iWindowRef, kWindowFadeTransitionEffect, kWindowShowTransitionAction, NULL );
		SelectWindow( iWindowRef );
		ActivateWindow( iWindowRef, true );
		RunAppModalLoopForWindow( iWindowRef );

		TransitionWindow( iWindowRef, kWindowFadeTransitionEffect, kWindowHideTransitionAction, NULL );
		DisposeWindow( iWindowRef );

		return iDisplayStatus;

	CantGetNibRef:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantGetNibRef" );
	CantCreateWindow:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantCreateWindow" );
	CantInstallWindowEventHandler:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantInstallWindowEventHandler" );
	ImporterError:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:ImporterError" );
	LogoViewNotFound:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:LogoViewNotFound" );
	SetImageFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetImageFailed" );
	ScaleFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetScaleFailed" );
	SetVisibleFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetVisibleFailed" );
		return( iDisplayStatus );

		return true;
	*/
	}

};
<commit_msg>Definitely prefer FBO over PBuffer on OSX now. People will need to delete their ogre.cfg files though.<commit_after>#include <QuickTime/QuickTime.h>
#include "OgreLogManager.h"
#include "OgreConfigDialog.h"

namespace Ogre {

	ConfigDialog* dlg = NULL;
	static EventHandlerUPP WindowEventHandlerUPP;

	ConfigDialog::ConfigDialog() : iSelectedRenderSystem( NULL ), iVideoModeRef( NULL ), iLogoViewRef( NULL ), iWindowRef( NULL ), iNibRef( NULL ), iMenuRef( NULL )
	{
		dlg = this;
	}

	ConfigDialog::~ConfigDialog()
	{
	}

	void ConfigDialog::initialise()
	{
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();
		ConfigOptionMap config = renderer->getConfigOptions();

		ConfigOptionMap::iterator cfi;

		cfi = config.find( "Full Screen" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "Yes" )
			{
				SetControlValue( iFullScreenRef, 1 );
			}
			else
			{
				SetControlValue( iFullScreenRef, 2 );
			}
		}

		cfi = config.find( "FSAA" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "0" )
			{
				SetControlValue( iFSAARef, 1 );
			}
			else if( cfi->second.currentValue == "2" )
			{
				SetControlValue( iFSAARef, 2 );
			}
			else if( cfi->second.currentValue == "4" )
			{
				SetControlValue( iFSAARef, 3 );
			}
			else if( cfi->second.currentValue == "6" )
			{
				SetControlValue( iFSAARef, 4 );
			}
		}

		cfi = config.find( "Colour Depth" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "32" )
			{
				SetControlValue( iColorDepthRef, 1 );
			}
			else
			{
				SetControlValue( iColorDepthRef, 2 );
			}
		}

		cfi = config.find( "RTT Preferred Mode" );
		if( cfi != config.end() )
		{
			if( cfi->second.currentValue == "FBO" )
			{
				SetControlValue( iRTTPrefModeRef, 1 );
			}
			else if( cfi->second.currentValue == "PBuffer" )
			{
				SetControlValue( iRTTPrefModeRef, 2 );
			}
			else if( cfi->second.currentValue == "Copy" )
			{
				SetControlValue( iRTTPrefModeRef, 3 );
			}
		}
	}

	void ConfigDialog::run()
	{
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();

		SInt16 value = 0;

		// temp
		value = GetControlValue( iVideoModeRef );
		renderer->setConfigOption( "Video Mode", "800 x 600" );

		// full screen
		value = GetControlValue( iFullScreenRef );
		if( value == 1 ) // Yes
		{
			LogManager::getSingleton().logMessage( "CONFIG => FullScreen [ Yes ]" );
			renderer->setConfigOption( "Full Screen", "Yes" );
		}
		else
		{
			LogManager::getSingleton().logMessage( "CONFIG => FullScreen [ No ]" );
			renderer->setConfigOption( "Full Screen", "No" );
		}

		// fsaa
		value = GetControlValue( iFSAARef );
		switch( value )
		{
			case 1:
				renderer->setConfigOption( "FSAA", "0" );
				break;
			case 2:
				renderer->setConfigOption( "FSAA", "2" );
				break;
			case 3:
				renderer->setConfigOption( "FSAA", "4" );
				break;
			case 4:
				LogManager::getSingleton().logMessage( "CONFIG => FSAA [ 6 ]" );
				renderer->setConfigOption( "FSAA", "6" );
				break;
			default:
				renderer->setConfigOption( "FSAA", "0" );
				break;
		}

		// fsaa
		value = GetControlValue( iColorDepthRef );
		if( value == 1 )
		{
			renderer->setConfigOption( "Colour Depth", "32" );
		}
		else
		{
			renderer->setConfigOption( "Colour Depth", "16" );
		}

		// rtt pref mode
		value = GetControlValue( iRTTPrefModeRef );
		switch( value )
		{
			case 1:
				renderer->setConfigOption( "RTT Preferred Mode", "FBO" );
				break;
			case 2:
				renderer->setConfigOption( "RTT Preferred Mode", "PBuffer" );
				break;
			case 3:
				renderer->setConfigOption( "RTT Preferred Mode", "Copy" );
				break;
		}

		Root::getSingleton().setRenderSystem( renderer );

		iDisplayStatus = true;

		QuitAppModalLoopForWindow( iWindowRef );
	}

	void ConfigDialog::cancel()
	{
		iDisplayStatus = false;
		QuitAppModalLoopForWindow( iWindowRef );
	}

	pascal OSStatus ConfigDialog::windowEventHandler( EventHandlerCallRef aNextHandler, EventRef aEvent, void* aUserData )
	{
		#pragma unused ( inCallRef )
		OSStatus status	= eventNotHandledErr;
		UInt32 eventKind = GetEventKind( aEvent );
		UInt32 eventClass = GetEventClass( aEvent );
		WindowRef window = ( WindowRef ) aUserData;
		HICommand command;
		if( eventClass == kEventClassWindow && eventKind == kEventWindowClose )
		{
			QuitAppModalLoopForWindow( window );
		}
		else if( eventClass == kEventClassCommand && eventKind == kEventCommandProcess )
		{
			GetEventParameter( aEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( HICommand ), NULL, &command );
			switch( command.commandID )
			{
				case 'run!':
					{
					dlg->run();
					break;
					}
				case 'not!':
					{
					dlg->cancel();
					break;
					}
				default:
					break;
			}
		}
		return ( status );
	}

	bool ConfigDialog::display()
	{
		// TODO: Fix OS X Config dialog
		RenderSystemList* renderers = Root::getSingleton().getAvailableRenderers();
		RenderSystem* renderer = renderers->front();

		// WARNING: restoreConfig() should not be invoked here as Root calls
		// it before this method anyway, and invoking restoreConfig() here
		// forces the client application to use Ogre.cfg, while it may have
		// different plans.
		if(!Root::getSingleton().restoreConfig())
		{
			// Set some defaults
			renderer->setConfigOption("Video Mode", "800 x 600");
			renderer->setConfigOption("Colour Depth", "32");
			renderer->setConfigOption("FSAA", "0");
			renderer->setConfigOption("Full Screen", "No");
			renderer->setConfigOption("RTT Preferred Mode", "FBO");
			// Set the rendersystem and save the config.
			Root::getSingleton().setRenderSystem(renderer);
		}
		return true;
	/*
		iDisplayStatus = false;
		OSStatus status;
		CFStringRef logoRef = NULL;
		CFURLRef logoUrlRef = NULL;
		OSType dataRefType;
		GraphicsImportComponent	ci = NULL;
		CGImageRef cgImageRef = NULL;
		Handle dataRef = NULL;

		HIViewID logoViewID = { 'CONF', 100 };
		HIViewID videoModeViewID = { 'CONF', 104 };
		HIViewID colorDepthViewID = { 'CONF', 105 };
		HIViewID fsaaViewID = { 'CONF', 106 };
		HIViewID rttPrefModeViewID = { 'CONF', 107 };
		HIViewID fullScreenViewID = { 'CONF', 108 };

		const EventTypeSpec windowEvents[] =
		{
			{ kEventClassCommand, kEventCommandProcess },
			{ kEventClassWindow, kEventWindowClose }
		};

		// We need to get the Ogre Bundle
		CFBundleRef baseBundle = CFBundleGetBundleWithIdentifier(CFSTR("org.ogre3d.Ogre"));
		status	= CreateNibReferenceWithCFBundle(baseBundle, CFSTR("main"), &iNibRef );
		require_noerr( status, CantGetNibRef );

		status	= CreateWindowFromNib( iNibRef, CFSTR( "ConfigWindow" ), &iWindowRef );
		require_noerr( status, CantCreateWindow );

		if( WindowEventHandlerUPP == NULL )
			WindowEventHandlerUPP = NewEventHandlerUPP( windowEventHandler );

		status = InstallWindowEventHandler( iWindowRef, WindowEventHandlerUPP, GetEventTypeCount( windowEvents ), windowEvents, iWindowRef, NULL );
		//status = InstallStandardEventHandler(GetWindowEventTarget(iWindowRef));
		require_noerr( status, CantInstallWindowEventHandler );

		//logoRef = CFStringCreateWithCString( kCFAllocatorDefault, "file:///Users/aljen/Code/OSXConfig/logo.bmp", NULL );
		//logoUrlRef = CFURLCreateWithString( kCFAllocatorDefault, logoRef, NULL );

		//status = QTNewDataReferenceFromCFURL( logoUrlRef, 0, &dataRef, &dataRefType );
		//status	= GetGraphicsImporterForDataRef( dataRef, dataRefType, &ci );
		//require( ci != NULL, ImporterError );
		//status	= GraphicsImportCreateCGImage( ci, &cgImageRef, kGraphicsImportCreateCGImageUsingCurrentSettings );

		// logo view
		status	= HIViewFindByID( HIViewGetRoot( iWindowRef ), logoViewID, &iLogoViewRef );
		require_noerr( status, LogoViewNotFound );
		status	= HIImageViewSetImage( iLogoViewRef, cgImageRef );
		require_noerr( status, SetImageFailed );
		status	= HIImageViewSetScaleToFit( iLogoViewRef, false );
		require_noerr( status, ScaleFailed );
		status	= HIViewSetVisible( iLogoViewRef, true );
		require_noerr( status, SetVisibleFailed );

		// video mode view
		status	= HIViewFindByID( HIViewGetRoot( iWindowRef ), videoModeViewID, &iVideoModeRef );

		CreateNewMenu( iMenuID, 0, &iMenuRef );

		if( iMenuRef != NULL )
		{
			CFStringRef itemNames[] =
			{
				CFSTR( "640 x 480" ),
				CFSTR( "800 x 600" ),
				CFSTR( "1024 x 768" )
			};

			MenuItemIndex numItems = ( sizeof( itemNames ) / sizeof( CFStringRef ) );
			for( int i = 0; i < numItems; i++ )
			{
				MenuItemIndex newItem;
				AppendMenuItemTextWithCFString( iMenuRef, itemNames[ i ], 0, 0, &newItem );
			}

			SetControlData( iVideoModeRef, kControlEntireControl, kControlPopupButtonMenuRefTag, sizeof( MenuRef ), &iMenuRef );
		}

		// color depth view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), colorDepthViewID, &iColorDepthRef );

		// fsaa view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), fsaaViewID, &iFSAARef );

		// rtt pref mode view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), rttPrefModeViewID, &iRTTPrefModeRef );

		// full screen view
		status = HIViewFindByID( HIViewGetRoot( iWindowRef ), fullScreenViewID, &iFullScreenRef );

		DisposeNibReference( iNibRef );

		initialise();

		RepositionWindow( iWindowRef, NULL, kWindowCenterOnMainScreen );
		TransitionWindow( iWindowRef, kWindowFadeTransitionEffect, kWindowShowTransitionAction, NULL );
		SelectWindow( iWindowRef );
		ActivateWindow( iWindowRef, true );
		RunAppModalLoopForWindow( iWindowRef );

		TransitionWindow( iWindowRef, kWindowFadeTransitionEffect, kWindowHideTransitionAction, NULL );
		DisposeWindow( iWindowRef );

		return iDisplayStatus;

	CantGetNibRef:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantGetNibRef" );
	CantCreateWindow:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantCreateWindow" );
	CantInstallWindowEventHandler:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:CantInstallWindowEventHandler" );
	ImporterError:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:ImporterError" );
	LogoViewNotFound:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:LogoViewNotFound" );
	SetImageFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetImageFailed" );
	ScaleFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetScaleFailed" );
	SetVisibleFailed:
		LogManager::getSingleton().logMessage( "ConfigDialog::display() => err:SetVisibleFailed" );
		return( iDisplayStatus );

		return true;
	*/
	}

};
<|endoftext|>


<commit_before>/*
//  gc.cpp
//
//  Author:     Sophia Lee
//  Created:    2017. 04. 26. 11:58
//  Copyright (c) 2016 Sophia Lee. All rights reserved.
//
//  General_Category
*/
#include <seshat/unicode/gc.h>

#include "ucd/gc.h"

#include <algorithm>

namespace seshat {
namespace unicode {

Gc gc(uint32_t cp)
{
    // Find the gc matching the range that code point belongs
    uint32_t code = cp;
    auto found = ucd::gc_table.find(CodeRange(code, code));
    /*
    auto gc_pair = std::find_if(ucd::gc_table.begin(), ucd::gc_table.end(),
        [code](const std::pair<CodePointRange, Gc>& p)->bool {
            return (p.first.first <= code && code <= p.first.second);
        }
    );
    */

    if (found != ucd::gc_table.end()) {
        return found->second;
    } else {
        return Gc::Cn;
    }
}

} // namespace unicode
} // namespace seshat
<commit_msg>Fix merge error.<commit_after>/*
//  gc.cpp
//
//  Author:     Sophia Lee
//  Created:    2017. 04. 26. 11:58
//  Copyright (c) 2016 Sophia Lee. All rights reserved.
//
//  General_Category
*/
#include <seshat/unicode/gc.h>

#include "ucd/gc.h"

#include <algorithm>

namespace seshat {
namespace unicode {

Gc gc(uint32_t cp)
{
    // Find the gc matching the range that code point belongs
    uint32_t code = cp;
    auto found = ucd::gc_table.find(CodePointRange(code, code));
    /*
    auto gc_pair = std::find_if(ucd::gc_table.begin(), ucd::gc_table.end(),
        [code](const std::pair<CodePointRange, Gc>& p)->bool {
            return (p.first.first <= code && code <= p.first.second);
        }
    );
    */

    if (found != ucd::gc_table.end()) {
        return found->second;
    } else {
        return Gc::Cn;
    }
}

} // namespace unicode
} // namespace seshat
<|endoftext|>


<commit_before>/*****************************************************************************\
 * Copyright 2005, 2006 Niels Lohmann, Christian Gierds, Dennis Reinert      *
 *                                                                           *
 * This file is part of BPEL2oWFN.                                           *
 *                                                                           *
 * BPEL2oWFN 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.                                                *
 *                                                                           *
 * BPEL2oWFN 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 BPEL2oWFN; if not, write to the Free Software Foundation, Inc., 51   *
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                      *
\****************************************************************************/

/*!
 * \file main.cc
 *
 * \brief The control component for BPEL2oWFN
 *
 * This file controls the behaviour of BPEL2oWFN and is the interface to the
 * environment.
 *
 * \author
 *          - responsible: Christian Gierds <gierds@informatik.hu-berlin.de>
 *          - last changes of: \$Author: gierds $
 *
 * \date
 *          - created: 2005/10/18
 *          - last changed: \$Date: 2006/06/19 13:06:33 $
 *
 * \note    This file is part of the tool BPEL2oWFN and was created during the
 *          project "Tools4BPEL" at the Humboldt-Universitt zu Berlin. See
 *          http://www.informatik.hu-berlin.de/top/forschung/projekte/tools4bpel
 *          for details.
 *
 * \version \$Revision: 1.77 $
 *          - 2005-11-15 (gierds) Moved command line evaluation to helpers.cc.
 *            Added option to created (abstracted) low level nets.
 *            Added option for LoLA output.
 *          - 2005-11-15 (nlohmann) Call Exception::info() to signal error.
 *          - 2005-11-16 (gierds) Use of error() and cleanup() as defined in
 *            helpers.cc
 *          - 2005-12-13 (gierds) Added variables in order to handle creation
 *            of oWFNs.
 *
 */

#include "main.h"
#include "options.h"
#include "ast-printers.h"

/// The Petri Net
PetriNet *TheNet = new PetriNet();

/// The CFG
CFGBlock * TheCFG = NULL;

void cfg()
{

      // create CFG
      if (modus == M_CFG) //  || modus == M_PETRINET
      {
	TheCFG = NULL;
        trace(TRACE_INFORMATION, "-> Unparsing AST to CFG ...\n");
        TheProcess->unparse(kc::pseudoPrinter, kc::cfg);
	trace(TRACE_DEBUG, "[CFG] checking for DPE\n");
	// do some business with CFG
	list<kc::integer> kcl;
	TheCFG->needsDPE(0, kcl);
	TheCFG->resetProcessedFlag();

	trace(TRACE_DEBUG, "[CFG] checking for cyclic links\n");
	/// \todo (gierds) check for cyclic links, otherwise we will fail
	TheCFG->checkForCyclicLinks();
	TheCFG->resetProcessedFlag(true);

	trace(TRACE_DEBUG, "[CFG] checking for uninitialized variables\n");
	// test
	TheCFG->checkForUninitializedVariables();
	TheCFG->resetProcessedFlag();
	/// end test

	TheCFG->lastBlock->checkForConflictingReceive();
	TheCFG->resetProcessedFlag(true, false);
      }

      if (modus == M_CFG)
      {
	if (formats[F_DOT])
	{
	  if (output_filename != "")
	  {
 	    output = openOutput(output_filename + ".cfg." + suffixes[F_DOT]);
	  }
 	  trace(TRACE_INFORMATION, "-> Printing CFG in dot ...\n");
          // output CFG;
  	  cfgDot(TheCFG);
	  if (output_filename != "")
	  {
	    closeOutput(output);
	    output = NULL;
	  }
	}
      }

      // delete CFG
      if (modus == M_CFG || modus == M_PETRINET)
      {
	delete(TheCFG);
      }
}

void petrinet_unparse()
{
 //     if(modus == M_PETRINET)
      {
        trace(TRACE_INFORMATION, "-> Unparsing AST to Petri net ...\n");

	if (parameters[P_COMMUNICATIONONLY] == false)
	  TheProcess->unparse(kc::pseudoPrinter, kc::petrinet);
	else
	  TheProcess->unparse(kc::pseudoPrinter, kc::petrinetsmall);
      }
}

/**
 * Entry point for BPEL2oWFN.
 * Controls the behaviour of input and output.
 *
 * \param argc	number of command line arguments
 * \param argv	array with command line arguments
 *
 * \returns Error code (0 if everything went well)
 */
int main( int argc, char *argv[])
{

  try
  {
    /***
     * Reading command line arguments and triggering appropriate behaviour.
     * In case of false parameters call command line help function and exit.
     */
    parse_command_line(argc, argv);

    PetriNet * TheNet2 = new PetriNet();
    list< std::string >::iterator file = inputfiles.begin();
    do {
      if (inputfiles.size() >= 1)
      {
	filename = *file;
	if (!(yyin = fopen(filename.c_str(), "r")))
	{
	  throw Exception(FILE_NOT_FOUND, "File '" + filename + "' not found.\n");
	}
      }
      trace(TRACE_INFORMATION, "Parsing " + filename + " ...\n");

      // invoke Bison parser
      int error = yyparse();

      if (!error)
      {
	trace(TRACE_INFORMATION, "Parsing complete.\n");

	if ( filename != "<STDIN>" && yyin != NULL)
	{
	  trace(TRACE_INFORMATION," + Closing input file: " + filename + "\n");
	  fclose(yyin);
	}

	cfg();

	if (modus == M_PETRINET || modus == M_CONSISTENCY)
	{
	  petrinet_unparse();

	  if (modus == M_CONSISTENCY)
	  {
            unsigned int pos = file->rfind(".bpel", file->length());
	    unsigned int pos2 = file->rfind("/", file->length());
	    std::string prefix = "";
	    if (pos == (file->length() - 5))
	    {
	      prefix = file->substr(pos2 + 1, pos - pos2 - 1) + "_";
	    }
	    TheNet->addPrefix(prefix);

	    TheNet2->connectNet(TheNet);
	    TheNet = new PetriNet();
	    TheProcess = NULL;
	  }
	}

      }
      else
      {
	cleanup();

	return error;

      }
      file++;
    } while (modus == M_CONSISTENCY && file != inputfiles.end());

    TheNet = TheNet2;

    if (modus == M_AST)
    {
      trace(TRACE_INFORMATION, "-> Printing AST ...\n");
      TheProcess->print();
    }

    if (modus == M_PRETTY)
    {
      if (formats[F_XML])
      {
        if (output_filename != "")
        {
          output = openOutput(output_filename + "." + suffixes[F_XML]);
        }
        trace(TRACE_INFORMATION, "-> Printing \"pretty\" XML ...\n");
        TheProcess->unparse(kc::printer, kc::xml);
        if (output_filename != "")
        {
          closeOutput(output);
          output = NULL;
        }
      }
    }

    if (modus == M_PETRINET || modus == M_CONSISTENCY)
    {

      // remove variables?
      if ( parameters[P_NOVARIABLES] )
      {
 	trace(TRACE_INFORMATION, "-> Remove variable places from Petri Net ...\n");
        TheNet->removeVariables();
      }
      // simplify net ?
      if ( parameters[P_SIMPLIFY] )
      {
 	trace(TRACE_INFORMATION, "-> Structurally simplifying Petri Net ...\n");
        TheNet->simplify();
      }

      // create oWFN output ?
      if ( formats[F_OWFN] )
      {
        if (output_filename != "")
	{
          output = openOutput(output_filename + "." + suffixes[F_OWFN]);
    	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for oWFN ...\n");
        TheNet->owfnOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create LoLA output ?
      if ( formats[F_LOLA] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_LOLA]);
	}

	// TheNet->makeChannelsInternal();

	trace(TRACE_INFORMATION, "-> Printing Petri net for LoLA ...\n");
        TheNet->lolaOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}

	if (modus == M_CONSISTENCY)
	{
	  if (output_filename != "")
	  {
	    output = openOutput(output_filename + ".task");
	  }
	  std::string andStr = "";
	  (*output) << "FORMULA ALLPATH ALWAYS EXPATH EVENTUALLY (";
	  for (list< std::string >::iterator file = inputfiles.begin(); file != inputfiles.end(); file++)
	  {
            unsigned int pos = file->rfind(".bpel", file->length());
	    unsigned int pos2 = file->rfind("/", file->length());
	    std::string prefix = "";
	    if (pos == (file->length() - 5))
	    {
	      prefix = file->substr(pos2 + 1, pos - pos2 - 1) + "_";
	    }
	    (*output) << andStr << TheNet->findPlace(prefix + "1.internal.final")->nodeShortName() << " > 0";
	    andStr = " AND ";
	  }

	  (*output) << ")";
	  if (output_filename != "")
	  {
	    closeOutput(output);
	    output = NULL;
	  }
	}
      }
      // create PNML output ?
      if ( formats[F_PNML] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_PNML]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for PNML ...\n");
        TheNet->pnmlOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create PEP output ?
      if ( formats[F_PEP] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_PEP]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for PEP ...\n");
        TheNet->pepOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create APNN output ?
      if ( formats[F_APNN] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_APNN]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for APNN ...\n");
        TheNet->apnnOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create dot output ?
      if ( formats[F_DOT] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_DOT]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for dot ...\n");
        TheNet->dotOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create info file ?
      if ( formats[F_INFO] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_INFO]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net information ...\n");
        TheNet->printInformation();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }

    }

  }
  catch (Exception& e)
  {
    // output info file ?
    if ( formats[F_INFO] )
    {
      output = log_output;
      // just print to std::out
      TheNet->printInformation();
      output = NULL;
    }
    error(e);
  }

  return 0;
}
<commit_msg>* fixed bug concerning the "empty" output in Petri net mode<commit_after>/*****************************************************************************\
 * Copyright 2005, 2006 Niels Lohmann, Christian Gierds, Dennis Reinert      *
 *                                                                           *
 * This file is part of BPEL2oWFN.                                           *
 *                                                                           *
 * BPEL2oWFN 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.                                                *
 *                                                                           *
 * BPEL2oWFN 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 BPEL2oWFN; if not, write to the Free Software Foundation, Inc., 51   *
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                      *
\****************************************************************************/

/*!
 * \file main.cc
 *
 * \brief The control component for BPEL2oWFN
 *
 * This file controls the behaviour of BPEL2oWFN and is the interface to the
 * environment.
 *
 * \author
 *          - responsible: Christian Gierds <gierds@informatik.hu-berlin.de>
 *          - last changes of: \$Author: gierds $
 *
 * \date
 *          - created: 2005/10/18
 *          - last changed: \$Date: 2006/06/21 08:54:18 $
 *
 * \note    This file is part of the tool BPEL2oWFN and was created during the
 *          project "Tools4BPEL" at the Humboldt-Universitt zu Berlin. See
 *          http://www.informatik.hu-berlin.de/top/forschung/projekte/tools4bpel
 *          for details.
 *
 * \version \$Revision: 1.78 $
 *          - 2005-11-15 (gierds) Moved command line evaluation to helpers.cc.
 *            Added option to created (abstracted) low level nets.
 *            Added option for LoLA output.
 *          - 2005-11-15 (nlohmann) Call Exception::info() to signal error.
 *          - 2005-11-16 (gierds) Use of error() and cleanup() as defined in
 *            helpers.cc
 *          - 2005-12-13 (gierds) Added variables in order to handle creation
 *            of oWFNs.
 *
 */

#include "main.h"
#include "options.h"
#include "ast-printers.h"

/// The Petri Net
PetriNet *TheNet = new PetriNet();

/// The CFG
CFGBlock * TheCFG = NULL;

void cfg()
{

      // create CFG
      if (modus == M_CFG) //  || modus == M_PETRINET
      {
	TheCFG = NULL;
        trace(TRACE_INFORMATION, "-> Unparsing AST to CFG ...\n");
        TheProcess->unparse(kc::pseudoPrinter, kc::cfg);
	trace(TRACE_DEBUG, "[CFG] checking for DPE\n");
	// do some business with CFG
	list<kc::integer> kcl;
	TheCFG->needsDPE(0, kcl);
	TheCFG->resetProcessedFlag();

	trace(TRACE_DEBUG, "[CFG] checking for cyclic links\n");
	/// \todo (gierds) check for cyclic links, otherwise we will fail
	TheCFG->checkForCyclicLinks();
	TheCFG->resetProcessedFlag(true);

	trace(TRACE_DEBUG, "[CFG] checking for uninitialized variables\n");
	// test
	TheCFG->checkForUninitializedVariables();
	TheCFG->resetProcessedFlag();
	/// end test

	TheCFG->lastBlock->checkForConflictingReceive();
	TheCFG->resetProcessedFlag(true, false);
      }

      if (modus == M_CFG)
      {
	if (formats[F_DOT])
	{
	  if (output_filename != "")
	  {
 	    output = openOutput(output_filename + ".cfg." + suffixes[F_DOT]);
	  }
 	  trace(TRACE_INFORMATION, "-> Printing CFG in dot ...\n");
          // output CFG;
  	  cfgDot(TheCFG);
	  if (output_filename != "")
	  {
	    closeOutput(output);
	    output = NULL;
	  }
	}
      }

      // delete CFG
      if (modus == M_CFG || modus == M_PETRINET)
      {
	delete(TheCFG);
      }
}

void petrinet_unparse()
{
 //     if(modus == M_PETRINET)
      {
        trace(TRACE_INFORMATION, "-> Unparsing AST to Petri net ...\n");

	if (parameters[P_COMMUNICATIONONLY] == false)
	  TheProcess->unparse(kc::pseudoPrinter, kc::petrinet);
	else
	  TheProcess->unparse(kc::pseudoPrinter, kc::petrinetsmall);
      }
}

/**
 * Entry point for BPEL2oWFN.
 * Controls the behaviour of input and output.
 *
 * \param argc	number of command line arguments
 * \param argv	array with command line arguments
 *
 * \returns Error code (0 if everything went well)
 */
int main( int argc, char *argv[])
{

  try
  {
    /***
     * Reading command line arguments and triggering appropriate behaviour.
     * In case of false parameters call command line help function and exit.
     */
    parse_command_line(argc, argv);

    PetriNet * TheNet2 = new PetriNet();
    list< std::string >::iterator file = inputfiles.begin();
    do {
      if (inputfiles.size() >= 1)
      {
	filename = *file;
	if (!(yyin = fopen(filename.c_str(), "r")))
	{
	  throw Exception(FILE_NOT_FOUND, "File '" + filename + "' not found.\n");
	}
      }
      trace(TRACE_INFORMATION, "Parsing " + filename + " ...\n");

      // invoke Bison parser
      int error = yyparse();

      if (!error)
      {
	trace(TRACE_INFORMATION, "Parsing complete.\n");

	if ( filename != "<STDIN>" && yyin != NULL)
	{
	  trace(TRACE_INFORMATION," + Closing input file: " + filename + "\n");
	  fclose(yyin);
	}

	cfg();

	if (modus == M_PETRINET || modus == M_CONSISTENCY)
	{
	  petrinet_unparse();

	  if (modus == M_CONSISTENCY)
	  {
            unsigned int pos = file->rfind(".bpel", file->length());
	    unsigned int pos2 = file->rfind("/", file->length());
	    std::string prefix = "";
	    if (pos == (file->length() - 5))
	    {
	      prefix = file->substr(pos2 + 1, pos - pos2 - 1) + "_";
	    }
	    TheNet->addPrefix(prefix);

	    TheNet2->connectNet(TheNet);
	    TheNet = new PetriNet();
	    TheProcess = NULL;
	  }
	}

      }
      else
      {
	cleanup();

	return error;

      }
      file++;
    } while (modus == M_CONSISTENCY && file != inputfiles.end());

    if (modus == M_CONSISTENCY)
    {
      TheNet = TheNet2;
    }

    if (modus == M_AST)
    {
      trace(TRACE_INFORMATION, "-> Printing AST ...\n");
      TheProcess->print();
    }

    if (modus == M_PRETTY)
    {
      if (formats[F_XML])
      {
        if (output_filename != "")
        {
          output = openOutput(output_filename + "." + suffixes[F_XML]);
        }
        trace(TRACE_INFORMATION, "-> Printing \"pretty\" XML ...\n");
        TheProcess->unparse(kc::printer, kc::xml);
        if (output_filename != "")
        {
          closeOutput(output);
          output = NULL;
        }
      }
    }

    if (modus == M_PETRINET || modus == M_CONSISTENCY)
    {

      // remove variables?
      if ( parameters[P_NOVARIABLES] )
      {
 	trace(TRACE_INFORMATION, "-> Remove variable places from Petri Net ...\n");
        TheNet->removeVariables();
      }
      // simplify net ?
      if ( parameters[P_SIMPLIFY] )
      {
 	trace(TRACE_INFORMATION, "-> Structurally simplifying Petri Net ...\n");
        TheNet->simplify();
      }

      // create oWFN output ?
      if ( formats[F_OWFN] )
      {
        if (output_filename != "")
	{
          output = openOutput(output_filename + "." + suffixes[F_OWFN]);
    	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for oWFN ...\n");
        TheNet->owfnOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create LoLA output ?
      if ( formats[F_LOLA] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_LOLA]);
	}

	// TheNet->makeChannelsInternal();

	trace(TRACE_INFORMATION, "-> Printing Petri net for LoLA ...\n");
        TheNet->lolaOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}

	if (modus == M_CONSISTENCY)
	{
	  if (output_filename != "")
	  {
	    output = openOutput(output_filename + ".task");
	  }
	  std::string andStr = "";
	  (*output) << "FORMULA ALLPATH ALWAYS EXPATH EVENTUALLY (";
	  for (list< std::string >::iterator file = inputfiles.begin(); file != inputfiles.end(); file++)
	  {
            unsigned int pos = file->rfind(".bpel", file->length());
	    unsigned int pos2 = file->rfind("/", file->length());
	    std::string prefix = "";
	    if (pos == (file->length() - 5))
	    {
	      prefix = file->substr(pos2 + 1, pos - pos2 - 1) + "_";
	    }
	    (*output) << andStr << TheNet->findPlace(prefix + "1.internal.final")->nodeShortName() << " > 0";
	    andStr = " AND ";
	  }

	  (*output) << ")";
	  if (output_filename != "")
	  {
	    closeOutput(output);
	    output = NULL;
	  }
	}
      }
      // create PNML output ?
      if ( formats[F_PNML] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_PNML]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for PNML ...\n");
        TheNet->pnmlOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create PEP output ?
      if ( formats[F_PEP] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_PEP]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for PEP ...\n");
        TheNet->pepOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create APNN output ?
      if ( formats[F_APNN] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_APNN]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for APNN ...\n");
        TheNet->apnnOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create dot output ?
      if ( formats[F_DOT] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_DOT]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net for dot ...\n");
        TheNet->dotOut();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }
      // create info file ?
      if ( formats[F_INFO] )
      {
	if (output_filename != "")
	{
 	  output = openOutput(output_filename + "." + suffixes[F_INFO]);
	}
 	trace(TRACE_INFORMATION, "-> Printing Petri net information ...\n");
        TheNet->printInformation();
	if (output_filename != "")
	{
	  closeOutput(output);
	  output = NULL;
	}
      }

    }

  }
  catch (Exception& e)
  {
    // output info file ?
    if ( formats[F_INFO] )
    {
      output = log_output;
      // just print to std::out
      TheNet->printInformation();
      output = NULL;
    }
    error(e);
  }

  return 0;
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                            OpenSim:  testDataTable.cpp                     *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2015 Stanford University and the Authors                *
 * Authors:                                                                   *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include <OpenSim/Common/TimeSeriesTable.h>
#include <iostream>

int main() {
    using namespace SimTK;
    using namespace OpenSim;
    using OpenSim::Exception;

    // Default construct, add metadata to columns, append rows one at a time.

    ValueArray<std::string> labels{};
    for(unsigned i = 1; i <= 5; ++i)
        labels.upd().push_back(SimTK::Value<std::string>{std::to_string(i)});

    ValueArray<unsigned> col_index{};
    for(unsigned i = 1; i <= 5; ++i)
        col_index.upd().push_back(SimTK::Value<unsigned>{i});

    DataTable::DependentsMetaData dep_metadata{};
    dep_metadata.setValueArrayForKey("labels", labels);
    dep_metadata.setValueArrayForKey("column-index", col_index);

    DataTable::IndependentMetaData ind_metadata{};
    ind_metadata.setValueForKey("labels", std::string{"0"});
    ind_metadata.setValueForKey("column-index", unsigned{0});

    TimeSeriesTable table{};
    {
        table.setColumnLabels({"0", "1", "2", "3"});
        assert(table.hasColumn("1"));
        assert(table.hasColumn("2"));
        assert(!table.hasColumn("column-does-not-exist"));

        table.setColumnLabel(0, "zero");
        table.setColumnLabel(2, "two");

        assert(table.getColumnLabel(0) == "zero");
        assert(table.getColumnLabel(2) == "two");

        table.setColumnLabel(0, "0");
        table.setColumnLabel(2, "2");

        const auto& labels = table.getColumnLabels();
        for(size_t i = 0; i < labels.size(); ++i)
            if(labels.at(i) != std::to_string(i))
                throw Exception{"Test failed: labels.at(i) != "
                                "std::to_string(i)"};

        for(size_t i = 0; i < labels.size(); ++i)
            if(table.getColumnIndex(labels.at(i)) != i)
                throw Exception{"Test failed: "
                                "table.getColumnIndex(labels.at(i)) != i"};
    }
    // Print out the DataTable to console.
    std::cout << table << std::endl;

    table.setDependentsMetaData(dep_metadata);
    table.setIndependentMetaData(ind_metadata);

    SimTK::RowVector_<double> row{5, double{0}};

    for(unsigned i = 0; i < 5; ++i)
        table.appendRow(0.00 + 0.25 * i, row + i);

    for(unsigned i = 0; i < 5; ++i)
        table.updRowAtIndex(i) += 1;

    for(unsigned i = 0; i < 5; ++i)
        table.updRow(0 + 0.25 * i) -= 1;

    try {
        table.appendRow(0.5, row);
    } catch (OpenSim::Exception&) {}

    table.updMatrix() += 2;
    table.updMatrixBlock(0, 0, table.getNumRows(), table.getNumColumns()) -= 2;

    table.updTableMetaData().setValueForKey("DataRate", 600);
    table.updTableMetaData().setValueForKey("Filename",
                                            std::string{"/path/to/file"});

    assert(table.hasColumn(0));
    assert(table.hasColumn(2));
    assert(!table.hasColumn(100));

    // Print out the DataTable to console.
    std::cout << table << std::endl;

    // Retrieve added metadata and rows to check.
    if(table.getNumRows() != unsigned{5})
        throw Exception{"Test Failed: table.getNumRows() != unsigned{5}"};

    if(table.getNumColumns() != unsigned{5})
        throw Exception{"Test Failed: table.getNumColumns() != unsigned{5}"};

    const auto& dep_metadata_ref = table.getDependentsMetaData();

    const auto& labels_ref = dep_metadata_ref.getValueArrayForKey("labels");
    for(unsigned i = 0; i < 5; ++i)
        if(labels_ref[i].getValue<std::string>() != std::to_string(i + 1))
            throw Exception{"Test failed: labels_ref[i].getValue<std::string>()"
                    " != std::to_string(i + 1)"};
    {
    const auto& labels = table.getColumnLabels();
    for(unsigned i = 0; i < 5; ++i)
        if(labels.at(i) != std::to_string(i + 1))
            throw Exception{"Test failed: labels[i].getValue<std::string>()"
                    " != std::to_string(i + 1)"};
    }

    const auto& col_index_ref
        = dep_metadata_ref.getValueArrayForKey("column-index");
    for(unsigned i = 0; i < 5; ++i)
        if(col_index_ref[i].getValue<unsigned>() != i + 1)
            throw Exception{"Test failed: col_index_ref[i].getValue<unsigned>()"
                    " != i + 1"};

    const auto& ind_metadata_ref = table.getIndependentMetaData();

    if(ind_metadata_ref.getValueForKey("labels").getValue<std::string>()
       != std::string{"0"})
        throw Exception{"Test failed: ind_metadata_ref.getValueForKey"
                "(\"labels\").getValue<std::string>() != std::string{\"0\"}"};
    if(ind_metadata_ref.getValueForKey("column-index").getValue<unsigned>()
       != unsigned{0})
        throw Exception{"Test failed: ind_metadata_ref.getValueForKey"
                "(\"column-index\").getValue<unsigned>() != unsigned{0}"};

    for(auto i = 0u; i < 5; ++i)
        table.updDependentColumnAtIndex(i) += 2;

    for(unsigned i = 0; i < 5; ++i) {
        for(unsigned j = 0; j < 5; ++j) {
            const auto row_i_1 = table.getRowAtIndex(i);
            if(row_i_1[j] != (row + i)[j] + 2)
                throw Exception{"Test failed: row_i_1[j] != (row + i)[j]"};

            const auto row_i_2 = table.getRow(0 + 0.25 * i);
            if(row_i_2[j] != (row + i)[j] + 2)
                throw Exception{"Test failed: row_i_2[j] != (row + i)[j]"};

            const auto col_i = table.getDependentColumnAtIndex(i);
            if(col_i[j] != j + 2)
                throw Exception{"Test failed: table.getDependentColumnAtIndex"
                        "(i)[j] != j"};
        }
    }

    const auto& tab_metadata_ref = table.getTableMetaData();
    if(tab_metadata_ref.getValueForKey("DataRate").getValue<int>()
       != 600)
        throw Exception{"Test failed: tab_metadata_ref.getValueForKey"
                "(\"DataRate\").getValue<int>() != 600"};
    if(tab_metadata_ref.getValueForKey("Filename").getValue<std::string>()
       != std::string{"/path/to/file"})
        throw Exception{"Test failed: tab_metadata_ref.getValueForKey"
                "(\"Filename\").getValue<std::string>() != std::string"
                "{\"/path/to/file\"}"};

    return 0;
}
<commit_msg>Test for updDependentColumn.<commit_after>/* -------------------------------------------------------------------------- *
 *                            OpenSim:  testDataTable.cpp                     *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2015 Stanford University and the Authors                *
 * Authors:                                                                   *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include <OpenSim/Common/TimeSeriesTable.h>
#include <iostream>

int main() {
    using namespace SimTK;
    using namespace OpenSim;
    using OpenSim::Exception;

    // Default construct, add metadata to columns, append rows one at a time.

    ValueArray<std::string> labels{};
    for(unsigned i = 1; i <= 5; ++i)
        labels.upd().push_back(SimTK::Value<std::string>{std::to_string(i)});

    ValueArray<unsigned> col_index{};
    for(unsigned i = 1; i <= 5; ++i)
        col_index.upd().push_back(SimTK::Value<unsigned>{i});

    DataTable::DependentsMetaData dep_metadata{};
    dep_metadata.setValueArrayForKey("labels", labels);
    dep_metadata.setValueArrayForKey("column-index", col_index);

    DataTable::IndependentMetaData ind_metadata{};
    ind_metadata.setValueForKey("labels", std::string{"0"});
    ind_metadata.setValueForKey("column-index", unsigned{0});

    TimeSeriesTable table{};
    {
        table.setColumnLabels({"0", "1", "2", "3"});
        assert(table.hasColumn("1"));
        assert(table.hasColumn("2"));
        assert(!table.hasColumn("column-does-not-exist"));

        table.setColumnLabel(0, "zero");
        table.setColumnLabel(2, "two");

        assert(table.getColumnLabel(0) == "zero");
        assert(table.getColumnLabel(2) == "two");

        table.setColumnLabel(0, "0");
        table.setColumnLabel(2, "2");

        const auto& labels = table.getColumnLabels();
        for(size_t i = 0; i < labels.size(); ++i)
            if(labels.at(i) != std::to_string(i))
                throw Exception{"Test failed: labels.at(i) != "
                                "std::to_string(i)"};

        for(size_t i = 0; i < labels.size(); ++i)
            if(table.getColumnIndex(labels.at(i)) != i)
                throw Exception{"Test failed: "
                                "table.getColumnIndex(labels.at(i)) != i"};
    }
    // Print out the DataTable to console.
    std::cout << table << std::endl;

    table.setDependentsMetaData(dep_metadata);
    table.setIndependentMetaData(ind_metadata);

    SimTK::RowVector_<double> row{5, double{0}};

    for(unsigned i = 0; i < 5; ++i)
        table.appendRow(0.00 + 0.25 * i, row + i);

    for(unsigned i = 0; i < 5; ++i)
        table.updRowAtIndex(i) += 1;

    for(unsigned i = 0; i < 5; ++i)
        table.updRow(0 + 0.25 * i) -= 1;

    try {
        table.appendRow(0.5, row);
    } catch (OpenSim::Exception&) {}

    table.updMatrix() += 2;
    table.updMatrixBlock(0, 0, table.getNumRows(), table.getNumColumns()) -= 2;

    table.updTableMetaData().setValueForKey("DataRate", 600);
    table.updTableMetaData().setValueForKey("Filename",
                                            std::string{"/path/to/file"});

    assert(table.hasColumn(0));
    assert(table.hasColumn(2));
    assert(!table.hasColumn(100));

    // Print out the DataTable to console.
    std::cout << table << std::endl;

    // Retrieve added metadata and rows to check.
    if(table.getNumRows() != unsigned{5})
        throw Exception{"Test Failed: table.getNumRows() != unsigned{5}"};

    if(table.getNumColumns() != unsigned{5})
        throw Exception{"Test Failed: table.getNumColumns() != unsigned{5}"};

    const auto& dep_metadata_ref = table.getDependentsMetaData();

    const auto& labels_ref = dep_metadata_ref.getValueArrayForKey("labels");
    for(unsigned i = 0; i < 5; ++i)
        if(labels_ref[i].getValue<std::string>() != std::to_string(i + 1))
            throw Exception{"Test failed: labels_ref[i].getValue<std::string>()"
                    " != std::to_string(i + 1)"};
    {
    const auto& labels = table.getColumnLabels();
    for(unsigned i = 0; i < 5; ++i)
        if(labels.at(i) != std::to_string(i + 1))
            throw Exception{"Test failed: labels[i].getValue<std::string>()"
                    " != std::to_string(i + 1)"};
    }

    const auto& col_index_ref
        = dep_metadata_ref.getValueArrayForKey("column-index");
    for(unsigned i = 0; i < 5; ++i)
        if(col_index_ref[i].getValue<unsigned>() != i + 1)
            throw Exception{"Test failed: col_index_ref[i].getValue<unsigned>()"
                    " != i + 1"};

    const auto& ind_metadata_ref = table.getIndependentMetaData();

    if(ind_metadata_ref.getValueForKey("labels").getValue<std::string>()
       != std::string{"0"})
        throw Exception{"Test failed: ind_metadata_ref.getValueForKey"
                "(\"labels\").getValue<std::string>() != std::string{\"0\"}"};
    if(ind_metadata_ref.getValueForKey("column-index").getValue<unsigned>()
       != unsigned{0})
        throw Exception{"Test failed: ind_metadata_ref.getValueForKey"
                "(\"column-index\").getValue<unsigned>() != unsigned{0}"};

    table.updDependentColumnAtIndex(0) += 2;
    table.updDependentColumnAtIndex(2) += 2;
    table.updDependentColumn("1") -= 2;
    table.updDependentColumn("3") -= 2;

    for(unsigned i = 0; i < 5; ++i) {
        for(unsigned j = 0; j < 5; ++j) {
            const auto row_i_1 = table.getRowAtIndex(i);
            if(row_i_1[j] != (row + i)[j])
                throw Exception{"Test failed: row_i_1[j] != (row + i)[j]"};

            const auto row_i_2 = table.getRow(0 + 0.25 * i);
            if(row_i_2[j] != (row + i)[j])
                throw Exception{"Test failed: row_i_2[j] != (row + i)[j]"};

            const auto col_i = table.getDependentColumnAtIndex(i);
            if(col_i[j] != j)
                throw Exception{"Test failed: table.getDependentColumnAtIndex"
                        "(i)[j] != j"};
        }
    }

    const auto& tab_metadata_ref = table.getTableMetaData();
    if(tab_metadata_ref.getValueForKey("DataRate").getValue<int>()
       != 600)
        throw Exception{"Test failed: tab_metadata_ref.getValueForKey"
                "(\"DataRate\").getValue<int>() != 600"};
    if(tab_metadata_ref.getValueForKey("Filename").getValue<std::string>()
       != std::string{"/path/to/file"})
        throw Exception{"Test failed: tab_metadata_ref.getValueForKey"
                "(\"Filename\").getValue<std::string>() != std::string"
                "{\"/path/to/file\"}"};

    return 0;
}
<|endoftext|>


<commit_before>
// Op.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include <stdafx.h>
#include "Op.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyString.h"
#include "interface/PropertyCheck.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "tinyxml/tinyxml.h"
#include "HeeksCNCTypes.h"
#include "CTool.h"
#include "PythonStuff.h"
#include "CNCConfig.h"
#include "MachineState.h"
#include "Program.h"
#ifdef HEEKSCNC
#include "Fixtures.h"
#define FIND_FIRST_TOOL CTool::FindFirstByType
#define FIND_ALL_TOOLS CTool::FindAllTools
#define MACHINE_STATE_TOOL(t) pMachineState->Tool(t)
#else
#define FIND_FIRST_TOOL heeksCNC->FindFirstToolByType
#define FIND_ALL_TOOLS heeksCNC->FindAllTools
#define MACHINE_STATE_TOOL(t) heeksCNC->MachineStateTool(pMachineState, t)
#endif

#include <iterator>
#include <vector>

const wxBitmap& COp::GetInactiveIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/noentry.png")));
	return *icon;
}

void COp::WriteBaseXML(TiXmlElement *element)
{
	if(m_comment.Len() > 0)element->SetAttribute("comment", m_comment.utf8_str());
	element->SetAttribute("active", m_active);
	element->SetAttribute("title", m_title.utf8_str());
	element->SetAttribute("execution_order", m_execution_order);
	element->SetAttribute("tool_number", m_tool_number);

	ObjList::WriteBaseXML(element);
}

void COp::ReadBaseXML(TiXmlElement* element)
{
	const char* comment = element->Attribute("comment");
	if(comment)m_comment.assign(Ctt(comment));
	const char* active = element->Attribute("active");
	if(active)
	{
		int int_active;
		element->Attribute("active", &int_active);
		m_active = (int_active != 0);
	}
	else
	{
        m_active = true;
	}

	const char* title = element->Attribute("title");
	if(title)m_title = wxString(Ctt(title));

	if (element->Attribute("execution_order") != NULL)
	{
		m_execution_order = atoi(element->Attribute("execution_order"));
	} // End if - then
	else
	{
		m_execution_order = 0;
	} // End if - else

	if (element->Attribute("tool_number") != NULL)
	{
		m_tool_number = atoi(element->Attribute("tool_number"));
	} // End if - then
	else
	{
		m_tool_number = 0;
	} // End if - else

	ObjList::ReadBaseXML(element);
}

static void on_set_comment(const wxChar* value, HeeksObj* object){((COp*)object)->m_comment = value;}
static void on_set_active(bool value, HeeksObj* object){((COp*)object)->m_active = value;heeksCAD->Changed();}
static void on_set_execution_order(int value, HeeksObj* object){((COp*)object)->m_execution_order = value;heeksCAD->Changed();}

static void on_set_tool_number(int zero_based_choice, HeeksObj* object)
{
	if (zero_based_choice < 0) return;	// An error has occured.

	std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

	if ((zero_based_choice >= int(0)) && (zero_based_choice <= int(tools.size()-1)))
	{
                ((COp *)object)->m_tool_number = tools[zero_based_choice].first;	// Convert the choice offset to the tool number for that choice
	} // End if - then

	((COp*)object)->WriteDefaultValues();

} // End on_set_tool_number() routine

void COp::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("comment"), m_comment, this, on_set_comment));
	list->push_back(new PropertyCheck(_("active"), m_active, this, on_set_active));
	list->push_back(new PropertyInt(_("execution_order"), m_execution_order, this, on_set_execution_order));

	if(UsesTool()){
		std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

		int choice = 0;
                std::list< wxString > choices;
		for (std::vector< std::pair< int, wxString > >::size_type i=0; i<tools.size(); i++)
		{
                	choices.push_back(tools[i].second);

			if (m_tool_number == tools[i].first)
			{
                		choice = int(i);
			} // End if - then
		} // End for

		list->push_back(new PropertyChoice(_("tool"), choices, choice, this, on_set_tool_number));
	}

	ObjList::GetProperties(list);
}

COp & COp::operator= ( const COp & rhs )
{
	if (this != &rhs)
	{
		// In the case of machine operations, the child objects are all used
		// for reference (position etc.) only.  When we duplicate the machine
		// operation, we don't want to duplicate these reference (child)
		// objects too.
		// To this end, we want to copy the m_objects list without duplicating the
		// objects they point to.  i.e. don't call the ObjList::operator=( rhs ) method.

		m_objects.clear();
		for (HeeksObj *child = ((ObjList &)rhs).GetFirstChild(); child != NULL; child = ((ObjList &)rhs).GetNextChild())
		{
			m_objects.push_back( child );
		} // End for

		HeeksObj::operator=(rhs);	// We need to call this as we've skipped over the ObjList::operator=() method
									// which would normally have called it for us.

		m_comment = rhs.m_comment;
		m_active = rhs.m_active;
		m_title = rhs.m_title;
		m_execution_order = rhs.m_execution_order;
		m_tool_number = rhs.m_tool_number;
		m_operation_type = rhs.m_operation_type;
	}

	return(*this);
}

// Don't call the ObjList() constructor here as the duplication is
// handled in an unusual way by the assignment operator.
COp::COp( const COp & rhs ) // : ObjList(rhs)
{
	*this = rhs;	// Call the assignment operator.
}

void COp::glCommands(bool select, bool marked, bool no_color)
{
	ObjList::glCommands(select, marked, no_color);
}

void COp::WriteDefaultValues()
{
	CNCConfig config(GetTypeString());
	config.Write(_T("Tool"), m_tool_number);
}

void COp::ReadDefaultValues()
{
	if (m_tool_number <= 0)
	{
		// The tool number hasn't been assigned from above.  Set some reasonable
		// defaults.

		CNCConfig config(GetTypeString());

		// assume that default.tooltable contains tools with IDs:
		// 1 drill
		// 2 centre drill
		// 3 end mill
		// 4 slot drill
		// 5 ball end mill
		// 6 chamfering bit
		// 7 turn tool

		int default_tool = 0;
		switch(m_operation_type)
		{
		case DrillingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eDrill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eCentreDrill );
			break;
		case AdaptiveType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ProfileType:
		case PocketType:
		case RaftType:
		case CounterBoreType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ZigZagType:
		case WaterlineType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			break;
		case TurnRoughType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTurningTool );
			break;
        case LocatingType:
		case ProbeCentreType:
		case ProbeEdgeType:
		case ProbeGridType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTouchProbe );
			break;
        case ChamferType:
        case InlayType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eChamfer );
			break;

        case TappingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTapTool );
			break;

		default:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = 4;
			break;
		}
		config.Read(_T("Tool"), &m_tool_number, default_tool);
	} // End if - then
}

/**
    Change tools (if necessary) and assign any private fixtures.
 */
Python COp::AppendTextToProgram(CMachineState *pMachineState )
{
    Python python;

	if(m_comment.Len() > 0)
	{
		python << _T("comment(") << PythonString(m_comment) << _T(")\n");
	}

	if(UsesTool())python << MACHINE_STATE_TOOL(m_tool_number);  // Select the correct  tool.

#ifdef HEEKSCNC
	// Check to see if this operation has its own fixture settings.  If so, change to that fixture now.
	for (HeeksObj *ob = GetFirstChild(); ob != NULL; ob = GetNextChild())
	{
		if (ob->GetType() == FixtureType)
		{
			CFixture *pFixture = (CFixture *) ob;
			python << pMachineState->Fixture(*pFixture);		// Change fixtures.
			break;
		}
	}
#endif

	return(python);
}

void COp::OnEditString(const wxChar* str){
	m_title.assign(str);
	heeksCAD->Changed();
}

#ifdef HEEKSCNC
class AddFixture: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Fixture");}
	void Run()
	{
		CProgram* program = theApp.m_program;
        if (program->Fixtures()->GetNextFixture() > 0)
        {
            CFixture::eCoordinateSystemNumber_t coordinate_system_number = CFixture::eCoordinateSystemNumber_t(program->Fixtures()->GetNextFixture());

            CFixture *new_object = new CFixture( NULL, coordinate_system_number, program->m_machine.m_safety_height_defined, program->m_machine.m_safety_height );
            m_pThis->Add(new_object, NULL);
            heeksCAD->ClearMarkedList();
            heeksCAD->Mark(new_object);
        } // End if - then
        else
        {
            wxMessageBox(_T("There are no more coordinate systems available"));
        } // End if - else
	}
	wxString BitmapPath(){ return _T("fixture");}
	wxString previous_path;
	COp *m_pThis;

public:
	void Set( COp *pOperation ) { m_pThis = pOperation; }
};

static AddFixture add_fixture;
#endif

void COp::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
    ObjList::GetTools( t_list, p );

#ifdef HEEKSCNC
	// See if this operation already has a child fixture.  If so, don't add a second one.
	unsigned int num_private_fixtures = 0;
	for (HeeksObj *child = GetFirstChild(); (child != NULL); child = GetNextChild())
	{
		if (child->GetType() == FixtureType) num_private_fixtures++;
	} // End for

	if (num_private_fixtures < MaxNumberOfPrivateFixtures())
	{
		add_fixture.Set(this);
		t_list->push_back(&add_fixture);
	} // End if - then
#endif
}

/* virtual */ std::list<CFixture> COp::PrivateFixtures()
{
    std::list<CFixture> fixtures;

    for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
    {
        if (child->GetType() == FixtureType)
        {
            fixtures.push_back( *((CFixture *) child) );
        }
    } // End for

    return(fixtures);
} // End PrivateFixtures() method

bool COp::operator==(const COp & rhs) const
{
	if (m_comment != rhs.m_comment) return(false);
	if (m_active != rhs.m_active) return(false);
	if (m_title != rhs.m_title) return(false);
	if (m_execution_order != rhs.m_execution_order) return(false);
	if (m_tool_number != rhs.m_tool_number) return(false);
	if (m_operation_type != rhs.m_operation_type) return(false);

	return(ObjList::operator==(rhs));
}

<commit_msg>Added check for the older name 'cutting_tool_number' as well as the new 'tool_number' names.  The older files were not reading the tool number values.<commit_after>
// Op.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include <stdafx.h>
#include "Op.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyString.h"
#include "interface/PropertyCheck.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "tinyxml/tinyxml.h"
#include "HeeksCNCTypes.h"
#include "CTool.h"
#include "PythonStuff.h"
#include "CNCConfig.h"
#include "MachineState.h"
#include "Program.h"
#ifdef HEEKSCNC
#include "Fixtures.h"
#define FIND_FIRST_TOOL CTool::FindFirstByType
#define FIND_ALL_TOOLS CTool::FindAllTools
#define MACHINE_STATE_TOOL(t) pMachineState->Tool(t)
#else
#define FIND_FIRST_TOOL heeksCNC->FindFirstToolByType
#define FIND_ALL_TOOLS heeksCNC->FindAllTools
#define MACHINE_STATE_TOOL(t) heeksCNC->MachineStateTool(pMachineState, t)
#endif

#include <iterator>
#include <vector>

const wxBitmap& COp::GetInactiveIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/noentry.png")));
	return *icon;
}

void COp::WriteBaseXML(TiXmlElement *element)
{
	if(m_comment.Len() > 0)element->SetAttribute("comment", m_comment.utf8_str());
	element->SetAttribute("active", m_active);
	element->SetAttribute("title", m_title.utf8_str());
	element->SetAttribute("execution_order", m_execution_order);
	element->SetAttribute("tool_number", m_tool_number);

	ObjList::WriteBaseXML(element);
}

void COp::ReadBaseXML(TiXmlElement* element)
{
	const char* comment = element->Attribute("comment");
	if(comment)m_comment.assign(Ctt(comment));
	const char* active = element->Attribute("active");
	if(active)
	{
		int int_active;
		element->Attribute("active", &int_active);
		m_active = (int_active != 0);
	}
	else
	{
        m_active = true;
	}

	const char* title = element->Attribute("title");
	if(title)m_title = wxString(Ctt(title));

	if (element->Attribute("execution_order") != NULL)
	{
		m_execution_order = atoi(element->Attribute("execution_order"));
	} // End if - then
	else
	{
		m_execution_order = 0;
	} // End if - else

	if (element->Attribute("tool_number") != NULL)
	{
		m_tool_number = atoi(element->Attribute("tool_number"));
	} // End if - then
	else
	{
	    // The older files used to call this attribute 'cutting_tool_number'.  Look for this old
	    // name if we can't find the new one.
	    if (element->Attribute("cutting_tool_number") != NULL)
        {
            m_tool_number = atoi(element->Attribute("cutting_tool_number"));
        } // End if - then
        else
        {
            m_tool_number = 0;
        } // End if - else
	} // End if - else

	ObjList::ReadBaseXML(element);
}

static void on_set_comment(const wxChar* value, HeeksObj* object){((COp*)object)->m_comment = value;}
static void on_set_active(bool value, HeeksObj* object){((COp*)object)->m_active = value;heeksCAD->Changed();}
static void on_set_execution_order(int value, HeeksObj* object){((COp*)object)->m_execution_order = value;heeksCAD->Changed();}

static void on_set_tool_number(int zero_based_choice, HeeksObj* object)
{
	if (zero_based_choice < 0) return;	// An error has occured.

	std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

	if ((zero_based_choice >= int(0)) && (zero_based_choice <= int(tools.size()-1)))
	{
                ((COp *)object)->m_tool_number = tools[zero_based_choice].first;	// Convert the choice offset to the tool number for that choice
	} // End if - then

	((COp*)object)->WriteDefaultValues();

} // End on_set_tool_number() routine

void COp::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("comment"), m_comment, this, on_set_comment));
	list->push_back(new PropertyCheck(_("active"), m_active, this, on_set_active));
	list->push_back(new PropertyInt(_("execution_order"), m_execution_order, this, on_set_execution_order));

	if(UsesTool()){
		std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

		int choice = 0;
                std::list< wxString > choices;
		for (std::vector< std::pair< int, wxString > >::size_type i=0; i<tools.size(); i++)
		{
                	choices.push_back(tools[i].second);

			if (m_tool_number == tools[i].first)
			{
                		choice = int(i);
			} // End if - then
		} // End for

		list->push_back(new PropertyChoice(_("tool"), choices, choice, this, on_set_tool_number));
	}

	ObjList::GetProperties(list);
}

COp & COp::operator= ( const COp & rhs )
{
	if (this != &rhs)
	{
		// In the case of machine operations, the child objects are all used
		// for reference (position etc.) only.  When we duplicate the machine
		// operation, we don't want to duplicate these reference (child)
		// objects too.
		// To this end, we want to copy the m_objects list without duplicating the
		// objects they point to.  i.e. don't call the ObjList::operator=( rhs ) method.

		m_objects.clear();
		for (HeeksObj *child = ((ObjList &)rhs).GetFirstChild(); child != NULL; child = ((ObjList &)rhs).GetNextChild())
		{
			m_objects.push_back( child );
		} // End for

		HeeksObj::operator=(rhs);	// We need to call this as we've skipped over the ObjList::operator=() method
									// which would normally have called it for us.

		m_comment = rhs.m_comment;
		m_active = rhs.m_active;
		m_title = rhs.m_title;
		m_execution_order = rhs.m_execution_order;
		m_tool_number = rhs.m_tool_number;
		m_operation_type = rhs.m_operation_type;
	}

	return(*this);
}

// Don't call the ObjList() constructor here as the duplication is
// handled in an unusual way by the assignment operator.
COp::COp( const COp & rhs ) // : ObjList(rhs)
{
	*this = rhs;	// Call the assignment operator.
}

void COp::glCommands(bool select, bool marked, bool no_color)
{
	ObjList::glCommands(select, marked, no_color);
}

void COp::WriteDefaultValues()
{
	CNCConfig config(GetTypeString());
	config.Write(_T("Tool"), m_tool_number);
}

void COp::ReadDefaultValues()
{
	if (m_tool_number <= 0)
	{
		// The tool number hasn't been assigned from above.  Set some reasonable
		// defaults.

		CNCConfig config(GetTypeString());

		// assume that default.tooltable contains tools with IDs:
		// 1 drill
		// 2 centre drill
		// 3 end mill
		// 4 slot drill
		// 5 ball end mill
		// 6 chamfering bit
		// 7 turn tool

		int default_tool = 0;
		switch(m_operation_type)
		{
		case DrillingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eDrill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eCentreDrill );
			break;
		case AdaptiveType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ProfileType:
		case PocketType:
		case RaftType:
		case CounterBoreType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ZigZagType:
		case WaterlineType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			break;
		case TurnRoughType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTurningTool );
			break;
        case LocatingType:
		case ProbeCentreType:
		case ProbeEdgeType:
		case ProbeGridType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTouchProbe );
			break;
        case ChamferType:
        case InlayType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eChamfer );
			break;

        case TappingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTapTool );
			break;

		default:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = 4;
			break;
		}
		config.Read(_T("Tool"), &m_tool_number, default_tool);
	} // End if - then
}

/**
    Change tools (if necessary) and assign any private fixtures.
 */
Python COp::AppendTextToProgram(CMachineState *pMachineState )
{
    Python python;

	if(m_comment.Len() > 0)
	{
		python << _T("comment(") << PythonString(m_comment) << _T(")\n");
	}

	if(UsesTool())python << MACHINE_STATE_TOOL(m_tool_number);  // Select the correct  tool.

#ifdef HEEKSCNC
	// Check to see if this operation has its own fixture settings.  If so, change to that fixture now.
	for (HeeksObj *ob = GetFirstChild(); ob != NULL; ob = GetNextChild())
	{
		if (ob->GetType() == FixtureType)
		{
			CFixture *pFixture = (CFixture *) ob;
			python << pMachineState->Fixture(*pFixture);		// Change fixtures.
			break;
		}
	}
#endif

	return(python);
}

void COp::OnEditString(const wxChar* str){
	m_title.assign(str);
	heeksCAD->Changed();
}

#ifdef HEEKSCNC
class AddFixture: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Fixture");}
	void Run()
	{
		CProgram* program = theApp.m_program;
        if (program->Fixtures()->GetNextFixture() > 0)
        {
            CFixture::eCoordinateSystemNumber_t coordinate_system_number = CFixture::eCoordinateSystemNumber_t(program->Fixtures()->GetNextFixture());

            CFixture *new_object = new CFixture( NULL, coordinate_system_number, program->m_machine.m_safety_height_defined, program->m_machine.m_safety_height );
            m_pThis->Add(new_object, NULL);
            heeksCAD->ClearMarkedList();
            heeksCAD->Mark(new_object);
        } // End if - then
        else
        {
            wxMessageBox(_T("There are no more coordinate systems available"));
        } // End if - else
	}
	wxString BitmapPath(){ return _T("fixture");}
	wxString previous_path;
	COp *m_pThis;

public:
	void Set( COp *pOperation ) { m_pThis = pOperation; }
};

static AddFixture add_fixture;
#endif

void COp::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
    ObjList::GetTools( t_list, p );

#ifdef HEEKSCNC
	// See if this operation already has a child fixture.  If so, don't add a second one.
	unsigned int num_private_fixtures = 0;
	for (HeeksObj *child = GetFirstChild(); (child != NULL); child = GetNextChild())
	{
		if (child->GetType() == FixtureType) num_private_fixtures++;
	} // End for

	if (num_private_fixtures < MaxNumberOfPrivateFixtures())
	{
		add_fixture.Set(this);
		t_list->push_back(&add_fixture);
	} // End if - then
#endif
}

/* virtual */ std::list<CFixture> COp::PrivateFixtures()
{
    std::list<CFixture> fixtures;

    for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
    {
        if (child->GetType() == FixtureType)
        {
            fixtures.push_back( *((CFixture *) child) );
        }
    } // End for

    return(fixtures);
} // End PrivateFixtures() method

bool COp::operator==(const COp & rhs) const
{
	if (m_comment != rhs.m_comment) return(false);
	if (m_active != rhs.m_active) return(false);
	if (m_title != rhs.m_title) return(false);
	if (m_execution_order != rhs.m_execution_order) return(false);
	if (m_tool_number != rhs.m_tool_number) return(false);
	if (m_operation_type != rhs.m_operation_type) return(false);

	return(ObjList::operator==(rhs));
}

<|endoftext|>


<commit_before>///
/// @file  Pk.cpp
/// @brief Partial sieve functions.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "pi_bsearch.hpp"
#include "pmath.hpp"

#include <primecount.hpp>
#include <primesieve.hpp>
#include <algorithm>
#include <stdint.h>
#include <vector>

#ifdef _OPENMP
  #include <omp.h>
  #include "get_omp_threads.hpp"
#endif

using namespace std;

namespace primecount {

/// 2nd partial sieve function.
/// P2(x, a) counts the numbers <= x that have exactly 2 prime
/// factors each exceeding the a-th prime.
/// Space complexity: O((x / primes[a])^(1/2)).
///
int64_t P2(int64_t x, int64_t a)
{
  vector<int32_t> primes;
  primes.push_back(0);
  primesieve::generate_n_primes(a, &primes);
  int64_t limit = (a > 0) ? x / primes[a] : x;
  int64_t sqrt_limit = isqrt(limit);
  int64_t sum = 0; // \sum_{i=a+1}^{b} pi(x / primes[i]) - (i - 1)
  int64_t pix = 1; // start counting primes at 3
  int64_t sqrtx = isqrt(x);
  int64_t b = pi_legendre(sqrtx, 1);
  int64_t segment_size = next_power_of_2(sqrt_limit);

  if (b <= a)
    return sum;

  primesieve::iterator iter(sqrtx + 1);
  int64_t stop = x / iter.previous_prime();
  vector<char> sieve(segment_size);
  vector<int64_t> next(primes.size());

  for (size_t i = 1; i < primes.size(); i++)
    next[i] = (isquare(primes[i]) - /* low */ 3) % segment_size;

  // segmented sieve of Eratosthenes
  for (int64_t low = 3; low <= limit; low += segment_size)
  {
    fill(sieve.begin(), sieve.end(), 1);

    // current segment = interval [low, high]
    int64_t high = min(low + segment_size - 1, limit);
    int64_t sqrt_high = isqrt(high);

    for (size_t i = 2; i < primes.size(); i++)
    {
      if (primes[i] > sqrt_high)
        break;
      int64_t k = next[i];
      for (int64_t p2 = primes[i] * 2; k < segment_size; k += p2)
        sieve[k] = 0;
      next[i] = k - segment_size;
    }

    int64_t j = ~low % 2;
    for (; stop <= high; stop = x / iter.previous_prime())
    {
      for (; j <= stop - low; j += 2)
        pix += sieve[j];
      // sum += pi(x / primes[b]) - (b - 1)
      sum += pix - (b - 1);
      if (--b <= a) return sum;
    }

    for (; j <= high - low; j += 2)
      pix += sieve[j];
  }

  return sum;
}

/// 2nd partial sieve function.
/// P2_lehmer(x, a) counts the numbers <= x that have exactly 2 prime
/// factors each exceeding the a-th prime. This implementation is
/// optimized for small values of a < pi(x^(1/3)) which requires
/// sieving up to a large limit (x / primes[a]). Sieving is done in
/// parallel using primesieve (segmented sieve of Eratosthenes).
/// Space complexity: O(pi(sqrt(x))).
///
int64_t P2_lehmer(int64_t x, int64_t a, int threads)
{
  vector<int32_t> primes;
  vector<int64_t> counts;
  primes.push_back(0);
  primesieve::generate_primes(isqrt(x), &primes);
  counts.resize(primes.size());

  int64_t b = pi_bsearch(primes, isqrt(x));
  int64_t sum = 0;
  int64_t pix = 0;

#ifdef _OPENMP
  #pragma omp parallel for num_threads(get_omp_threads(threads)) \
      schedule(dynamic)
#endif
  for (int64_t i = b; i > a; i--)
  {
    int64_t prev = (i == b) ? 0 : x / primes[i + 1] + 1;
    int64_t xi = x / primes[i];
    counts[i] = primesieve::count_primes(prev, xi);
  }

  for (int64_t i = b; i > a; i--)
  {
    pix += counts[i];
    sum += pix - (i - 1);
  }

  return sum;
}

/// 3rd partial sieve function.
/// P3(x, a) counts the numbers <= x that have exactly 3 prime
/// factors each exceeding the a-th prime.
/// Space complexity: O(pi(sqrt(x))).
///
int64_t P3(int64_t x, int64_t a, int threads)
{
  vector<int32_t> primes;
  primes.push_back(0);
  primesieve::generate_primes(isqrt(x), &primes);

  int64_t y = iroot<3>(x);
  int64_t pi_y = pi_bsearch(primes, y);
  int64_t sum = 0;

#ifdef _OPENMP
  #pragma omp parallel for num_threads(get_omp_threads(threads)) \
      schedule(dynamic) reduction(+: sum)
#endif
  for (int64_t i = a + 1; i <= pi_y; i++)
  {
    int64_t xi = x / primes[i];
    int64_t bi = pi_bsearch(primes, isqrt(xi));

    for (int64_t j = i; j <= bi; j++)
      sum += pi_bsearch(primes, xi / primes[j]) - (j - 1);
  }

  return sum;
}

} // namespace primecount
<commit_msg>Update Pk.cpp<commit_after>///
/// @file  Pk.cpp
/// @brief Partial sieve functions.
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "pi_bsearch.hpp"
#include "pmath.hpp"

#include <primecount.hpp>
#include <primesieve.hpp>
#include <algorithm>
#include <stdint.h>
#include <vector>

#ifdef _OPENMP
  #include <omp.h>
  #include "get_omp_threads.hpp"
#endif

using namespace std;

namespace primecount {

/// 2nd partial sieve function.
/// P2(x, a) counts the numbers <= x that have exactly 2 prime
/// factors each exceeding the a-th prime.
/// Space complexity: O((x / primes[a])^(1/2)).
///
int64_t P2(int64_t x, int64_t a)
{
  vector<int32_t> primes;
  primes.push_back(0);
  primesieve::generate_n_primes(a, &primes);
  int64_t limit = (a > 0) ? x / primes[a] : x;
  int64_t sqrt_limit = isqrt(limit);
  int64_t sum = 0; // \sum_{i=a+1}^{b} pi(x / primes[i]) - (i - 1)
  int64_t pix = 1; // start counting primes at 3
  int64_t sqrtx = isqrt(x);
  int64_t b = pi_legendre(sqrtx, 1);
  int64_t segment_size = next_power_of_2(sqrt_limit);

  if (b <= a)
    return sum;

  primesieve::iterator iter(sqrtx + 1);
  int64_t stop = x / iter.previous_prime();
  vector<char> sieve(segment_size);
  vector<int64_t> next(primes.size());

  for (size_t i = 1; i < primes.size(); i++)
    next[i] = (isquare(primes[i]) - /* low */ 3) % segment_size;

  // segmented sieve of Eratosthenes
  for (int64_t low = 3; low <= limit; low += segment_size)
  {
    fill(sieve.begin(), sieve.end(), 1);

    // current segment = interval [low, high]
    int64_t high = min(low + segment_size - 1, limit);
    int64_t sqrt_high = isqrt(high);

    for (size_t i = 2; i < primes.size(); i++)
    {
      if (primes[i] > sqrt_high)
        break;
      int64_t k = next[i];
      for (int64_t p2 = primes[i] * 2; k < segment_size; k += p2)
        sieve[k] = 0;
      next[i] = k - segment_size;
    }

    int64_t j = ~low & 1;
    for (; stop <= high; stop = x / iter.previous_prime())
    {
      for (; j <= stop - low; j += 2)
        pix += sieve[j];
      // sum += pi(x / primes[b]) - (b - 1)
      sum += pix - (b - 1);
      if (--b <= a) return sum;
    }

    for (; j <= high - low; j += 2)
      pix += sieve[j];
  }

  return sum;
}

/// 2nd partial sieve function.
/// P2_lehmer(x, a) counts the numbers <= x that have exactly 2 prime
/// factors each exceeding the a-th prime. This implementation is
/// optimized for small values of a < pi(x^(1/3)) which requires
/// sieving up to a large limit (x / primes[a]). Sieving is done in
/// parallel using primesieve (segmented sieve of Eratosthenes).
/// Space complexity: O(pi(sqrt(x))).
///
int64_t P2_lehmer(int64_t x, int64_t a, int threads)
{
  vector<int32_t> primes;
  vector<int64_t> counts;
  primes.push_back(0);
  primesieve::generate_primes(isqrt(x), &primes);
  counts.resize(primes.size());

  int64_t b = pi_bsearch(primes, isqrt(x));
  int64_t sum = 0;
  int64_t pix = 0;

#ifdef _OPENMP
  #pragma omp parallel for num_threads(get_omp_threads(threads)) \
      schedule(dynamic)
#endif
  for (int64_t i = b; i > a; i--)
  {
    int64_t prev = (i == b) ? 0 : x / primes[i + 1] + 1;
    int64_t xi = x / primes[i];
    counts[i] = primesieve::count_primes(prev, xi);
  }

  for (int64_t i = b; i > a; i--)
  {
    pix += counts[i];
    sum += pix - (i - 1);
  }

  return sum;
}

/// 3rd partial sieve function.
/// P3(x, a) counts the numbers <= x that have exactly 3 prime
/// factors each exceeding the a-th prime.
/// Space complexity: O(pi(sqrt(x))).
///
int64_t P3(int64_t x, int64_t a, int threads)
{
  vector<int32_t> primes;
  primes.push_back(0);
  primesieve::generate_primes(isqrt(x), &primes);

  int64_t y = iroot<3>(x);
  int64_t pi_y = pi_bsearch(primes, y);
  int64_t sum = 0;

#ifdef _OPENMP
  #pragma omp parallel for num_threads(get_omp_threads(threads)) \
      schedule(dynamic) reduction(+: sum)
#endif
  for (int64_t i = a + 1; i <= pi_y; i++)
  {
    int64_t xi = x / primes[i];
    int64_t bi = pi_bsearch(primes, isqrt(xi));

    for (int64_t j = i; j <= bi; j++)
      sum += pi_bsearch(primes, xi / primes[j]) - (j - 1);
  }

  return sum;
}

} // namespace primecount
<|endoftext|>