<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreWindowEventUtilities.h"
#include "OgreRenderWindow.h"
#include "OgreLogManager.h"
#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreStringConverter.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <X11/Xlib.h>
void GLXProc( Ogre::RenderWindow *win, const XEvent &event );
#endif

//using namespace Ogre;

Ogre::WindowEventUtilities::WindowEventListeners Ogre::WindowEventUtilities::_msListeners;
Ogre::RenderWindowList Ogre::WindowEventUtilities::_msWindows;

namespace Ogre {
//--------------------------------------------------------------------------------//
void WindowEventUtilities::messagePump()
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	// Windows Message Loop (NULL means check all HWNDs belonging to this context)
	MSG  msg;
	while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
	{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
	//GLX Message Pump
	Windows::iterator win = _msWindows.begin();
	Windows::iterator end = _msWindows.end();

	Display* xDisplay = 0; // same for all windows

	for (; win != end; win++)
	{
	    XID xid;
	    XEvent event;

	    if (!xDisplay)
		(*win)->getCustomAttribute("XDISPLAY", &xDisplay);

	    (*win)->getCustomAttribute("WINDOW", &xid);

	    while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event))
	    {
		GLXProc(*win, event);
	    }

	    // The ClientMessage event does not appear under any Event Mask
	    while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event))
	    {
		GLXProc(*win, event);
	    }
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
	// OSX Message Pump
	EventRef event = NULL;
	EventTargetRef targetWindow;
	targetWindow = GetEventDispatcherTarget();

    // If we are unable to get the target then we no longer care about events.
    if( !targetWindow ) return;

    // Grab the next event, process it if it is a window event
	while( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
	{
        // Dispatch the event
		SendEventToEventTarget( event, targetWindow );
   		ReleaseEvent( event );
	}
#endif
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::addWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	_msListeners.insert(std::make_pair(window, listener));
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::removeWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end();

	for( ; i != e; ++i )
	{
		if( i->first == window && i->second == listener )
		{
			_msListeners.erase(i);
			break;
		}
	}
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_addRenderWindow(RenderWindow* window)
{
	_msWindows.push_back(window);
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_removeRenderWindow(RenderWindow* window)
{
	RenderWindowList::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window);
	if( i != _msWindows.end() )
		_msWindows.erase( i );
}

}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//--------------------------------------------------------------------------------//
namespace Ogre {
LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CREATE)
	{	// Store pointer to Win32Window in user data area
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
		return 0;
	}

	// look up window instance
	// note: it is possible to get a WM_SIZE before WM_CREATE
	RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!win)
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	//LogManager* log = LogManager::getSingletonPtr();
	//Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(win),
        end = _msListeners.upper_bound(win);

	switch( uMsg )
	{
	case WM_ACTIVATE:
	{
        bool active = (LOWORD(wParam) != WA_INACTIVE);
        if( active )
        {
		    win->setActive( true );
        }
        else
        {
            if( win->isDeactivatedOnFocusChange() )
            {
    		    win->setActive( false );
            }
        }

	    for( ; start != end; ++start )
		    (start->second)->windowFocusChange(win);
		break;
	}
	case WM_SYSKEYDOWN:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSKEYUP:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
		case VK_F10:
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSCHAR:
		// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
		if (wParam != VK_SPACE)
			return 0;
		break;
	case WM_ENTERSIZEMOVE:
		//log->logMessage("WM_ENTERSIZEMOVE");
		break;
	case WM_EXITSIZEMOVE:
		//log->logMessage("WM_EXITSIZEMOVE");
		break;
	case WM_MOVE:
		//log->logMessage("WM_MOVE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowMoved(win);
		break;
	case WM_DISPLAYCHANGE:
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_SIZE:
		//log->logMessage("WM_SIZE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_GETMINMAXINFO:
		// Prevent the window from going smaller than some minimu size
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
		break;
	case WM_CLOSE:
	{
		//log->logMessage("WM_CLOSE");
		bool close = true;
		for(index = start; index != end; ++index)
		{
			if (!(index->second)->windowClosing(win))
				close = false;
		}
		if (!close) return 0;

		for(index = _msListeners.lower_bound(win); index != end; ++index)
			(index->second)->windowClosed(win);
		win->destroy();
		return 0;
	}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//--------------------------------------------------------------------------------//
void GLXProc( Ogre::RenderWindow *win, const XEvent &event )
{
	//An iterator for the window listeners
  Ogre::WindowEventUtilities::WindowEventListeners::iterator index,
		start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win),
		end   = Ogre::WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window closed by window manager
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			bool close = true;
            for(index = start ; index != end; ++index)
			{
				if (!(index->second)->windowClosing(win))
					close = false;
			}
			if (!close) return;

            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case DestroyNotify:
	{
		if (!win->isClosed())
		{
			// Window closed without window manager warning.
            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:
	{
        // This could be slightly more efficient if windowMovedOrResized took arguments:
		unsigned int oldWidth, oldHeight, oldDepth;
		int oldLeft, oldTop;
		win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop);
		win->windowMovedOrResized();

		unsigned int newWidth, newHeight, newDepth;
		int newLeft, newTop;
		win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop);

		if (newLeft != oldLeft || newTop != oldTop)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowMoved(win);
		}

		if (newWidth != oldWidth || newHeight != oldHeight)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowResized(win);
		}
		break;
	}
	case FocusIn:     // Gained keyboard focus
	case FocusOut:    // Lost keyboard focus
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case MapNotify:   //Restored
		win->setActive( true );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
//--------------------------------------------------------------------------------//
namespace Ogre {
OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd)
{
    OSStatus status = noErr;

    // Only events from our window should make it here
    // This ensures that our user data is our WindowRef
    RenderWindow* curWindow = (RenderWindow*)wnd;
    if(!curWindow) return eventNotHandledErr;

    //Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(curWindow),
        end = _msListeners.upper_bound(curWindow);

    // We only get called if a window event happens
    UInt32 eventKind = GetEventKind( event );

    switch( eventKind )
    {
        case kEventWindowActivated:
            curWindow->setActive( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDeactivated:
            if( curWindow->isDeactivatedOnFocusChange() )
            {
                curWindow->setActive( false );
            }

            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);

            break;
        case kEventWindowShown:
        case kEventWindowExpanded:
            curWindow->setActive( true );
            curWindow->setVisible( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowHidden:
        case kEventWindowCollapsed:
            curWindow->setActive( false );
            curWindow->setVisible( false );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDragCompleted:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowMoved(curWindow);
            break;
        case kEventWindowBoundsChanged:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowResized(curWindow);
            break;
		case kEventWindowClose:
		{
			bool close = true;
			for( ; start != end; ++start )
			{
				if (!(start->second)->windowClosing(curWindow))
					close = false;
			}
			if (close)
				// This will cause event handling to continue on to the standard handler, which calls
				// DisposeWindow(), which leads to the 'kEventWindowClosed' event
				status = eventNotHandledErr;
			break;
		}
        case kEventWindowClosed:
            curWindow->destroy();
            for( ; start != end; ++start )
				(start->second)->windowClosed(curWindow);
            break;
        default:
            status = eventNotHandledErr;
            break;
    }

    return status;
}
}
#endif
<commit_msg>[OGRE-122] Fix the build.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreCommon.h"
#include "OgreWindowEventUtilities.h"
#include "OgreRenderWindow.h"
#include "OgreLogManager.h"
#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreStringConverter.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <X11/Xlib.h>
void GLXProc( Ogre::RenderWindow *win, const XEvent &event );
#endif

//using namespace Ogre;

Ogre::WindowEventUtilities::WindowEventListeners Ogre::WindowEventUtilities::_msListeners;
Ogre::RenderWindowList Ogre::WindowEventUtilities::_msWindows;

namespace Ogre {
//--------------------------------------------------------------------------------//
void WindowEventUtilities::messagePump()
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	// Windows Message Loop (NULL means check all HWNDs belonging to this context)
	MSG  msg;
	while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
	{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
	//GLX Message Pump
	RenderWindowList::iterator win = _msWindows.begin();
	RenderWindowList::iterator end = _msWindows.end();

	Display* xDisplay = 0; // same for all windows

	for (; win != end; win++)
	{
	    XID xid;
	    XEvent event;

	    if (!xDisplay)
		(*win)->getCustomAttribute("XDISPLAY", &xDisplay);

	    (*win)->getCustomAttribute("WINDOW", &xid);

	    while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event))
	    {
		GLXProc(*win, event);
	    }

	    // The ClientMessage event does not appear under any Event Mask
	    while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event))
	    {
		GLXProc(*win, event);
	    }
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
	// OSX Message Pump
	EventRef event = NULL;
	EventTargetRef targetWindow;
	targetWindow = GetEventDispatcherTarget();

    // If we are unable to get the target then we no longer care about events.
    if( !targetWindow ) return;

    // Grab the next event, process it if it is a window event
	while( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
	{
        // Dispatch the event
		SendEventToEventTarget( event, targetWindow );
   		ReleaseEvent( event );
	}
#endif
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::addWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	_msListeners.insert(std::make_pair(window, listener));
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::removeWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end();

	for( ; i != e; ++i )
	{
		if( i->first == window && i->second == listener )
		{
			_msListeners.erase(i);
			break;
		}
	}
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_addRenderWindow(RenderWindow* window)
{
	_msWindows.push_back(window);
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_removeRenderWindow(RenderWindow* window)
{
	RenderWindowList::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window);
	if( i != _msWindows.end() )
		_msWindows.erase( i );
}

}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//--------------------------------------------------------------------------------//
namespace Ogre {
LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CREATE)
	{	// Store pointer to Win32Window in user data area
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
		return 0;
	}

	// look up window instance
	// note: it is possible to get a WM_SIZE before WM_CREATE
	RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!win)
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	//LogManager* log = LogManager::getSingletonPtr();
	//Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(win),
        end = _msListeners.upper_bound(win);

	switch( uMsg )
	{
	case WM_ACTIVATE:
	{
        bool active = (LOWORD(wParam) != WA_INACTIVE);
        if( active )
        {
		    win->setActive( true );
        }
        else
        {
            if( win->isDeactivatedOnFocusChange() )
            {
    		    win->setActive( false );
            }
        }

	    for( ; start != end; ++start )
		    (start->second)->windowFocusChange(win);
		break;
	}
	case WM_SYSKEYDOWN:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSKEYUP:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
		case VK_F10:
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSCHAR:
		// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
		if (wParam != VK_SPACE)
			return 0;
		break;
	case WM_ENTERSIZEMOVE:
		//log->logMessage("WM_ENTERSIZEMOVE");
		break;
	case WM_EXITSIZEMOVE:
		//log->logMessage("WM_EXITSIZEMOVE");
		break;
	case WM_MOVE:
		//log->logMessage("WM_MOVE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowMoved(win);
		break;
	case WM_DISPLAYCHANGE:
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_SIZE:
		//log->logMessage("WM_SIZE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_GETMINMAXINFO:
		// Prevent the window from going smaller than some minimu size
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
		break;
	case WM_CLOSE:
	{
		//log->logMessage("WM_CLOSE");
		bool close = true;
		for(index = start; index != end; ++index)
		{
			if (!(index->second)->windowClosing(win))
				close = false;
		}
		if (!close) return 0;

		for(index = _msListeners.lower_bound(win); index != end; ++index)
			(index->second)->windowClosed(win);
		win->destroy();
		return 0;
	}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//--------------------------------------------------------------------------------//
void GLXProc( Ogre::RenderWindow *win, const XEvent &event )
{
	//An iterator for the window listeners
  Ogre::WindowEventUtilities::WindowEventListeners::iterator index,
		start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win),
		end   = Ogre::WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window closed by window manager
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			bool close = true;
            for(index = start ; index != end; ++index)
			{
				if (!(index->second)->windowClosing(win))
					close = false;
			}
			if (!close) return;

            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case DestroyNotify:
	{
		if (!win->isClosed())
		{
			// Window closed without window manager warning.
            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:
	{
        // This could be slightly more efficient if windowMovedOrResized took arguments:
		unsigned int oldWidth, oldHeight, oldDepth;
		int oldLeft, oldTop;
		win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop);
		win->windowMovedOrResized();

		unsigned int newWidth, newHeight, newDepth;
		int newLeft, newTop;
		win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop);

		if (newLeft != oldLeft || newTop != oldTop)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowMoved(win);
		}

		if (newWidth != oldWidth || newHeight != oldHeight)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowResized(win);
		}
		break;
	}
	case FocusIn:     // Gained keyboard focus
	case FocusOut:    // Lost keyboard focus
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case MapNotify:   //Restored
		win->setActive( true );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
//--------------------------------------------------------------------------------//
namespace Ogre {
OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd)
{
    OSStatus status = noErr;

    // Only events from our window should make it here
    // This ensures that our user data is our WindowRef
    RenderWindow* curWindow = (RenderWindow*)wnd;
    if(!curWindow) return eventNotHandledErr;

    //Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(curWindow),
        end = _msListeners.upper_bound(curWindow);

    // We only get called if a window event happens
    UInt32 eventKind = GetEventKind( event );

    switch( eventKind )
    {
        case kEventWindowActivated:
            curWindow->setActive( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDeactivated:
            if( curWindow->isDeactivatedOnFocusChange() )
            {
                curWindow->setActive( false );
            }

            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);

            break;
        case kEventWindowShown:
        case kEventWindowExpanded:
            curWindow->setActive( true );
            curWindow->setVisible( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowHidden:
        case kEventWindowCollapsed:
            curWindow->setActive( false );
            curWindow->setVisible( false );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDragCompleted:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowMoved(curWindow);
            break;
        case kEventWindowBoundsChanged:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowResized(curWindow);
            break;
		case kEventWindowClose:
		{
			bool close = true;
			for( ; start != end; ++start )
			{
				if (!(start->second)->windowClosing(curWindow))
					close = false;
			}
			if (close)
				// This will cause event handling to continue on to the standard handler, which calls
				// DisposeWindow(), which leads to the 'kEventWindowClosed' event
				status = eventNotHandledErr;
			break;
		}
        case kEventWindowClosed:
            curWindow->destroy();
            for( ; start != end; ++start )
				(start->second)->windowClosed(curWindow);
            break;
        default:
            status = eventNotHandledErr;
            break;
    }

    return status;
}
}
#endif
<|endoftext|>


<commit_before>/* $Id$ */

// Script to create calibration parameters and store them into CDB
// Two sets of calibration parameters can be created:
// 1) equal parameters
// 2) randomly distributed parameters for decalibrated detector silumations

#if !defined(__CINT__)
#include "TControlBar.h"
#include "TString.h"
#include "TRandom.h"
#include "TH2F.h"
#include "TCanvas.h"

#include "AliRun.h"
#include "AliPHOSCalibData.h"
#include "AliCDBMetaData.h"
#include "AliCDBId.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#endif

static const Int_t nMod =  5;
static const Int_t nCol = 56;
static const Int_t nRow = 64;

void AliPHOSSetCDB()
{
  TControlBar *menu = new TControlBar("vertical","PHOS CDB");
  menu->AddButton("Help to run PHOS CDB","Help()",
		  "Explains how to use PHOS CDS menus");
  menu->AddButton("Equal CC","SetCC(0)",
		  "Set equal calibration coefficients");
  menu->AddButton("Decalibrate","SetCC(1)",
		  "Set random decalibration calibration coefficients");
  menu->AddButton("Set calibration equal to invers decalibration coefficients","SetCC(2)",
		  "Set calibration coefficients inverse to decalibration ones");
  menu->AddButton("Residual calibration","SetCC(3)",
		  "Set residual decalibration calibration coefficients");

  menu->AddButton("Read equal CC","GetCC(0)",
		  "Read initial equal calibration coefficients");
  menu->AddButton("Read random CC","GetCC(1)",
		  "Read random decalibration calibration coefficients");
  menu->AddButton("Read inverse CC","GetCC(2)",
		  "Read calibration coefficients inverse to decalibration ones");
  menu->AddButton("Read residual CC","GetCC(3)",
		  "Read residial calibration coefficients");
  menu->Show();
}

//------------------------------------------------------------------------
void Help()
{
  char *string =
    "\nSet calibration parameters and write them into ALICE CDB.
Press button \"Equal CC\" to create equal pedestals and gain factors.
Press button \"Decalibrate\" to create random pedestals and gain factors to imitate decalibrated detector\n";
  printf(string);
}

//------------------------------------------------------------------------
void SetCC(Int_t flag=0)
{
  // Writing calibration coefficients into the Calibration DB
  // Arguments:
  //   flag=0: all calibration coefficients are equal
  //   flag=1: decalibration coefficients
  //   flag=2: calibration coefficients equal to inverse decalibration ones
  // Author: Boris Polishchuk (Boris.Polichtchouk at cern.ch)

  TString DBFolder;
  Int_t firstRun   =  0;
  Int_t lastRun    =  0;
  Int_t beamPeriod =  1;
  char* objFormat  = "";

  AliPHOSCalibData* cdb = 0;

  if      (flag == 0) {
    DBFolder  ="local://InitCalibDB";
    firstRun  =  0;
    lastRun   =  0;
    objFormat = "PHOS initial pedestals and ADC gain factors (5x64x56)";
    cdb = new AliPHOSCalibData();
    cdb->CreateNew();
  }

  else if (flag == 1) {
    DBFolder  ="local://DeCalibDB";
    firstRun  =  100;
    lastRun   =  100;
    objFormat = "PHOS decalibration pedestals and ADC gain factors (5x64x56)";

    cdb = new AliPHOSCalibData();
    cdb->RandomEmc();
    cdb->RandomCpv();
  }

  else if (flag == 2) {
    // First read decalibration DB
    AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
    AliCDBManager::Instance()->SetSpecificStorage("PHOS","local://DeCalibDB");
    AliPHOSCalibData* cdbDecalib = new AliPHOSCalibData(100);

    DBFolder  ="local://InverseCalibDB";
    firstRun  = 200;
    lastRun   = 200;
    objFormat = "PHOS calibration parameters equal to inverse decalibration ones (5x64x56)";
    cdb = new AliPHOSCalibData();

    // Read EMC decalibration parameters and put inverse values to a new artificial CDB

    for (Int_t module=1; module<=nMod; module++) {
      for (Int_t column=1; column<=nCol; column++) {
	for (Int_t row=1; row<=nRow; row++) {
	  Float_t valueGain = cdbDecalib->GetADCchannelEmc (module,column,row);
	  Float_t valuePed  = cdbDecalib->GetADCpedestalEmc(module,column,row);
	  cdb->SetADCchannelEmc(module,column,row,1./valueGain);
	  cdb->SetADCpedestalEmc(module,column,row,valuePed);
	}
      }
    }

    // Read CPV decalibration parameters and put inverse values to a new artificial CDB

    for (Int_t module=1; module<=nMod; module++) {
      for (Int_t column=1; column<=nCol*2; column++) {
	for (Int_t row=1; row<=nRow; row++) {
	  Float_t valueGain = cdbDecalib->GetADCchannelCpv (module,column,row);
	  Float_t valuePed  = cdbDecalib->GetADCpedestalCpv(module,column,row);
	  cdb->SetADCchannelCpv(module,column,row,1./valueGain);
	  cdb->SetADCpedestalCpv(module,column,row,valuePed);
	}
      }
    }
  }
  else if (flag == 3) {
    DBFolder  ="local://ResidualCalibDB";
    firstRun  =  0;
    lastRun   =  999999;
    objFormat = "PHOS residual ADC gain factors (5x64x56)";

    cdb = new AliPHOSCalibData();
    cdb->RandomEmc(0.98,1.02);
    cdb->RandomCpv(0.00115,0.00125);
  }

  //Store calibration data into database

  AliCDBMetaData md;
  md.SetComment(objFormat);
  md.SetBeamPeriod(beamPeriod);
  md.SetResponsible("Boris Polichtchouk");

  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
  AliCDBManager::Instance()->SetSpecificStorage("PHOS",DBFolder.Data());

  cdb->WriteEmc(firstRun,lastRun,&md);
  cdb->WriteCpv(firstRun,lastRun,&md);

}

//------------------------------------------------------------------------
void GetCC(Int_t flag=0)
{
  // Read calibration coefficients into the Calibration DB
  // Arguments:
  //   flag=0: all calibration coefficients are equal
  //   flag=1: decalibration coefficients
  //   flag=2: calibration coefficients equal to inverse decalibration ones
  // Author: Yuri.Kharlov at cern.ch

  TString DBFolder;
  Int_t runNumber;

  if      (flag == 0) {
    DBFolder  ="local://InitCalibDB";
    runNumber = 0;
  }
  else if (flag == 1) {
    DBFolder  ="local://DeCalibDB";
    runNumber = 100;
  }
  else if (flag == 2) {
    DBFolder  ="local://InverseCalibDB";
    runNumber = 200;
  }
  else if (flag == 2) {
    DBFolder  ="local://ResidualCalibDB";
    runNumber = 0;
  }

  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
  AliCDBManager::Instance()->SetSpecificStorage("PHOS",DBFolder.Data());

  AliPHOSCalibData* clb  = new AliPHOSCalibData(runNumber);

  TH2::AddDirectory(kFALSE);

  TH2F* hPed[5];
  TH2F* hGain[5];

  TCanvas *cPed  = new TCanvas("cPed" ,"PHOS EMC Pedestals"   , 10,10,400,800);
  TCanvas *cGain = new TCanvas("cGain","PHOS EMC Gain factors",410,10,400,800);
  cPed ->Divide(1,5);
  cGain->Divide(1,5);

  for (Int_t module=1; module<=nMod; module++) {
    TString namePed="hPed";
    namePed+=module;
    TString titlePed="Pedestals in module ";
    titlePed+=module;
    hPed[module-1] = new TH2F(namePed.Data(),titlePed.Data(),
			    nCol,1.,1.*nCol,nRow,1.,1.*nRow);

    TString nameGain="hGain";
    nameGain+=module;
    TString titleGain="Gain factors in module ";
    titleGain+=module;
    hGain[module-1] = new TH2F(nameGain.Data(),titleGain.Data(),
			    nCol,1.,1.*nCol,nRow,1.,1.*nRow);

    for (Int_t column=1; column<=nCol; column++) {
      for (Int_t row=1; row<=nRow; row++) {
	Float_t ped  = clb->GetADCpedestalEmc(module,column,row);
	Float_t gain = clb->GetADCchannelEmc (module,column,row);
	hPed[module-1]->SetBinContent(column,row,ped);
	hGain[module-1]->SetBinContent(column,row,gain);
      }
    }
    cPed ->cd(module);
    hPed[module-1]->Draw("lego2");
    cGain->cd(module);
    hGain[module-1]->Draw("lego2");
  }
  cPed ->Print("pedestals.eps");
  cGain->Print("gains.eps");
}
<commit_msg>Update specific storage and run range<commit_after>/* $Id$ */

// Script to create calibration parameters and store them into CDB
// Two sets of calibration parameters can be created:
// 1) equal parameters
// 2) randomly distributed parameters for decalibrated detector silumations

#if !defined(__CINT__)
#include "TControlBar.h"
#include "TString.h"
#include "TRandom.h"
#include "TH2F.h"
#include "TCanvas.h"

#include "AliRun.h"
#include "AliPHOSCalibData.h"
#include "AliCDBMetaData.h"
#include "AliCDBId.h"
#include "AliCDBEntry.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#endif

static const Int_t nMod =  5;
static const Int_t nCol = 56;
static const Int_t nRow = 64;

void AliPHOSSetCDB()
{
  TControlBar *menu = new TControlBar("vertical","PHOS CDB");
  menu->AddButton("Help to run PHOS CDB","Help()",
		  "Explains how to use PHOS CDS menus");
  menu->AddButton("Equal CC","SetCC(0)",
		  "Set equal calibration coefficients");
  menu->AddButton("Decalibrate","SetCC(1)",
		  "Set random decalibration calibration coefficients");
  menu->AddButton("Set calibration equal to invers decalibration coefficients","SetCC(2)",
		  "Set calibration coefficients inverse to decalibration ones");
  menu->AddButton("Residual calibration","SetCC(3)",
		  "Set residual decalibration calibration coefficients");

  menu->AddButton("Read equal CC","GetCC(0)",
		  "Read initial equal calibration coefficients");
  menu->AddButton("Read random CC","GetCC(1)",
		  "Read random decalibration calibration coefficients");
  menu->AddButton("Read inverse CC","GetCC(2)",
		  "Read calibration coefficients inverse to decalibration ones");
  menu->AddButton("Read residual CC","GetCC(3)",
		  "Read residial calibration coefficients");
  menu->Show();
}

//------------------------------------------------------------------------
void Help()
{
  char *string =
    "\nSet calibration parameters and write them into ALICE CDB.
Press button \"Equal CC\" to create equal pedestals and gain factors.
Press button \"Decalibrate\" to create random pedestals and gain factors to imitate decalibrated detector\n";
  printf(string);
}

//------------------------------------------------------------------------
void SetCC(Int_t flag=0)
{
  // Writing calibration coefficients into the Calibration DB
  // Arguments:
  //   flag=0: all calibration coefficients are equal
  //   flag=1: decalibration coefficients
  //   flag=2: calibration coefficients equal to inverse decalibration ones
  // Author: Boris Polishchuk (Boris.Polichtchouk at cern.ch)

  TString DBFolder;
  Int_t firstRun   =  0;
  Int_t lastRun    =  0;
  Int_t beamPeriod =  1;
  char* objFormat  = "";

  AliPHOSCalibData* cdb = 0;

  if      (flag == 0) {
    DBFolder  ="local://InitCalibDB";
    firstRun  =  0;
    lastRun   =  999999;
    objFormat = "PHOS initial pedestals and ADC gain factors (5x64x56)";
    cdb = new AliPHOSCalibData();
    cdb->CreateNew();
  }

  else if (flag == 1) {
    DBFolder  ="local://DeCalibDB";
    firstRun  =  0;
    lastRun   =  999999;
    objFormat = "PHOS decalibration pedestals and ADC gain factors (5x64x56)";

    cdb = new AliPHOSCalibData();
    cdb->RandomEmc();
    cdb->RandomCpv();
  }

  else if (flag == 2) {
    // First read decalibration DB
    AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
    AliCDBManager::Instance()->SetSpecificStorage("PHOS/*","local://DeCalibDB");
    AliPHOSCalibData* cdbDecalib = new AliPHOSCalibData(100);

    DBFolder  ="local://InverseCalibDB";
    firstRun  = 0;
    lastRun   = 999999;
    objFormat = "PHOS calibration parameters equal to inverse decalibration ones (5x64x56)";
    cdb = new AliPHOSCalibData();

    // Read EMC decalibration parameters and put inverse values to a new artificial CDB

    for (Int_t module=1; module<=nMod; module++) {
      for (Int_t column=1; column<=nCol; column++) {
	for (Int_t row=1; row<=nRow; row++) {
	  Float_t valueGain = cdbDecalib->GetADCchannelEmc (module,column,row);
	  Float_t valuePed  = cdbDecalib->GetADCpedestalEmc(module,column,row);
	  cdb->SetADCchannelEmc(module,column,row,1./valueGain);
	  cdb->SetADCpedestalEmc(module,column,row,valuePed);
	}
      }
    }

    // Read CPV decalibration parameters and put inverse values to a new artificial CDB

    for (Int_t module=1; module<=nMod; module++) {
      for (Int_t column=1; column<=nCol*2; column++) {
	for (Int_t row=1; row<=nRow; row++) {
	  Float_t valueGain = cdbDecalib->GetADCchannelCpv (module,column,row);
	  Float_t valuePed  = cdbDecalib->GetADCpedestalCpv(module,column,row);
	  cdb->SetADCchannelCpv(module,column,row,1./valueGain);
	  cdb->SetADCpedestalCpv(module,column,row,valuePed);
	}
      }
    }
  }
  else if (flag == 3) {
    DBFolder  ="local://ResidualCalibDB";
    firstRun  =  0;
    lastRun   =  999999;
    objFormat = "PHOS residual ADC gain factors (5x64x56)";

    cdb = new AliPHOSCalibData();
    cdb->RandomEmc(0.98,1.02);
    cdb->RandomCpv(0.00115,0.00125);
  }

  //Store calibration data into database

  AliCDBMetaData md;
  md.SetComment(objFormat);
  md.SetBeamPeriod(beamPeriod);
  md.SetResponsible("Boris Polichtchouk");

  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
  AliCDBManager::Instance()->SetSpecificStorage("PHOS/*",DBFolder.Data());

  cdb->WriteEmc(firstRun,lastRun,&md);
  cdb->WriteCpv(firstRun,lastRun,&md);

}

//------------------------------------------------------------------------
void GetCC(Int_t flag=0)
{
  // Read calibration coefficients into the Calibration DB
  // Arguments:
  //   flag=0: all calibration coefficients are equal
  //   flag=1: decalibration coefficients
  //   flag=2: calibration coefficients equal to inverse decalibration ones
  // Author: Yuri.Kharlov at cern.ch

  TString DBFolder;
  Int_t runNumber;

  if      (flag == 0) {
    DBFolder  ="local://InitCalibDB";
    runNumber = 0;
  }
  else if (flag == 1) {
    DBFolder  ="local://DeCalibDB";
    runNumber = 100;
  }
  else if (flag == 2) {
    DBFolder  ="local://InverseCalibDB";
    runNumber = 200;
  }
  else if (flag == 2) {
    DBFolder  ="local://ResidualCalibDB";
    runNumber = 0;
  }

  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
  AliCDBManager::Instance()->SetSpecificStorage("PHOS/*",DBFolder.Data());

  AliPHOSCalibData* clb  = new AliPHOSCalibData(runNumber);

  TH2::AddDirectory(kFALSE);

  TH2F* hPed[5];
  TH2F* hGain[5];

  TCanvas *cPed  = new TCanvas("cPed" ,"PHOS EMC Pedestals"   , 10,10,400,800);
  TCanvas *cGain = new TCanvas("cGain","PHOS EMC Gain factors",410,10,400,800);
  cPed ->Divide(1,5);
  cGain->Divide(1,5);

  for (Int_t module=1; module<=nMod; module++) {
    TString namePed="hPed";
    namePed+=module;
    TString titlePed="Pedestals in module ";
    titlePed+=module;
    hPed[module-1] = new TH2F(namePed.Data(),titlePed.Data(),
			    nCol,1.,1.*nCol,nRow,1.,1.*nRow);

    TString nameGain="hGain";
    nameGain+=module;
    TString titleGain="Gain factors in module ";
    titleGain+=module;
    hGain[module-1] = new TH2F(nameGain.Data(),titleGain.Data(),
			    nCol,1.,1.*nCol,nRow,1.,1.*nRow);

    for (Int_t column=1; column<=nCol; column++) {
      for (Int_t row=1; row<=nRow; row++) {
	Float_t ped  = clb->GetADCpedestalEmc(module,column,row);
	Float_t gain = clb->GetADCchannelEmc (module,column,row);
	hPed[module-1]->SetBinContent(column,row,ped);
	hGain[module-1]->SetBinContent(column,row,gain);
      }
    }
    cPed ->cd(module);
    hPed[module-1]->Draw("lego2");
    cGain->cd(module);
    hGain[module-1]->Draw("lego2");
  }
  cPed ->Print("pedestals.eps");
  cGain->Print("gains.eps");
}
<|endoftext|>


<commit_before>void AddTask_Material(  TString   V0ReaderEventCutNumber      = "00000003",
                        TString   V0ReaderPhotonCutNumber     = "060000084001001500000000",
                        TString   TaskEventCutnumber          = "00000003",
                        TString   TaskPhotonCutnumber         = "090000092663743800000000",
                        Bool_t    isMC                        = kFALSE,
                        Int_t     IsHeavyIon                  = 0,
                        TString   cutnumberAODBranch          = "0000000060084001001500000",
                        Bool_t    doEtaShiftV0Reader          = kFALSE,
                        Bool_t    enableV0findingEffi         = kFALSE,                       // enables V0finding efficiency histograms
                        Bool_t    enableConstructGamma        = kFALSE
                    ){

  // ================== GetAnalysisManager ===============================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error(Form("AddTask_GammaConvV1_%i",trainConfig), "No analysis manager found.");
    return ;
  }

  // ================== GetInputEventHandler =============================
  AliVEventHandler *inputHandler=mgr->GetInputEventHandler();

  //========= Add PID Reponse to ANALYSIS manager ====
  if(!(AliPIDResponse*)mgr->GetTask("PIDResponseTask")){
    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C");
    AddTaskPIDResponse(isMC);
  }
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
    TString V0ReaderName = Form("V0ReaderV1_%s_%s",cutnumberEvent.Data(),cutnumberPhoton.Data());
    if( !(AliV0ReaderV1*)mgr->GetTask(V0ReaderName.Data()) ){
        AliV0ReaderV1 *fV0ReaderV1 = new AliV0ReaderV1(V0ReaderName.Data());

    fV0ReaderV1->SetUseOwnXYZCalculation(kTRUE);
    fV0ReaderV1->SetCreateAODs(kFALSE);// AOD Output
    fV0ReaderV1->SetUseAODConversionPhoton(kTRUE);
    fV0ReaderV1->SetProduceV0FindingEfficiency(enableV0findingEffi);
    fV0ReaderV1->SetUseConstructGamma(enableConstructGamma);
    if (!mgr) {
      Error("AddTask_V0ReaderV1", "No analysis manager found.");
      return;
    }

    AliConvEventCuts *fEventCuts=NULL;
    if(V0ReaderEventCutNumber!=""){
      fEventCuts= new AliConvEventCuts(V0ReaderEventCutNumber.Data(),V0ReaderEventCutNumber.Data());
      fEventCuts->SetPreSelectionCutFlag(kTRUE);
            fEventCuts->SetV0ReaderName(V0ReaderName);
      if(fEventCuts->InitializeCutsFromCutString(V0ReaderEventCutNumber.Data())){
        fV0ReaderV1->SetEventCuts(fEventCuts);
        fEventCuts->SetFillCutHistograms("",kTRUE);
        if (IsHeavyIon==2){
          fEventCuts->SelectCollisionCandidates(AliVEvent::kINT7);
          fEventCuts->DoEtaShift(doEtaShiftV0Reader);
        }
      }
    }

    // Set AnalysisCut Number
    AliConversionPhotonCuts *fCuts=NULL;
    if(V0ReaderPhotonCutNumber!=""){
      fCuts= new AliConversionPhotonCuts(V0ReaderPhotonCutNumber.Data(),V0ReaderPhotonCutNumber.Data());
      fCuts->SetPreSelectionCutFlag(kTRUE);
      fCuts->SetIsHeavyIon(IsHeavyIon);
      fCuts->SetV0ReaderName(V0ReaderName);
      if(fCuts->InitializeCutsFromCutString(V0ReaderPhotonCutNumber.Data())){
        fV0ReaderV1->SetConversionCuts(fCuts);
        fCuts->SetFillCutHistograms("",kTRUE);
      }
    }

    if(inputHandler->IsA()==AliAODInputHandler::Class()){
      // AOD mode
      fV0ReaderV1->SetDeltaAODBranchName(Form("GammaConv_%s_gamma",cutnumberAODBranch.Data()));
    }
    fV0ReaderV1->Init();

    AliLog::SetGlobalLogLevel(AliLog::kInfo);

    //connect input V0Reader
    mgr->AddTask(fV0ReaderV1);
    mgr->ConnectInput(fV0ReaderV1,0,cinput);

  } else {
    Error("AddTask_V0ReaderV1", "Cannot execute AddTask, V0ReaderV1 already exists.");
  }

  AliConvEventCuts *analysisEventCuts = new AliConvEventCuts();
  analysisEventCuts->SetV0ReaderName(V0ReaderName);
  analysisEventCuts->InitializeCutsFromCutString(TaskEventCutnumber.Data());
  analysisEventCuts->SetFillCutHistograms("",kFALSE);

  AliConversionPhotonCuts *analysisCuts = new AliConversionPhotonCuts();
  analysisCuts->SetV0ReaderName(V0ReaderName);
  analysisCuts->InitializeCutsFromCutString(TaskPhotonCutnumber.Data());
  analysisCuts->SetFillCutHistograms("",kFALSE);

  AliAnalysisTaskMaterial *fMaterial= new AliAnalysisTaskMaterial(Form("%s_%s_Material",(analysisEventCuts->GetCutNumber()).Data(),(analysisCuts->GetCutNumber()).Data()));
  fMaterial->SetEventCuts(analysisEventCuts,IsHeavyIon);
  fMaterial->SetConversionCuts(analysisCuts,IsHeavyIon);
  fMaterial->SetIsMC(isMC);
  fMaterial->SetV0ReaderName(V0ReaderName);
  mgr->AddTask(fMaterial);

  AliAnalysisDataContainer *coutput1 =
  mgr->CreateContainer(Form("GammaConvMaterial_%s_%s",TaskEventCutnumber.Data(),TaskPhotonCutnumber.Data()), TList::Class(), AliAnalysisManager::kOutputContainer,Form("GammaConv_Material_%s_%s.root",TaskEventCutnumber.Data(),TaskPhotonCutnumber.Data()));

  AliAnalysisDataContainer *cinput1  = mgr->GetCommonInputContainer();
  mgr->ConnectInput(fMaterial,  0, cinput1 );
  mgr->ConnectOutput (fMaterial,  1, coutput1);
  //connect containers
  return;
}
<commit_msg>PWGGA/GammaConv/macro: fixed names cut string<commit_after>void AddTask_Material(  TString   V0ReaderEventCutNumber      = "00000003",
                        TString   V0ReaderPhotonCutNumber     = "060000084001001500000000",
                        TString   TaskEventCutnumber          = "00000003",
                        TString   TaskPhotonCutnumber         = "090000092663743800000000",
                        Bool_t    isMC                        = kFALSE,
                        Int_t     IsHeavyIon                  = 0,
                        TString   cutnumberAODBranch          = "0000000060084001001500000",
                        Bool_t    doEtaShiftV0Reader          = kFALSE,
                        Bool_t    enableV0findingEffi         = kFALSE,                       // enables V0finding efficiency histograms
                        Bool_t    enableConstructGamma        = kFALSE
                    ){

  // ================== GetAnalysisManager ===============================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error(Form("AddTask_GammaConvV1_%i",trainConfig), "No analysis manager found.");
    return ;
  }

  // ================== GetInputEventHandler =============================
  AliVEventHandler *inputHandler=mgr->GetInputEventHandler();

  //========= Add PID Reponse to ANALYSIS manager ====
  if(!(AliPIDResponse*)mgr->GetTask("PIDResponseTask")){
    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C");
    AddTaskPIDResponse(isMC);
  }
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
    TString V0ReaderName = Form("V0ReaderV1_%s_%s",V0ReaderEventCutNumber.Data(),V0ReaderPhotonCutNumber.Data());
    if( !(AliV0ReaderV1*)mgr->GetTask(V0ReaderName.Data()) ){
        AliV0ReaderV1 *fV0ReaderV1 = new AliV0ReaderV1(V0ReaderName.Data());

    fV0ReaderV1->SetUseOwnXYZCalculation(kTRUE);
    fV0ReaderV1->SetCreateAODs(kFALSE);// AOD Output
    fV0ReaderV1->SetUseAODConversionPhoton(kTRUE);
    fV0ReaderV1->SetProduceV0FindingEfficiency(enableV0findingEffi);
    fV0ReaderV1->SetUseConstructGamma(enableConstructGamma);
    if (!mgr) {
      Error("AddTask_V0ReaderV1", "No analysis manager found.");
      return;
    }

    AliConvEventCuts *fEventCuts=NULL;
    if(V0ReaderEventCutNumber!=""){
      fEventCuts= new AliConvEventCuts(V0ReaderEventCutNumber.Data(),V0ReaderEventCutNumber.Data());
      fEventCuts->SetPreSelectionCutFlag(kTRUE);
            fEventCuts->SetV0ReaderName(V0ReaderName);
      if(fEventCuts->InitializeCutsFromCutString(V0ReaderEventCutNumber.Data())){
        fV0ReaderV1->SetEventCuts(fEventCuts);
        fEventCuts->SetFillCutHistograms("",kTRUE);
        if (IsHeavyIon==2){
          fEventCuts->SelectCollisionCandidates(AliVEvent::kINT7);
          fEventCuts->DoEtaShift(doEtaShiftV0Reader);
        }
      }
    }

    // Set AnalysisCut Number
    AliConversionPhotonCuts *fCuts=NULL;
    if(V0ReaderPhotonCutNumber!=""){
      fCuts= new AliConversionPhotonCuts(V0ReaderPhotonCutNumber.Data(),V0ReaderPhotonCutNumber.Data());
      fCuts->SetPreSelectionCutFlag(kTRUE);
      fCuts->SetIsHeavyIon(IsHeavyIon);
      fCuts->SetV0ReaderName(V0ReaderName);
      if(fCuts->InitializeCutsFromCutString(V0ReaderPhotonCutNumber.Data())){
        fV0ReaderV1->SetConversionCuts(fCuts);
        fCuts->SetFillCutHistograms("",kTRUE);
      }
    }

    if(inputHandler->IsA()==AliAODInputHandler::Class()){
      // AOD mode
      fV0ReaderV1->SetDeltaAODBranchName(Form("GammaConv_%s_gamma",cutnumberAODBranch.Data()));
    }
    fV0ReaderV1->Init();

    AliLog::SetGlobalLogLevel(AliLog::kInfo);

    //connect input V0Reader
    mgr->AddTask(fV0ReaderV1);
    mgr->ConnectInput(fV0ReaderV1,0,cinput);

  } else {
    Error("AddTask_V0ReaderV1", "Cannot execute AddTask, V0ReaderV1 already exists.");
  }

  AliConvEventCuts *analysisEventCuts = new AliConvEventCuts();
  analysisEventCuts->SetV0ReaderName(V0ReaderName);
  analysisEventCuts->InitializeCutsFromCutString(TaskEventCutnumber.Data());
  analysisEventCuts->SetFillCutHistograms("",kFALSE);

  AliConversionPhotonCuts *analysisCuts = new AliConversionPhotonCuts();
  analysisCuts->SetV0ReaderName(V0ReaderName);
  analysisCuts->InitializeCutsFromCutString(TaskPhotonCutnumber.Data());
  analysisCuts->SetFillCutHistograms("",kFALSE);

  AliAnalysisTaskMaterial *fMaterial= new AliAnalysisTaskMaterial(Form("%s_%s_Material",(analysisEventCuts->GetCutNumber()).Data(),(analysisCuts->GetCutNumber()).Data()));
  fMaterial->SetEventCuts(analysisEventCuts,IsHeavyIon);
  fMaterial->SetConversionCuts(analysisCuts,IsHeavyIon);
  fMaterial->SetIsMC(isMC);
  fMaterial->SetV0ReaderName(V0ReaderName);
  mgr->AddTask(fMaterial);

  AliAnalysisDataContainer *coutput1 =
  mgr->CreateContainer(Form("GammaConvMaterial_%s_%s",TaskEventCutnumber.Data(),TaskPhotonCutnumber.Data()), TList::Class(), AliAnalysisManager::kOutputContainer,Form("GammaConv_Material_%s_%s.root",TaskEventCutnumber.Data(),TaskPhotonCutnumber.Data()));

  AliAnalysisDataContainer *cinput1  = mgr->GetCommonInputContainer();
  mgr->ConnectInput(fMaterial,  0, cinput1 );
  mgr->ConnectOutput (fMaterial,  1, coutput1);
  //connect containers
  return;
}
<|endoftext|>


<commit_before>#include <FancyMeshSystem.hpp>

#include <Core/String/StringUtils.hpp>
#include <Core/Tasks/Task.hpp>
#include <Core/Tasks/TaskQueue.hpp>

#include <Engine/RadiumEngine.hpp>
#include <Engine/Entity/Entity.hpp>
#include <Engine/Entity/FrameInfo.hpp>
#include <Engine/Renderer/RenderTechnique/RenderTechnique.hpp>
#include <Engine/Assets/FileData.hpp>
#include <Engine/Assets/GeometryData.hpp>
#include <Engine/Entity/ComponentMessenger.hpp>

#include <FancyMeshComponent.hpp>

namespace FancyMeshPlugin
{

    FancyMeshSystem::FancyMeshSystem()
        : Ra::Engine::System()
    {
    }

    FancyMeshSystem::~FancyMeshSystem()
    {
    }

    void FancyMeshSystem::handleAssetLoading( Ra::Engine::Entity* entity, const Ra::Asset::FileData* fileData )
    {
        auto geomData = fileData->getGeometryData();

        uint id = 0;

        for ( const auto& data : geomData )
        {
            std::string componentName = "FMC_" + entity->getName() + std::to_string( id );
            FancyMeshComponent * comp = new FancyMeshComponent( componentName );
            entity->addComponent( comp );
            comp->handleMeshLoading(data);
            registerComponent( entity, comp );
        }
    }

    void FancyMeshSystem::generateTasks( Ra::Core::TaskQueue* taskQueue, const Ra::Engine::FrameInfo& frameInfo )
    {
        // Do nothing, as this system only displays meshes.
    }

    FancyMeshComponent* FancyMeshSystem::makeFancyMeshFromGeometry(
                    const Ra::Core::TriangleMesh& mesh, const std::string& name,
                    Ra::Engine::RenderTechnique* technique )
    {
        FancyMeshComponent* comp = new FancyMeshComponent(name);
        if ( technique )
        {
            comp->addMeshRenderObject( mesh, "Mesh RenderObject", technique );
        }
        else
        {
            comp->addMeshRenderObject( mesh, "Mesh RenderObject" );
        }
        return comp;
    }

} // namespace FancyMeshPlugin
<commit_msg>Fixed a crash when multiple objects had the same name<commit_after>#include <FancyMeshSystem.hpp>

#include <Core/String/StringUtils.hpp>
#include <Core/Tasks/Task.hpp>
#include <Core/Tasks/TaskQueue.hpp>

#include <Engine/RadiumEngine.hpp>
#include <Engine/Entity/Entity.hpp>
#include <Engine/Entity/FrameInfo.hpp>
#include <Engine/Renderer/RenderTechnique/RenderTechnique.hpp>
#include <Engine/Assets/FileData.hpp>
#include <Engine/Assets/GeometryData.hpp>
#include <Engine/Entity/ComponentMessenger.hpp>

#include <FancyMeshComponent.hpp>

namespace FancyMeshPlugin
{

    FancyMeshSystem::FancyMeshSystem()
        : Ra::Engine::System()
    {
    }

    FancyMeshSystem::~FancyMeshSystem()
    {
    }

    void FancyMeshSystem::handleAssetLoading( Ra::Engine::Entity* entity, const Ra::Asset::FileData* fileData )
    {
        auto geomData = fileData->getGeometryData();

        uint id = 0;

        for ( const auto& data : geomData )
        {
            std::string componentName = "FMC_" + entity->getName() + std::to_string( id++ );
            FancyMeshComponent * comp = new FancyMeshComponent( componentName );
            entity->addComponent( comp );
            comp->handleMeshLoading(data);
            registerComponent( entity, comp );
        }
    }

    void FancyMeshSystem::generateTasks( Ra::Core::TaskQueue* taskQueue, const Ra::Engine::FrameInfo& frameInfo )
    {
        // Do nothing, as this system only displays meshes.
    }

    FancyMeshComponent* FancyMeshSystem::makeFancyMeshFromGeometry(
                    const Ra::Core::TriangleMesh& mesh, const std::string& name,
                    Ra::Engine::RenderTechnique* technique )
    {
        FancyMeshComponent* comp = new FancyMeshComponent(name);
        if ( technique )
        {
            comp->addMeshRenderObject( mesh, "Mesh RenderObject", technique );
        }
        else
        {
            comp->addMeshRenderObject( mesh, "Mesh RenderObject" );
        }
        return comp;
    }

} // namespace FancyMeshPlugin
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Characters/String.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Containers/Collection.h"
#include "Stroika/Foundation/Containers/SortedCollection.h"
#include "Stroika/Foundation/Debug/Trace.h"

// Not generally included, but you can include these if you want to select a particular backend implementation
#include "Stroika/Foundation/Containers/Concrete/Collection_Array.h"
#include "Stroika/Foundation/Containers/Concrete/Collection_LinkedList.h"
#include "Stroika/Foundation/Containers/Concrete/Collection_stdforward_list.h"

#include "Stroika/Foundation/Debug/Assertions.h"

#include "Collection.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

using Characters::CompareOptions;

namespace {
    void SimplestCollectionTest_ ()
    {
        /*
         *  A Collection is the simplest form of Stroika container. You can add things, and remove them, and iterate over them.
         *  View the class declaration, with all the methods well documented, must with examples of usage.
         */
        Collection<int> c;
        c.Add (3);
        c += 13;
        for ([[maybe_unused]] int i : c) {
            Assert (i == 3 or i == 13);
        }
        Assert (c.size () == 2);
    }
}

namespace {
    void UseParticularConcreteRepresentation_ ()
    {
        {
            Collection<int> c{3, 5, 19, 3040, 34, 1, 33, 33, 4, 19};

            // Unclear what the performance characteristics of this will be - with a linked list - O(1), but with array, O(N) worst case.
            c += 4;

            // 'c' will now operate identically (same API) - but use a differnt backend datastructure for storage,
            // always showing O(1) worst case addition time
            c = Concrete::Collection_stdforward_list<int>{c};
            c += 4;
        }
        {
            using Characters::String;
            Collection<String> fruits;
            fruits += L"apple";
            fruits += L"bananas";
            fruits += L"cherries";
            fruits += L"APPLE";
            // Print (to debugger/tracelog) the fruits - but now they could come out in any order
            DbgTrace (L"fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.size () == 4); // they are all there

            // Like changing the backend. But this still respects all the rules of a Collection (no order specified) -
            // except now it will happen to be ordered (using the default compare function)
            fruits = SortedCollection<String>{fruits};
            DbgTrace (L"sorted fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.size () == 4); // only one apple or the other (case squished)
            // note they must now be in alphabetic order
            Assert (fruits.SequentialEquals (initializer_list<String>{L"APPLE", L"apple", L"bananas", L"cherries"}));

            // But, we can do the same thing with a compare function that sorts case insensitively
            fruits = SortedCollection<String>{String::LessComparer{CompareOptions::eCaseInsensitive}, fruits};
            DbgTrace (L"sorted case insensitve fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.SequentialEquals (initializer_list<String>{L"apple", L"APPLE", L"bananas", L"cherries"}) or
                    fruits.SequentialEquals (initializer_list<String>{L"APPLE", L"apple", L"bananas", L"cherries"}));
        }
    }
}

namespace {
    void InterfaceWithSTLContainers_ ()
    {
        vector<int>     aVector{1, 3, 5, 7, 9, 11};
        Collection<int> c{aVector};

        // CANNOT guarantee the ordering is the same, as Collection guarantees it keeps all the same elements,
        // but does not guarantee maintaining order.
        Assert (c.SetEquals (aVector));
        Assert (c.SequentialEquals (aVector) or not c.SequentialEquals (aVector));

        vector<int> v2 = c.As<vector<int>> ();
        // V will contain all the same elements as aVector, but maybe not in the same order.
        // it will be in the order the 'c' collection happened to produce
    }
}

namespace {
    void PrintTheContentsOfAContainerToTheTraceLog_ ()
    {
        /*
         *  Use DbgTrace and Characters::ToString () to echo objects to a tracelog file (and/or debugger output under windows)
         */
        Debug::TraceContextBumper ctx{L"PrintTheContentsOfAContainerToTheTraceLog_"};
        Collection<int>           tmp{1, 3, 5, 7, 9};
        DbgTrace (L"tmp=%s", Characters::ToString (tmp).c_str ());
    }
}

namespace {
    void StoreOtherSortsOfElements_ ()
    {
        Debug::TraceContextBumper ctx{L"StoreOtherSortsOfElements_"};
        using Characters::String;
        Collection<String> fruits;
        fruits += L"apple";
        fruits += L"bananas";
        fruits += L"cherries";
        DbgTrace (L"fruits=%s", Characters::ToString (fruits).c_str ());
    }
}

namespace {
    void UseLinqLikeFunctionalAPIs_ ()
    {
        Debug::TraceContextBumper ctx{L"PrintTheContentsOfAContainerToTheTraceLog_"};
        /*
         *  See the Iterable<> template in Iterable.h - for a ton more of this functional style linq-like operations
         *  you can do on any Stroika container.
         */
        {
            Collection<int> tmp{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            auto            whereTestResult = tmp.Where ([] (int i) { return i % 2 == 1; });
            DbgTrace (L"tmp=%s", Characters::ToString (whereTestResult).c_str ());
        }
        {
            Collection<int> tmp{1, 2, 3, 4, 5, 1, 2, 3, 4, 5};
            auto            d = tmp.Distinct ();
            DbgTrace (L"d=%s", Characters::ToString (d).c_str ());
            Assert (d.SetEquals (initializer_list<int>{1, 2, 3, 4, 5}));
        }
        {
            using Characters::String;
            Collection<String> fruits;
            fruits += L"apple";
            fruits += L"APPLE";
            fruits += L"bananas";
            fruits += L"cherries";
            DbgTrace (L"fruits=%s", Characters::ToString (fruits.Distinct (String::EqualsComparer{CompareOptions::eCaseInsensitive})).c_str ());
            Assert (fruits.Distinct (String::EqualsComparer{CompareOptions::eCaseInsensitive}).size () == 3); // only one apple or the other (case squished)
        }
    }
}

namespace {
    void CollectionOfThingsWithNoOpEqualsAndNotDefaultConstructibleEtc_ ()
    {
        struct MyFunnyObject_ {
            MyFunnyObject_ () = delete; // no need to be default constructible
            MyFunnyObject_ (int /*n*/)
            {
                // need some constructor to test
            }
            MyFunnyObject_ (const MyFunnyObject_&) = default; // OK, but you do need to be copyable
        };
        Collection<MyFunnyObject_> myObjects;
        myObjects.Add (MyFunnyObject_{3});
        myObjects += MyFunnyObject_{4}; // use whatever add syntax you want

        // THIS WONT WORK, because no operator== defined
        //      myObjects.Remove (MyFunnyObject_{3});
        // but this will remove the first object found
        Assert (myObjects.size () == 2);
        myObjects.Remove (MyFunnyObject_{3}, [] (const MyFunnyObject_&, const MyFunnyObject_&) { return true; });
        Assert (myObjects.size () == 1);
    }
}

namespace {
    void IteratorsAndSafeUpdateIteration_ ()
    {
        using Characters::String;
        Collection<String> fruits;
        fruits += L"apple";
        fruits += L"APPLE";
        fruits += L"bananas";
        fruits += L"cherries";

        {
            Iterator<String> i = fruits.FindFirstThat ([] (String i) { return i == L"apple"; });
            Assert (i != fruits.end ());
            Assert (fruits.size () == 4);
        }
        for (Iterator<String> i = fruits.begin (); i != fruits.end (); ++i) {
            if (String::EqualsComparer{CompareOptions::eCaseInsensitive}(*i, L"apple")) {
                fruits.Remove (i);
                // with STL containers, it would be illegal to reference i again, as in i++.
                // However, with Stroika iterators, they are smart about doing the right thing,
                // when they point to a deleted item, and this code will work as expected.
            }
        }
        Assert (fruits.size () == 2);
    }
}

void Samples::Containers::Collection::RunDemo ()
{
    SimplestCollectionTest_ ();
    UseParticularConcreteRepresentation_ ();
    InterfaceWithSTLContainers_ ();
    PrintTheContentsOfAContainerToTheTraceLog_ ();
    StoreOtherSortsOfElements_ ();
    UseLinqLikeFunctionalAPIs_ ();
    CollectionOfThingsWithNoOpEqualsAndNotDefaultConstructibleEtc_ ();
    IteratorsAndSafeUpdateIteration_ ();
}
<commit_msg>fixed issue in Containers sample app violating rules of new container code<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "Stroika/Foundation/StroikaPreComp.h"

#include "Stroika/Foundation/Characters/String.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Containers/Collection.h"
#include "Stroika/Foundation/Containers/SortedCollection.h"
#include "Stroika/Foundation/Debug/Trace.h"

// Not generally included, but you can include these if you want to select a particular backend implementation
#include "Stroika/Foundation/Containers/Concrete/Collection_Array.h"
#include "Stroika/Foundation/Containers/Concrete/Collection_LinkedList.h"
#include "Stroika/Foundation/Containers/Concrete/Collection_stdforward_list.h"

#include "Stroika/Foundation/Debug/Assertions.h"

#include "Collection.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

using Characters::CompareOptions;

namespace {
    void SimplestCollectionTest_ ()
    {
        /*
         *  A Collection is the simplest form of Stroika container. You can add things, and remove them, and iterate over them.
         *  View the class declaration, with all the methods well documented, must with examples of usage.
         */
        Collection<int> c;
        c.Add (3);
        c += 13;
        for ([[maybe_unused]] int i : c) {
            Assert (i == 3 or i == 13);
        }
        Assert (c.size () == 2);
    }
}

namespace {
    void UseParticularConcreteRepresentation_ ()
    {
        {
            Collection<int> c{3, 5, 19, 3040, 34, 1, 33, 33, 4, 19};

            // Unclear what the performance characteristics of this will be - with a linked list - O(1), but with array, O(N) worst case.
            c += 4;

            // 'c' will now operate identically (same API) - but use a differnt backend datastructure for storage,
            // always showing O(1) worst case addition time
            c = Concrete::Collection_stdforward_list<int>{c};
            c += 4;
        }
        {
            using Characters::String;
            Collection<String> fruits;
            fruits += L"apple";
            fruits += L"bananas";
            fruits += L"cherries";
            fruits += L"APPLE";
            // Print (to debugger/tracelog) the fruits - but now they could come out in any order
            DbgTrace (L"fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.size () == 4); // they are all there

            // Like changing the backend. But this still respects all the rules of a Collection (no order specified) -
            // except now it will happen to be ordered (using the default compare function)
            fruits = SortedCollection<String>{fruits};
            DbgTrace (L"sorted fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.size () == 4); // only one apple or the other (case squished)
            // note they must now be in alphabetic order
            Assert (fruits.SequentialEquals (initializer_list<String>{L"APPLE", L"apple", L"bananas", L"cherries"}));

            // But, we can do the same thing with a compare function that sorts case insensitively
            fruits = SortedCollection<String>{String::LessComparer{CompareOptions::eCaseInsensitive}, fruits};
            DbgTrace (L"sorted case insensitve fruits=%s", Characters::ToString (fruits).c_str ());
            Assert (fruits.SequentialEquals (initializer_list<String>{L"apple", L"APPLE", L"bananas", L"cherries"}) or
                    fruits.SequentialEquals (initializer_list<String>{L"APPLE", L"apple", L"bananas", L"cherries"}));
        }
    }
}

namespace {
    void InterfaceWithSTLContainers_ ()
    {
        vector<int>     aVector{1, 3, 5, 7, 9, 11};
        Collection<int> c{aVector};

        // CANNOT guarantee the ordering is the same, as Collection guarantees it keeps all the same elements,
        // but does not guarantee maintaining order.
        Assert (c.SetEquals (aVector));
        Assert (c.SequentialEquals (aVector) or not c.SequentialEquals (aVector));

        vector<int> v2 = c.As<vector<int>> ();
        // V will contain all the same elements as aVector, but maybe not in the same order.
        // it will be in the order the 'c' collection happened to produce
    }
}

namespace {
    void PrintTheContentsOfAContainerToTheTraceLog_ ()
    {
        /*
         *  Use DbgTrace and Characters::ToString () to echo objects to a tracelog file (and/or debugger output under windows)
         */
        Debug::TraceContextBumper ctx{L"PrintTheContentsOfAContainerToTheTraceLog_"};
        Collection<int>           tmp{1, 3, 5, 7, 9};
        DbgTrace (L"tmp=%s", Characters::ToString (tmp).c_str ());
    }
}

namespace {
    void StoreOtherSortsOfElements_ ()
    {
        Debug::TraceContextBumper ctx{L"StoreOtherSortsOfElements_"};
        using Characters::String;
        Collection<String> fruits;
        fruits += L"apple";
        fruits += L"bananas";
        fruits += L"cherries";
        DbgTrace (L"fruits=%s", Characters::ToString (fruits).c_str ());
    }
}

namespace {
    void UseLinqLikeFunctionalAPIs_ ()
    {
        Debug::TraceContextBumper ctx{L"PrintTheContentsOfAContainerToTheTraceLog_"};
        /*
         *  See the Iterable<> template in Iterable.h - for a ton more of this functional style linq-like operations
         *  you can do on any Stroika container.
         */
        {
            Collection<int> tmp{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            auto            whereTestResult = tmp.Where ([] (int i) { return i % 2 == 1; });
            DbgTrace (L"tmp=%s", Characters::ToString (whereTestResult).c_str ());
        }
        {
            Collection<int> tmp{1, 2, 3, 4, 5, 1, 2, 3, 4, 5};
            auto            d = tmp.Distinct ();
            DbgTrace (L"d=%s", Characters::ToString (d).c_str ());
            Assert (d.SetEquals (initializer_list<int>{1, 2, 3, 4, 5}));
        }
        {
            using Characters::String;
            Collection<String> fruits;
            fruits += L"apple";
            fruits += L"APPLE";
            fruits += L"bananas";
            fruits += L"cherries";
            DbgTrace (L"fruits=%s", Characters::ToString (fruits.Distinct (String::EqualsComparer{CompareOptions::eCaseInsensitive})).c_str ());
            Assert (fruits.Distinct (String::EqualsComparer{CompareOptions::eCaseInsensitive}).size () == 3); // only one apple or the other (case squished)
        }
    }
}

namespace {
    void CollectionOfThingsWithNoOpEqualsAndNotDefaultConstructibleEtc_ ()
    {
        struct MyFunnyObject_ {
            MyFunnyObject_ () = delete; // no need to be default constructible
            MyFunnyObject_ (int /*n*/)
            {
                // need some constructor to test
            }
            MyFunnyObject_ (const MyFunnyObject_&) = default; // OK, but you do need to be copyable
        };
        Collection<MyFunnyObject_> myObjects;
        myObjects.Add (MyFunnyObject_{3});
        myObjects += MyFunnyObject_{4}; // use whatever add syntax you want

        // THIS WONT WORK, because no operator== defined
        //      myObjects.Remove (MyFunnyObject_{3});
        // but this will remove the first object found
        Assert (myObjects.size () == 2);
        myObjects.Remove (MyFunnyObject_{3}, [] (const MyFunnyObject_&, const MyFunnyObject_&) { return true; });
        Assert (myObjects.size () == 1);
    }
}

namespace {
    void IteratorsAndSafeUpdateIteration_ ()
    {
        using Characters::String;
        Collection<String> fruits;
        fruits += L"apple";
        fruits += L"APPLE";
        fruits += L"bananas";
        fruits += L"cherries";

        {
            Iterator<String> i = fruits.FindFirstThat ([] (String i) { return i == L"apple"; });
            Assert (i != fruits.end ());
            Assert (fruits.size () == 4);
        }
        for (Iterator<String> i = fruits.begin (); i != fruits.end (); ) {
            if (String::EqualsComparer{CompareOptions::eCaseInsensitive}(*i, L"apple")) {
                fruits.Remove (i, &i);
                // with STL containers, it would be illegal to reference i again, as in i++.
                // However, with Stroika iterators, they are smart about doing the right thing,
                // when they point to a deleted item, and this code will work as expected.
            }
            else {
                i++;
            }
        }
        Assert (fruits.size () == 2);
    }
}

void Samples::Containers::Collection::RunDemo ()
{
    SimplestCollectionTest_ ();
    UseParticularConcreteRepresentation_ ();
    InterfaceWithSTLContainers_ ();
    PrintTheContentsOfAContainerToTheTraceLog_ ();
    StoreOtherSortsOfElements_ ();
    UseLinqLikeFunctionalAPIs_ ();
    CollectionOfThingsWithNoOpEqualsAndNotDefaultConstructibleEtc_ ();
    IteratorsAndSafeUpdateIteration_ ();
}
<|endoftext|>


<commit_before>#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Scene/SceneEvents.h>
#include <Urho3D/SystemUI/SystemUIEvents.h>
#include <Toolbox/SystemUI/AttributeInspector.h>
#include <Toolbox/SystemUI/Gizmo.h>
#include "UndoStack.h"

namespace Urho3D
{

UndoStack::UndoStack(Context* context)
    : Object(context)
{
    SubscribeToEvent(E_ENDFRAME, [this](StringHash, VariantMap&)
    {
        if (!trackingEnabled_ || currentFrameActions_.empty())
            return;

        if (modifiedThisFrame_.NotNull())
        {
            modifiedThisFrame_->SendEvent(E_DOCUMENTMODIFIEDREQUEST);
            modifiedThisFrame_ = nullptr;
        }

        auto time = GetSubsystem<Time>();
        unsigned frame = time->GetFrameNumber();
        for (auto& action : currentFrameActions_)
            action->frame_ = frame;

        stack_.resize(index_);              // Discard unneeded states
        stack_.push_back(currentFrameActions_);
        index_++;
        currentFrameActions_.clear();
        modifiedThisFrame_ = nullptr;
    });
}

void UndoStack::Undo()
{
    bool doneAnything = false;
    while (index_ > 0 && !doneAnything)
    {
        UndoTrackGuard noTrack(this, false);
        workingValueCache_.Clear();
        index_--;
        const auto& actions = stack_[index_];
        for (int i = (int)actions.size() - 1; i >= 0; --i)
        {
            UndoAction* action = actions[i];
            if (action->Undo(context_))
            {
                doneAnything = true;
                action->OnModified(context_);
            }
        }
    }
}

void UndoStack::Redo()
{
    bool doneAnything = false;
    while (index_ < stack_.size() && !doneAnything)
    {
        UndoTrackGuard noTrack(this, false);
        workingValueCache_.Clear();
        for (auto& action : stack_[index_])
        {
            if (action->Redo(context_))
            {
                doneAnything = true;
                action->OnModified(context_);
            }
        }
        index_++;
    }
}

void UndoStack::Clear()
{
    stack_.clear();
    currentFrameActions_.clear();
    index_ = 0;
}

void UndoStack::Connect(Scene* scene, Object* modified)
{
    Connect(static_cast<Object*>(scene), modified);

    SubscribeToEvent(scene, E_NODEADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[NodeAdded::P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoCreateNode>(node);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_NODEREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[NodeRemoved::P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoDeleteNode>(node);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_COMPONENTADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[ComponentAdded::P_NODE].GetPtr());
        auto* component = dynamic_cast<Component*>(args[ComponentAdded::P_COMPONENT].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoCreateComponent>(component);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_COMPONENTREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[ComponentRemoved::P_NODE].GetPtr());
        auto* component = dynamic_cast<Component*>(args[ComponentRemoved::P_COMPONENT].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoDeleteComponent>(component);

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::Connect(Object* inspector, Object* modified)
{
    SubscribeToEvent(inspector, E_ATTRIBUTEINSPECTVALUEMODIFIED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace AttributeInspectorValueModified;
        auto item = dynamic_cast<Serializable*>(args[P_SERIALIZABLE].GetPtr());
        if (Node* node = dynamic_cast<Node*>(item))
        {
            if (node->HasTag("__EDITOR_OBJECT__"))
                return;
        }

        const auto& name = reinterpret_cast<AttributeInfo*>(args[P_ATTRIBUTEINFO].GetVoidPtr())->name_;
        const auto& oldValue = args[P_OLDVALUE];
        const auto& newValue = item->GetAttribute(name);
        if (oldValue != newValue)
        {
            // Dummy attributes are used for rendering custom inspector widgets that do not map to Variant values.
            // These dummy values are not modified, however inspector event is still useful for tapping into their
            // modifications. State tracking for these dummy values is not needed and would introduce extra ctrl+z
            // presses that do nothing.
            Add<UndoEditAttribute>(item, name, oldValue, newValue);

            SetModifiedObject(modifiedPtr);
        }
    });
}

void UndoStack::Connect(UIElement* root, Object* modified)
{
    assert(root->IsElementEventSender());

    Connect(static_cast<Object*>(root), modified);

    SubscribeToEvent(root, E_ELEMENTADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace ElementAdded;
        Add<UndoCreateUIElement>(dynamic_cast<UIElement*>(args[P_ELEMENT].GetPtr()));

        SetModifiedObject(modifiedPtr);
    });
    SubscribeToEvent(root, E_ELEMENTREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace ElementRemoved;
        Add<UndoDeleteUIElement>(dynamic_cast<UIElement*>(args[P_ELEMENT].GetPtr()));

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::Connect(Gizmo* gizmo, Object* modified)
{
    SubscribeToEvent(gizmo, E_GIZMONODEMODIFIED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace GizmoNodeModified;
        auto node = dynamic_cast<Node*>(args[P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        const auto& oldTransform = args[P_OLDTRANSFORM].GetMatrix3x4();
        const auto& newTransform = args[P_NEWTRANSFORM].GetMatrix3x4();

        Add<UndoEditAttribute>(node, "Position", oldTransform.Translation(), newTransform.Translation());
        Add<UndoEditAttribute>(node, "Rotation", oldTransform.Rotation(), newTransform.Rotation());
        Add<UndoEditAttribute>(node, "Scale", oldTransform.Scale(), newTransform.Scale());

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::SetModifiedObject(Object* modified)
{
    if (modified == nullptr)
        return;

    if (modifiedThisFrame_.Null())
        modifiedThisFrame_ = modified;
    else
    {
        // We definitely do not want to modify multiple tabs with one action. Guard against it.
        assert(modifiedThisFrame_ == modified);
    }
}

}
<commit_msg>Toolbox: Execute OnModified() when saving actions to undo stack. If we have actions to save - state was modified.<commit_after>#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Scene/SceneEvents.h>
#include <Urho3D/SystemUI/SystemUIEvents.h>
#include <Toolbox/SystemUI/AttributeInspector.h>
#include <Toolbox/SystemUI/Gizmo.h>
#include "UndoStack.h"

namespace Urho3D
{

UndoStack::UndoStack(Context* context)
    : Object(context)
{
    SubscribeToEvent(E_ENDFRAME, [this](StringHash, VariantMap&)
    {
        if (!trackingEnabled_ || currentFrameActions_.empty())
            return;

        if (modifiedThisFrame_.NotNull())
        {
            modifiedThisFrame_->SendEvent(E_DOCUMENTMODIFIEDREQUEST);
            modifiedThisFrame_ = nullptr;
        }

        auto time = GetSubsystem<Time>();
        unsigned frame = time->GetFrameNumber();
        for (auto& action : currentFrameActions_)
            action->frame_ = frame;

        stack_.resize(index_);              // Discard unneeded states
        stack_.push_back(currentFrameActions_);
        index_++;
        for (UndoAction* action : currentFrameActions_)
            action->OnModified(context_);
        currentFrameActions_.clear();
        modifiedThisFrame_ = nullptr;
    });
}

void UndoStack::Undo()
{
    bool doneAnything = false;
    while (index_ > 0 && !doneAnything)
    {
        UndoTrackGuard noTrack(this, false);
        workingValueCache_.Clear();
        index_--;
        const auto& actions = stack_[index_];
        for (int i = (int)actions.size() - 1; i >= 0; --i)
        {
            UndoAction* action = actions[i];
            if (action->Undo(context_))
            {
                doneAnything = true;
                action->OnModified(context_);
            }
        }
    }
}

void UndoStack::Redo()
{
    bool doneAnything = false;
    while (index_ < stack_.size() && !doneAnything)
    {
        UndoTrackGuard noTrack(this, false);
        workingValueCache_.Clear();
        for (auto& action : stack_[index_])
        {
            if (action->Redo(context_))
            {
                doneAnything = true;
                action->OnModified(context_);
            }
        }
        index_++;
    }
}

void UndoStack::Clear()
{
    stack_.clear();
    currentFrameActions_.clear();
    index_ = 0;
}

void UndoStack::Connect(Scene* scene, Object* modified)
{
    Connect(static_cast<Object*>(scene), modified);

    SubscribeToEvent(scene, E_NODEADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[NodeAdded::P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoCreateNode>(node);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_NODEREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[NodeRemoved::P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoDeleteNode>(node);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_COMPONENTADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[ComponentAdded::P_NODE].GetPtr());
        auto* component = dynamic_cast<Component*>(args[ComponentAdded::P_COMPONENT].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoCreateComponent>(component);

        SetModifiedObject(modifiedPtr);
    });

    SubscribeToEvent(scene, E_COMPONENTREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        auto* node = dynamic_cast<Node*>(args[ComponentRemoved::P_NODE].GetPtr());
        auto* component = dynamic_cast<Component*>(args[ComponentRemoved::P_COMPONENT].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        Add<UndoDeleteComponent>(component);

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::Connect(Object* inspector, Object* modified)
{
    SubscribeToEvent(inspector, E_ATTRIBUTEINSPECTVALUEMODIFIED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace AttributeInspectorValueModified;
        auto item = dynamic_cast<Serializable*>(args[P_SERIALIZABLE].GetPtr());
        if (Node* node = dynamic_cast<Node*>(item))
        {
            if (node->HasTag("__EDITOR_OBJECT__"))
                return;
        }

        const auto& name = reinterpret_cast<AttributeInfo*>(args[P_ATTRIBUTEINFO].GetVoidPtr())->name_;
        const auto& oldValue = args[P_OLDVALUE];
        const auto& newValue = item->GetAttribute(name);
        if (oldValue != newValue)
        {
            // Dummy attributes are used for rendering custom inspector widgets that do not map to Variant values.
            // These dummy values are not modified, however inspector event is still useful for tapping into their
            // modifications. State tracking for these dummy values is not needed and would introduce extra ctrl+z
            // presses that do nothing.
            Add<UndoEditAttribute>(item, name, oldValue, newValue);

            SetModifiedObject(modifiedPtr);
        }
    });
}

void UndoStack::Connect(UIElement* root, Object* modified)
{
    assert(root->IsElementEventSender());

    Connect(static_cast<Object*>(root), modified);

    SubscribeToEvent(root, E_ELEMENTADDED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace ElementAdded;
        Add<UndoCreateUIElement>(dynamic_cast<UIElement*>(args[P_ELEMENT].GetPtr()));

        SetModifiedObject(modifiedPtr);
    });
    SubscribeToEvent(root, E_ELEMENTREMOVED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace ElementRemoved;
        Add<UndoDeleteUIElement>(dynamic_cast<UIElement*>(args[P_ELEMENT].GetPtr()));

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::Connect(Gizmo* gizmo, Object* modified)
{
    SubscribeToEvent(gizmo, E_GIZMONODEMODIFIED, [this, modifiedPtr=WeakPtr(modified)](StringHash, VariantMap& args)
    {
        if (!trackingEnabled_)
            return;
        using namespace GizmoNodeModified;
        auto node = dynamic_cast<Node*>(args[P_NODE].GetPtr());
        if (node->HasTag("__EDITOR_OBJECT__"))
            return;
        const auto& oldTransform = args[P_OLDTRANSFORM].GetMatrix3x4();
        const auto& newTransform = args[P_NEWTRANSFORM].GetMatrix3x4();

        Add<UndoEditAttribute>(node, "Position", oldTransform.Translation(), newTransform.Translation());
        Add<UndoEditAttribute>(node, "Rotation", oldTransform.Rotation(), newTransform.Rotation());
        Add<UndoEditAttribute>(node, "Scale", oldTransform.Scale(), newTransform.Scale());

        SetModifiedObject(modifiedPtr);
    });
}

void UndoStack::SetModifiedObject(Object* modified)
{
    if (modified == nullptr)
        return;

    if (modifiedThisFrame_.Null())
        modifiedThisFrame_ = modified;
    else
    {
        // We definitely do not want to modify multiple tabs with one action. Guard against it.
        assert(modifiedThisFrame_ == modified);
    }
}

}
<|endoftext|>


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

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

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

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

=========================================================================*/
#include <iostream>

#include "vnl/vnl_matrix.h"
#include <vnl/algo/vnl_svd.h>

template <typename T>
void print_vnl_matrix(T& mat)
{
  std::cout << mat;
  for(unsigned int r = 0; r < mat.rows(); r++)
    {
    for(unsigned int c = 0; c < mat.rows(); c++)
      std::cout << mat(r, c) << " ";
    std::cout << std::endl;
    }
}

template <class D>  // D is often double or float
vnl_matrix<D> solve_with_warning(vnl_matrix<D>const& M,
         vnl_matrix<D>const& B)
{
  // Take svd of vnl_matrix<D> M, setting singular values
  // smaller than 1e-8 to 0, and hold the result.
  vnl_svd<D> svd(M, 1e-8);
  // Check for rank-deficiency
  if (svd.singularities() > 1)
    std::cout << "Warning: Singular matrix, condition = " << svd.well_condition() << std::endl;
  return svd.solve(B);
}

int test_svd() {
  double data[] = { 1, 1, 1,  1, 2, 3,  1, 3, 6};
  vnl_matrix<double> M (data, 3, 3);
  vnl_matrix<double> B (3, 1, 7.0); // column vector [7 7 7]^T
  vnl_matrix<double> result = solve_with_warning(M,B);
  std::cout << "Original svd problem solution" << std::endl;
  print_vnl_matrix(result);
  M(2,2)=5; result = solve_with_warning(M,B);
  std::cout << std::endl << "Modified svd problem solution" << std::endl;
  print_vnl_matrix(result);
  return 0;
}

int main()
{
  test_svd();
  double data[] = { 1, 1, 1,  1, 2, 3,  1, 3, 6};
  vnl_matrix<double> mat(data, 3, 3);
  std::cout << std::endl << "A matrix" << std::endl;
  for(unsigned int r = 0; r < mat.rows(); r++)
    {
    for(unsigned int c = 0; c < mat.rows(); c++)
      {
      std::cout << mat(r, c) << " ";
      }
    std::cout << std::endl;
    }

  return 0;
}

<commit_msg>ERR: rows -> columns in inner loop of print. Was causing a Puriry ABR.<commit_after>/*=========================================================================

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

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

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

=========================================================================*/
#include <iostream>

#include "vnl/vnl_matrix.h"
#include <vnl/algo/vnl_svd.h>

template <typename T>
void print_vnl_matrix(T& mat)
{
  std::cout << mat;
  for(unsigned int r = 0; r < mat.rows(); r++)
    {
    for(unsigned int c = 0; c < mat.columns(); c++)
      std::cout << mat(r, c) << " ";
    std::cout << std::endl;
    }
}

template <class D>  // D is often double or float
vnl_matrix<D> solve_with_warning(vnl_matrix<D>const& M,
         vnl_matrix<D>const& B)
{
  // Take svd of vnl_matrix<D> M, setting singular values
  // smaller than 1e-8 to 0, and hold the result.
  vnl_svd<D> svd(M, 1e-8);
  // Check for rank-deficiency
  if (svd.singularities() > 1)
    std::cout << "Warning: Singular matrix, condition = " << svd.well_condition() << std::endl;
  return svd.solve(B);
}

int test_svd() {
  double data[] = { 1, 1, 1,  1, 2, 3,  1, 3, 6};
  vnl_matrix<double> M (data, 3, 3);
  vnl_matrix<double> B (3, 1, 7.0); // column vector [7 7 7]^T
  vnl_matrix<double> result = solve_with_warning(M,B);
  std::cout << "Original svd problem solution" << std::endl;
  print_vnl_matrix(result);
  M(2,2)=5; result = solve_with_warning(M,B);
  std::cout << std::endl << "Modified svd problem solution" << std::endl;
  print_vnl_matrix(result);
  return 0;
}

int main()
{
  test_svd();
  double data[] = { 1, 1, 1,  1, 2, 3,  1, 3, 6};
  vnl_matrix<double> mat(data, 3, 3);
  std::cout << std::endl << "A matrix" << std::endl;
  for(unsigned int r = 0; r < mat.rows(); r++)
    {
    for(unsigned int c = 0; c < mat.rows(); c++)
      {
      std::cout << mat(r, c) << " ";
      }
    std::cout << std::endl;
    }

  return 0;
}

<|endoftext|>