<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <prewin.h>
#include <postwin.h>
#undef OPTIONAL

#include "vcl/svapp.hxx"
#include "tools/fsys.hxx"
#include "tools/urlobj.hxx"
#include "osl/mutex.hxx"

#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"

#include "plugin/impl.hxx"

#pragma warning (push,1)
#pragma warning (disable:4005)

#include <string.h>
#include <tchar.h>
#include <objbase.h>

#pragma warning (pop)

#include <list>
#include <map>
#include <algorithm>

using namespace std;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::plugin;

using ::rtl::OUString;
using ::rtl::OString;
using ::rtl::OStringToOUString;
using ::rtl::OUStringToOString;

typedef map< OString, OUString, less< OString > > PluginLocationMap;

//__________________________________________________________________________________________________
static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
{
    // append dll name pattern we are looking for
    TCHAR arPluginsPath[MAX_PATH];
    arPluginsPath[0] = 0;

    if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
    {
        const char * p = ::getenv( "ProgramFiles" );
        if (p)
        {
            ::lstrcpy( arPluginsPath, p );
            pPluginsPath += 14;
        }
    }
    ::lstrcat( arPluginsPath, pPluginsPath );
    ::lstrcat( arPluginsPath, _T("\\") );

    TCHAR arPluginsPattern[MAX_PATH];
    ::lstrcpy( arPluginsPattern, arPluginsPath );
    ::lstrcat( arPluginsPattern, _T("NP*.DLL") );

    WIN32_FIND_DATA aFindData;
    HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );

    while (hFind != INVALID_HANDLE_VALUE)
    {
        OString aName = OUString( aFindData.cFileName ).toAsciiLowerCase();

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            TCHAR arComplete[MAX_PATH];
            ::lstrcpy( arComplete, arPluginsPath );
            ::lstrcat( arComplete, aFindData.cFileName );

            OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
            rPlugins[ aName ] = path;
        }

        if (! ::FindNextFile( hFind, &aFindData ))
            break;
    }

    if (hFind != INVALID_HANDLE_VALUE)
        ::FindClose( hFind );
}
//__________________________________________________________________________________________________
static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
{
    TCHAR arPluginsPath[MAX_PATH];
    DWORD dwPluginsPathSize = sizeof(arPluginsPath);
    arPluginsPath[dwPluginsPathSize-1] = 0;

    OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
    ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );

    addPluginsFromPath( arPluginsPath, rPlugins );
}

//__________________________________________________________________________________________________
static void add_IE_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    TCHAR arCurrent[MAX_PATH];
    DWORD dwType, dwCurrentSize = sizeof(arCurrent);

    if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
                        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
                               (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
            (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
        {
            // add \\Plugins
            ::lstrcat( arCurrent, _T("\\Plugins") );

            addPluginsFromPath( arCurrent, rPlugins );
        }
        ::RegCloseKey( hKey );
    }
}

//--------------------------------------------------------------------------------------------------
static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    // 4.7
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
    // 6
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Install Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        int n = size / sizeof (TCHAR);
        if ('\\' != value[ n -2 ])
        {
            value[ n -1 ] = '\\';
            value[ n ] = 0;
        }
        addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
    }
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
}
//--------------------------------------------------------------------------------------------------
static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
{
    add_NS_keys( hKey, rPlugins );

    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_NS_lookupRecursive( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Path"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
        INetURLObject aURL( aUPath );
        OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            rPlugins[ aName ] = aUPath;
        }
    }
}
static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_MozPlugin( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_NS_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    // Netscape
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla - plugins
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_MozillaPlugin( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
}

//__________________________________________________________________________________________________
static void add_SO_Plugins( PluginLocationMap & rPlugins )
{
    const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();

    const OUString * pPaths = rPaths.getConstArray();
    for ( UINT32 nPos = rPaths.getLength(); nPos--; )
    {
        addPluginsFromPath( pPaths[nPos], rPlugins );
    }
}

//__________________________________________________________________________________________________
Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
{
    Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
    static Sequence<PluginDescription > s_aDescriptions( 0 );
    static bool s_bInit = FALSE;

    if (! s_bInit)
    {
        // collect all distinct plugin dlls
        PluginLocationMap aPlugins;
        add_SO_Plugins( aPlugins );
        add_NS_Plugins( aPlugins );
        add_IE_Plugins( aPlugins );

        // collect mime types of plugin dlls
        for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
              iPos != aPlugins.end();
              ++iPos )
        {
            TCHAR arFileName[MAX_PATH];
            DWORD dwDummy, dwSize;

            // DLL name
            OUString aName( (*iPos).second.getStr() );

            OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
            ::strcpy( arFileName, aStr.getStr() );
            dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );

            if ( !dwSize )
                continue;

            char * pVersionData = new char[dwSize];
            if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
            {
                // optional comment
                OUString aComment;

                TCHAR * pInfo = NULL, * pInfo2 = NULL;
                UINT nSize = 0;
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
                                     (void**)&pInfo, &nSize ) && pInfo)
                {
                    aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
                }

                // mandatory mime type and file extensions
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
                                     (void**)&pInfo, &nSize ) && pInfo &&
                    ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
                                     (void**)&pInfo2, &nSize ) && pInfo2)
                {
                    OString aStr2( pInfo2 );
                    OString aExt( aStr2 );
                    OString aStr( pInfo );
                    OString aMIME( aStr );
                    aMIME.trim();

                    // count mime tokens
                    USHORT nToken = 0;
                    if (aMIME.getLength())
                    {
                        ++nToken;
                        for ( sal_Int32 n = aMIME.getLength(); n--; )
                        {
                            if (aMIME[ n ] == '|')
                            {
                                ++nToken;
                            }
                        }
                    }
                    sal_Int32 nIndex = 0, nIndex2 = 0;

                    UINT32 nStart = s_aDescriptions.getLength();
                    s_aDescriptions.realloc( nStart + nToken );
                    PluginDescription* pDescriptions = s_aDescriptions.getArray();
                    // for every MIME Type
                    sal_Int32 nTok = 0;
                    while (true)
                    {
                        if (nIndex < 0 || nIndex2 < 0)
                            break;

                        PluginDescription & rDescr = pDescriptions[nStart+nTok];
                        OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
                        OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
                        if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
                            continue;

                        rDescr.Mimetype = OUString(
                            aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
                        if (! rDescr.Mimetype.getLength())
                            break;

                        OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
                        rDescr.PluginName = aName;
                        rDescr.Description = aComment;

                        sal_Int32 nPos = 0, nLen = aExtToken.getLength();
                        OUString aExtensions = nLen ? OUString("*.") : OUString("*.*");

                        for ( ; nPos < nLen; ++nPos )
                        {
                            sal_Unicode c = aExtToken[nPos];
                            switch (c)
                            {
                            case ',':
                            case ';':
                                aExtensions += OUString(";*.");
                            case ' ':
                                break;
                            case '*':
                                if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
                                {
                                    ++nPos;
                                    break;
                                }
                            default:
                                aExtensions += OUString( &c, 1 );
                            }
                        }
                        rDescr.Extension = aExtensions;

                        ++nTok;
                    }

                    if (nToken != nTok)
                    {
                        s_aDescriptions.realloc( nTok );
                    }
                }
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_FAIL( "### cannot get MIME type or extensions!" );
#endif
            }
            if (pVersionData)
                delete[] pVersionData;
        }

        s_bInit = TRUE;
    }
    return s_aDescriptions;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>oops. mixed-up OString and OUString<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <prewin.h>
#include <postwin.h>
#undef OPTIONAL

#include "vcl/svapp.hxx"
#include "tools/fsys.hxx"
#include "tools/urlobj.hxx"
#include "osl/mutex.hxx"

#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"

#include "plugin/impl.hxx"

#pragma warning (push,1)
#pragma warning (disable:4005)

#include <string.h>
#include <tchar.h>
#include <objbase.h>

#pragma warning (pop)

#include <list>
#include <map>
#include <algorithm>

using namespace std;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::plugin;

using ::rtl::OUString;
using ::rtl::OString;
using ::rtl::OStringToOUString;
using ::rtl::OUStringToOString;

typedef map< OString, OUString, less< OString > > PluginLocationMap;

//__________________________________________________________________________________________________
static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
{
    // append dll name pattern we are looking for
    TCHAR arPluginsPath[MAX_PATH];
    arPluginsPath[0] = 0;

    if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
    {
        const char * p = ::getenv( "ProgramFiles" );
        if (p)
        {
            ::lstrcpy( arPluginsPath, p );
            pPluginsPath += 14;
        }
    }
    ::lstrcat( arPluginsPath, pPluginsPath );
    ::lstrcat( arPluginsPath, _T("\\") );

    TCHAR arPluginsPattern[MAX_PATH];
    ::lstrcpy( arPluginsPattern, arPluginsPath );
    ::lstrcat( arPluginsPattern, _T("NP*.DLL") );

    WIN32_FIND_DATA aFindData;
    HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );

    while (hFind != INVALID_HANDLE_VALUE)
    {
        OString aName = OString( aFindData.cFileName ).toAsciiLowerCase();

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            TCHAR arComplete[MAX_PATH];
            ::lstrcpy( arComplete, arPluginsPath );
            ::lstrcat( arComplete, aFindData.cFileName );

            OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
            rPlugins[ aName ] = path;
        }

        if (! ::FindNextFile( hFind, &aFindData ))
            break;
    }

    if (hFind != INVALID_HANDLE_VALUE)
        ::FindClose( hFind );
}
//__________________________________________________________________________________________________
static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
{
    TCHAR arPluginsPath[MAX_PATH];
    DWORD dwPluginsPathSize = sizeof(arPluginsPath);
    arPluginsPath[dwPluginsPathSize-1] = 0;

    OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
    ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );

    addPluginsFromPath( arPluginsPath, rPlugins );
}

//__________________________________________________________________________________________________
static void add_IE_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    TCHAR arCurrent[MAX_PATH];
    DWORD dwType, dwCurrentSize = sizeof(arCurrent);

    if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
                        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
                               (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
            (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
        {
            // add \\Plugins
            ::lstrcat( arCurrent, _T("\\Plugins") );

            addPluginsFromPath( arCurrent, rPlugins );
        }
        ::RegCloseKey( hKey );
    }
}

//--------------------------------------------------------------------------------------------------
static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    // 4.7
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
    // 6
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Install Directory"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        int n = size / sizeof (TCHAR);
        if ('\\' != value[ n -2 ])
        {
            value[ n -1 ] = '\\';
            value[ n ] = 0;
        }
        addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
    }
    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Plugins"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        addPluginsFromPath( value, rPlugins );
    }
}
//--------------------------------------------------------------------------------------------------
static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
{
    add_NS_keys( hKey, rPlugins );

    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_NS_lookupRecursive( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR value[MAX_PATH];
    DWORD dwType, size = sizeof(value);

    size = sizeof(value);
    if (::RegQueryValueEx(
        hKey, _T("Path"), NULL, &dwType,
        (LPBYTE)value, &size ) == ERROR_SUCCESS &&
        (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
    {
        OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
        INetURLObject aURL( aUPath );
        OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );

        // no netscape default plugin anymore...
        // and no double plugin dlls
        if ( !aName.equals( "npnul32.dll" ) &&
             ! aName.equals( "npnrvp.dll" ) &&
             rPlugins.find( aName ) == rPlugins.end())
        {
            rPlugins[ aName ] = aUPath;
        }
    }
}
static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
{
    TCHAR keyName[MAX_PATH];
    DWORD dwIndex = 0, size = sizeof (keyName);

    while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
    {
        size = sizeof (keyName);
        HKEY hSubKey;
        if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
        {
            add_MozPlugin( hSubKey, rPlugins );
            ::RegCloseKey( hSubKey );
        }
        ++dwIndex;
    }
}
//__________________________________________________________________________________________________
static void add_NS_Plugins( PluginLocationMap & rPlugins )
{
    HKEY hKey;
    // Netscape
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_NS_lookupRecursive( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
    // Mozilla - plugins
    if (::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
        0, KEY_READ, &hKey ) == ERROR_SUCCESS)
    {
        add_MozillaPlugin( hKey, rPlugins );
        ::RegCloseKey( hKey );
    }
}

//__________________________________________________________________________________________________
static void add_SO_Plugins( PluginLocationMap & rPlugins )
{
    const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();

    const OUString * pPaths = rPaths.getConstArray();
    for ( UINT32 nPos = rPaths.getLength(); nPos--; )
    {
        addPluginsFromPath( pPaths[nPos], rPlugins );
    }
}

//__________________________________________________________________________________________________
Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
{
    Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
    static Sequence<PluginDescription > s_aDescriptions( 0 );
    static bool s_bInit = FALSE;

    if (! s_bInit)
    {
        // collect all distinct plugin dlls
        PluginLocationMap aPlugins;
        add_SO_Plugins( aPlugins );
        add_NS_Plugins( aPlugins );
        add_IE_Plugins( aPlugins );

        // collect mime types of plugin dlls
        for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
              iPos != aPlugins.end();
              ++iPos )
        {
            TCHAR arFileName[MAX_PATH];
            DWORD dwDummy, dwSize;

            // DLL name
            OUString aName( (*iPos).second.getStr() );

            OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
            ::strcpy( arFileName, aStr.getStr() );
            dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );

            if ( !dwSize )
                continue;

            char * pVersionData = new char[dwSize];
            if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
            {
                // optional comment
                OUString aComment;

                TCHAR * pInfo = NULL, * pInfo2 = NULL;
                UINT nSize = 0;
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
                                     (void**)&pInfo, &nSize ) && pInfo)
                {
                    aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
                }

                // mandatory mime type and file extensions
                if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
                                     (void**)&pInfo, &nSize ) && pInfo &&
                    ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
                                     (void**)&pInfo2, &nSize ) && pInfo2)
                {
                    OString aStr2( pInfo2 );
                    OString aExt( aStr2 );
                    OString aStr( pInfo );
                    OString aMIME( aStr );
                    aMIME.trim();

                    // count mime tokens
                    USHORT nToken = 0;
                    if (aMIME.getLength())
                    {
                        ++nToken;
                        for ( sal_Int32 n = aMIME.getLength(); n--; )
                        {
                            if (aMIME[ n ] == '|')
                            {
                                ++nToken;
                            }
                        }
                    }
                    sal_Int32 nIndex = 0, nIndex2 = 0;

                    UINT32 nStart = s_aDescriptions.getLength();
                    s_aDescriptions.realloc( nStart + nToken );
                    PluginDescription* pDescriptions = s_aDescriptions.getArray();
                    // for every MIME Type
                    sal_Int32 nTok = 0;
                    while (true)
                    {
                        if (nIndex < 0 || nIndex2 < 0)
                            break;

                        PluginDescription & rDescr = pDescriptions[nStart+nTok];
                        OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
                        OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
                        if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
                            continue;

                        rDescr.Mimetype = OUString(
                            aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
                        if (! rDescr.Mimetype.getLength())
                            break;

                        OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
                        rDescr.PluginName = aName;
                        rDescr.Description = aComment;

                        sal_Int32 nPos = 0, nLen = aExtToken.getLength();
                        OUString aExtensions = nLen ? OUString("*.") : OUString("*.*");

                        for ( ; nPos < nLen; ++nPos )
                        {
                            sal_Unicode c = aExtToken[nPos];
                            switch (c)
                            {
                            case ',':
                            case ';':
                                aExtensions += OUString(";*.");
                            case ' ':
                                break;
                            case '*':
                                if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
                                {
                                    ++nPos;
                                    break;
                                }
                            default:
                                aExtensions += OUString( &c, 1 );
                            }
                        }
                        rDescr.Extension = aExtensions;

                        ++nTok;
                    }

                    if (nToken != nTok)
                    {
                        s_aDescriptions.realloc( nTok );
                    }
                }
#if OSL_DEBUG_LEVEL > 1
                else
                    OSL_FAIL( "### cannot get MIME type or extensions!" );
#endif
            }
            if (pVersionData)
                delete[] pVersionData;
        }

        s_bInit = TRUE;
    }
    return s_aDescriptions;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

// order of includes is important: first qapplication, than BALL includes
#include <QtGui/QApplication>
#include <BALL/CONFIG/config.h>

#ifdef BALL_HAS_GLEW
#	include <GL/glew.h>
#endif

#include <QtCore/QLocale>
#include <QtCore/QTranslator>

#include <QtGui/QMessageBox>
#include <QtGui/QSplashScreen>
#include <QtOpenGL/qgl.h>

#include "mainframe.h"
#include <BALL/SYSTEM/path.h>
#include <BALL/SYSTEM/directory.h>
#include <BALL/FORMAT/INIFile.h>
#include <BALL/SYSTEM/fileSystem.h>
#include <BALL/COMMON/logStream.h>

#include <iostream>

#ifdef Q_WS_X11
#include <X11/Xlib.h>
#endif

void logMessages(QtMsgType type, const char *msg)
{
	BALL::String s(msg);
	if (s.hasPrefix("QTextBrowser")) return;

	switch ( type ) {
		case QtDebugMsg:
				BALL::Log.info() << msg << std::endl;
				break;
		case QtWarningMsg:
				BALL::Log.warn() << msg << std::endl;
				break;
		case QtFatalMsg:
				fprintf( stderr, "Fatal: %s\n", msg );
				abort();                    // deliberately core dump
		case QtCriticalMsg:
				fprintf( stderr, "Critical: %s\n", msg );
				abort();                    // deliberately core dump
	}
}

// uncomment this to use debugging to std::cout!
//#undef BALL_OS_WINDOWS

#ifndef BALL_OS_WINDOWS
int main(int argc, char **argv)
{
#else
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR cmd_line, int)
{
	int argc = __argc;
	char** argv = __argv;
#endif

#ifdef Q_WS_X11
    XInitThreads();
#endif

	qInstallMsgHandler(logMessages);

	putenv("BALL_RETURN_VALUE=");
	QApplication application(argc, argv);

	QPixmap splash_pm(":BALLView-1.4-Splashscreen.png");
	QSplashScreen* splash = new QSplashScreen(splash_pm);
	splash->show();

	// =============== testing for opengl support ======================================
	if (!QGLFormat::hasOpenGL())
	{
		QMessageBox::critical(0, "Error while starting BALLView",
				"Your computer has no OpenGL support, please install the correct drivers. Aborting for now...",
				QMessageBox::Ok, Qt::NoButton, Qt::NoButton);
		return -1;
	}

	BALL::String home_dir = BALL::Directory::getUserHomeDir();

	// =============== load translations =====================
	BALL::INIFile f(home_dir + BALL::FileSystem::PATH_SEPARATOR + ".BALLView");
	f.read();

	if (f.hasEntry("GENERAL", "language"))
	{
		QString str = f.getValue("GENERAL", "language").c_str();

		if (!(str == "Default"))
		{
			QString loc = "BALLView." + str;

			BALL::Path p;
			QStringList dpaths = QString(p.getDataPath().c_str()).split("\n");

			QTranslator* translator = new QTranslator(&application);
			foreach(QString str, dpaths)
			{
				translator->load(loc, str + "BALLView/translations");
				if (!translator->isEmpty())
				{
					QCoreApplication::installTranslator(translator);
					break;
				}
			}
		}
	}

	// =============== testing if we can write in current directory =====================
	if (home_dir == "")
	{
		try
		{
			BALL::String temp_file_name;
			BALL::File::createTemporaryFilename(temp_file_name);
			BALL::File out(temp_file_name, std::ios::out);
			out << "test" << std::endl;
			out.remove();
		}
		catch(...)
		{
			QMessageBox::warning(0, "Error while starting BALLView",
					QString("You dont have write access to the current working directory\n") +
					"and BALLView can not find your home directory. This can cause\n" +
					"unexpected behaviour. Please start BALLView from your homedir with\n" +
					"absolute path (e.g. C:\\Programs\\BALLView\\BALLView).\n");
		}
	}

	// =============== initialize Mainframe ============================================
	// Create the mainframe.
	BALL::Mainframe mainframe(0, "Mainframe");

	// can we use the users homedir as working dir?
	if (home_dir != "")
	{
		mainframe.setWorkingDir(home_dir);
	}

	// Register the mainfram (required for Python support).
	mainframe.setIdentifier("Mainframe");
	mainframe.registerThis();

	// Show the main window.
	mainframe.show();

	// =============== parsing command line arguments ==================================
	// If there are additional command line arguments, interpret them as files to open or logging flag.
	for (BALL::Index i = 1; i < argc; ++i)
	{
		BALL::String argument(argv[i]);
		if (argument == "-l")
		{
			mainframe.enableLoggingToFile();
			continue;
		}

		mainframe.openFile(argument);
	}

	// enable ending of program from python script
	if (mainframe.isAboutToQuit())
	{
		mainframe.aboutToExit();
		return 0;
	}

	// Remove the splashscreen
	splash->finish(&mainframe);
	delete splash;

	// Hand over control to the application.
	int value = application.exec();
	char*	return_value = getenv("BALL_RETURN_VALUE");
	if (return_value != 0)
	{
		try
		{
			value = BALL::String(return_value).toInt();
		}
		catch(...)
		{
		}
	}

	return value;
}
<commit_msg>Initialize UIOperationMode in BALLView/main.C<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

// order of includes is important: first qapplication, than BALL includes
#include <QtGui/QApplication>
#include <BALL/CONFIG/config.h>

#ifdef BALL_HAS_GLEW
#	include <GL/glew.h>
#endif

#include <QtCore/QLocale>
#include <QtCore/QTranslator>

#include <QtGui/QMessageBox>
#include <QtGui/QSplashScreen>
#include <QtOpenGL/qgl.h>

#include "mainframe.h"
#include <BALL/SYSTEM/path.h>
#include <BALL/SYSTEM/directory.h>
#include <BALL/FORMAT/INIFile.h>
#include <BALL/SYSTEM/fileSystem.h>
#include <BALL/COMMON/logStream.h>

#include <BALL/VIEW/KERNEL/UIOperationMode.h>

#include <iostream>

#ifdef Q_WS_X11
#include <X11/Xlib.h>
#endif

void logMessages(QtMsgType type, const char *msg)
{
	BALL::String s(msg);
	if (s.hasPrefix("QTextBrowser")) return;

	switch ( type ) {
		case QtDebugMsg:
				BALL::Log.info() << msg << std::endl;
				break;
		case QtWarningMsg:
				BALL::Log.warn() << msg << std::endl;
				break;
		case QtFatalMsg:
				fprintf( stderr, "Fatal: %s\n", msg );
				abort();                    // deliberately core dump
		case QtCriticalMsg:
				fprintf( stderr, "Critical: %s\n", msg );
				abort();                    // deliberately core dump
	}
}

// uncomment this to use debugging to std::cout!
//#undef BALL_OS_WINDOWS

#ifndef BALL_OS_WINDOWS
int main(int argc, char **argv)
{
#else
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR cmd_line, int)
{
	int argc = __argc;
	char** argv = __argv;
#endif

#ifdef Q_WS_X11
    XInitThreads();
#endif

	qInstallMsgHandler(logMessages);

	putenv("BALL_RETURN_VALUE=");
	QApplication application(argc, argv);

	QStringList arguments = application.arguments();
	QStringList::const_iterator arg_it;

	bool kiosk_mode = false;
	for (arg_it = arguments.constBegin(); arg_it != arguments.constEnd(); ++arg_it)
	{
		if (arg_it->toLocal8Bit().constData() == "-kiosk")
		{
			kiosk_mode = true;
		}
	}

	if (kiosk_mode)
	{
		BALL::VIEW::UIOperationMode::instance().setMode(BALL::VIEW::UIOperationMode::MODE_KIOSK);
	}

  QPixmap splash_pm(":BALLView-1.4-Splashscreen.png");
  QSplashScreen* splash = new QSplashScreen(splash_pm);
  splash->show();

	// =============== testing for opengl support ======================================
	if (!QGLFormat::hasOpenGL())
	{
		QMessageBox::critical(0, "Error while starting BALLView",
				"Your computer has no OpenGL support, please install the correct drivers. Aborting for now...",
				QMessageBox::Ok, Qt::NoButton, Qt::NoButton);
		return -1;
	}

	BALL::String home_dir = BALL::Directory::getUserHomeDir();

	// =============== load translations =====================
	BALL::INIFile f(home_dir + BALL::FileSystem::PATH_SEPARATOR + ".BALLView");
	f.read();

	if (f.hasEntry("GENERAL", "language"))
	{
		QString str = f.getValue("GENERAL", "language").c_str();

		if (!(str == "Default"))
		{
			QString loc = "BALLView." + str;

			BALL::Path p;
			QStringList dpaths = QString(p.getDataPath().c_str()).split("\n");

			QTranslator* translator = new QTranslator(&application);
			foreach(QString str, dpaths)
			{
				translator->load(loc, str + "BALLView/translations");
				if (!translator->isEmpty())
				{
					QCoreApplication::installTranslator(translator);
					break;
				}
			}
		}
	}

	// =============== testing if we can write in current directory =====================
	if (home_dir == "")
	{
		try
		{
			BALL::String temp_file_name;
			BALL::File::createTemporaryFilename(temp_file_name);
			BALL::File out(temp_file_name, std::ios::out);
			out << "test" << std::endl;
			out.remove();
		}
		catch(...)
		{
			QMessageBox::warning(0, "Error while starting BALLView",
					QString("You dont have write access to the current working directory\n") +
					"and BALLView can not find your home directory. This can cause\n" +
					"unexpected behaviour. Please start BALLView from your homedir with\n" +
					"absolute path (e.g. C:\\Programs\\BALLView\\BALLView).\n");
		}
	}

	// =============== initialize Mainframe ============================================
	// Create the mainframe.
	BALL::Mainframe mainframe(0, "Mainframe");

	// can we use the users homedir as working dir?
	if (home_dir != "")
	{
		mainframe.setWorkingDir(home_dir);
	}

	// Register the mainfram (required for Python support).
	mainframe.setIdentifier("Mainframe");
	mainframe.registerThis();

	// Show the main window.
	mainframe.show();

	// =============== parsing command line arguments ==================================
	// If there are additional command line arguments, interpret them as files to open or logging flag.
	for (BALL::Index i = 1; i < argc; ++i)
	{
		BALL::String argument(argv[i]);
		if (argument == "-l")
		{
			mainframe.enableLoggingToFile();
			continue;
		}

		mainframe.openFile(argument);
	}

	// enable ending of program from python script
	if (mainframe.isAboutToQuit())
	{
		mainframe.aboutToExit();
		return 0;
	}

	// Remove the splashscreen
	splash->finish(&mainframe);
	delete splash;

	// Hand over control to the application.
	int value = application.exec();
	char*	return_value = getenv("BALL_RETURN_VALUE");
	if (return_value != 0)
	{
		try
		{
			value = BALL::String(return_value).toInt();
		}
		catch(...)
		{
		}
	}

	return value;
}
<|endoftext|>


<commit_before>#include <BALL/VIEW/RENDERING/renderSetup.h>

#include <BALL/VIEW/RENDERING/bufferedRenderer.h>
#include <BALL/VIEW/RENDERING/tilingRenderer.h>
#include <BALL/VIEW/RENDERING/glRenderWindow.h>

#include <BALL/VIEW/WIDGETS/scene.h>

#include <BALL/SYSTEM/timer.h>

#ifdef BALL_HAS_RTFACT
#include <BALL/VIEW/RENDERING/RENDERERS/rtfactRenderer.h>

#define USE_TBB
#ifdef USE_TBB
# include <tbb/task_scheduler_init.h>
#endif
#endif

namespace BALL
{
	namespace VIEW
	{
		RenderSetup::RenderSetup(Renderer* r, RenderTarget* t, Scene* scene, const Stage* stage)
			: QThread(),
				renderer(r),
				target(t),
				rendering_paused_(false),
				receive_updates_(true),
				use_offset_(false),
				camera_(),
				camera_offset_(Vector3(0.)),
				stereo_setup_(NONE),
				use_continuous_loop_(false),
				scene_(scene),
				stage_(stage),
				render_mutex_(true),
				show_ruler_(false)
		{
			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);
		}

		RenderSetup::RenderSetup(const RenderSetup& rs)
			: QThread(),
				renderer(rs.renderer),
				target(rs.target),
				rendering_paused_(rs.rendering_paused_),
				receive_updates_(rs.receive_updates_),
				use_offset_(rs.use_offset_),
				camera_(rs.camera_),
				camera_offset_(rs.camera_offset_),
				stereo_setup_(rs.stereo_setup_),
				use_continuous_loop_(rs.use_continuous_loop_),
				scene_(rs.scene_),
				stage_(rs.stage_),
				render_mutex_(true),
				show_ruler_(rs.show_ruler_)
		{
			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);
		}

		const RenderSetup& RenderSetup::operator = (const RenderSetup& rs)
		{
			render_mutex_.lock();

			renderer = rs.renderer;
			target = rs.target;
			rendering_paused_ = rs.rendering_paused_;
			receive_updates_ = rs.receive_updates_;
			use_offset_ = rs.use_offset_;
			about_to_quit_ = rs.about_to_quit_;
			camera_ = rs.camera_;
			camera_offset_ = rs.camera_offset_;
			stereo_setup_ = rs.stereo_setup_;
			use_continuous_loop_ = rs.use_continuous_loop_;
			scene_ = rs.scene_;
			stage_ = rs.stage_;

			show_ruler_ = rs.show_ruler_;

			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);

			render_mutex_.unlock();

			return *this;
		}

		void RenderSetup::init()
		{
			render_mutex_.lock();

			makeCurrent();

			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);

			// initialize the rendering target
			target->init();

			// initialize the renderer
			if(!renderer->init(*scene_))
			{
				Log.error() << "Renderer failed to initialize" << std::endl;
				throw Exception::GeneralException(__FILE__, __LINE__);
			}

			if (gl_renderer_)
				gl_renderer_->enableVertexBuffers(scene_->want_to_use_vertex_buffer_);

			render_mutex_.unlock();
		}

		void RenderSetup::resize(Size width, Size height)
		{
			// prevent resizing of full screen Windows because they are
			// most probably stereo half images
			if (gl_target_ && gl_target_->isFullScreen())
				return;

			render_mutex_.lock();

			makeCurrent();

			if(!target->resize(width, height))
			{
				Log.error() << "Cannot resize window. Size "
										<< width  << " x "
										<< height << " is not supported" << std::endl;
			}

			renderer->setSize(width, height);
			if (RTTI::isKindOf<BufferedRenderer>(*renderer))
			{
				if(!(((BufferedRenderer*)renderer)->setFrameBufferFormat(target->getFormat())))
				{
					Log.error() << "Raytracing render does not support window framebuffer format. Seems to be configuration error" << std::endl;

					render_mutex_.unlock();

					throw Exception::GeneralException(__FILE__, __LINE__);
				}
			}

			renderer->setSize(width, height);
			render_mutex_.unlock();

			updateCamera();

			renderToBuffer_();

			render_mutex_.lock();

			if (gl_target_)
				gl_target_->swapBuffers();

			render_mutex_.unlock();
		}

		void RenderSetup::updateCamera(const Camera* camera)
		{
			Stage const& stage = renderer->getStage();

			camera_ = (camera == 0) ? stage.getCamera() : *camera;

			render_mutex_.lock();

			if (stereo_setup_ != NONE)
			{
				float eye_separation = stage.getEyeDistance() * 0.5;
				eye_separation *= (stereo_setup_ == LEFT_EYE) ? -1. : 1.;
				eye_separation *= stage.swapSideBySideStereo() ? -1. : 1.;

				renderer->setupStereo(eye_separation, stage.getFocalDistance());

				camera_offset_  = Vector3(eye_separation, 0., 0.);

				use_offset_ = true;
			}

			if (use_offset_)
			{
				Vector3 const& right = camera_.getRightVector();
				Vector3 const& up    = camera_.getLookUpVector();
				Vector3 const& view  = camera_.getViewVector();

				Vector3 absolute_offset = 	right * camera_offset_.x
																	+ up    * camera_offset_.y
																	+ view  * camera_offset_.z;

				camera_.setViewPoint(camera_.getViewPoint()+absolute_offset);
				camera_.setLookAtPosition(camera_.getLookAtPosition()+absolute_offset);
			}

			renderer->updateCamera(&camera_);

			render_mutex_.unlock();
		}

		void RenderSetup::setOffset(const Vector3& offset)
		{
			camera_offset_ = offset;

			if (offset.getSquareLength() > 0)
				use_offset_ = true;
			else
				use_offset_ = false;
		}

		void RenderSetup::useContinuousLoop(bool use_loop)
		{
			// TODO: mutex for use_continuous_loop_ just to be on the safe side
			use_continuous_loop_ = use_loop;

			render_mutex_.lock();
			renderer->useContinuousLoop(use_loop);
			render_mutex_.unlock();
		}

		void RenderSetup::makeCurrent()
		{
			if (gl_target_ &&
				   (QGLContext::currentContext() != gl_target_->context()))
				gl_target_->makeCurrent();
			else
				target->prepareRendering();
		}

		void RenderSetup::run()
		{
#ifdef USE_TBB
			tbb::task_scheduler_init init;
#endif
			if (gl_target_)
				gl_target_->ignoreEvents(true);
			Timer t;

			// to be stopped from the outside, someone needs to call useContinuousLoop(false)
			while (!about_to_quit_)
			{
				printf("###################################### FRAME #####################################\n");
				t.start();
				renderToBuffer_();

				loop_mutex.lock();
				qApp->postEvent(scene_, new RenderToBufferFinishedEvent(this));
				wait_for_render.wait(&loop_mutex);
				loop_mutex.unlock();
				t.stop();
				printf("###################################### DONE (%f)  #####################################\n", t.getClockTime());
				t.reset();
			}
		}

		void RenderSetup::renderToBuffer()
		{
			if (!use_continuous_loop_)
				renderToBuffer_();
		}

		void RenderSetup::renderToBuffer_()
		{
			if (rendering_paused_)
			{
				if (use_continuous_loop_)
					msleep(100);
				return;
			}

			render_mutex_.lock();

			renderer->setPreviewMode(scene_->use_preview_ && scene_->preview_);
			renderer->showLightSources(scene_->show_light_sources_);

			updateCamera();

			if (RTTI::isKindOf<BufferedRenderer>(*renderer))
			{
				((BufferedRenderer*)renderer)->renderToBuffer(target, *stage_);
			}
			else if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				GLRenderer* current_gl_renderer = static_cast<GLRenderer*>(renderer);
				// TODO: what do we do here? should we push the gl calls somewhere else, i.e. in the GUI thread?
				// cannot call update here, because it calls updateGL
				current_gl_renderer->renderToBuffer(target, GLRenderer::DISPLAY_LISTS_RENDERING);

				glFlush();
			}
			else if (RTTI::isKindOf<TilingRenderer>(*renderer))
			{
				static_cast<TilingRenderer*>(renderer)->renderToBuffer(target);
				glFlush();
			}

			if (show_ruler_)
				renderer->renderRuler();

			render_mutex_.unlock();
		}

		bool RenderSetup::exportPNG(const String& filename)
		{
			if (!gl_target_)
				return false;

			render_mutex_.lock();

			makeCurrent();

			QImage image(target->grabFrameBuffer(true));

			render_mutex_.unlock();

			bool ok = image.save(filename.c_str(), "PNG");

			return ok;
		}

		void RenderSetup::bufferRepresentation(const Representation& rep)
		{
			if (receive_updates_)
			{
				render_mutex_.lock();

				makeCurrent();

				renderer->bufferRepresentation(rep);

				render_mutex_.unlock();
			}
		}

		void RenderSetup::removeRepresentation(const Representation& rep)
		{
			if (receive_updates_)
			{
				render_mutex_.lock();

				makeCurrent();

				renderer->removeRepresentation(rep);

				render_mutex_.unlock();
			}
		}

		void RenderSetup::setLights(bool reset_all)
		{
			render_mutex_.lock();

			makeCurrent();

			renderer->setLights(reset_all);

			render_mutex_.unlock();
		}

		void RenderSetup::updateBackgroundColor()
		{
			render_mutex_.lock();

			makeCurrent();

			renderer->updateBackgroundColor();

			render_mutex_.unlock();
		}

		Position RenderSetup::prepareGridTextures(const RegularData3D& grid, const ColorMap& map)
		{
			Position texname = 0;

			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				render_mutex_.lock();

				makeCurrent();

				texname = ((GLRenderer*)renderer)->createTextureFromGrid(grid, map);

				render_mutex_.unlock();
			}

			return texname;
		}

		void RenderSetup::removeGridTextures(const RegularData3D& grid)
		{
			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				MutexLocker ml(&render_mutex_);

				makeCurrent();

				((GLRenderer*)renderer)->removeTextureFor_(grid);
			}
		}

		Vector3 RenderSetup::mapViewportTo3D(Position x, Position y)
		{
			MutexLocker ml(&render_mutex_);
			render_mutex_.lock();

			makeCurrent();

			return renderer->mapViewportTo3D(x, y);
		}

		Vector2 RenderSetup::map3DToViewport(const Vector3& vec)
		{
			MutexLocker ml(&render_mutex_);

			makeCurrent();

			return renderer->map3DToViewport(vec);
		}

		void RenderSetup::pickObjects(Position x1, Position y1,
		                              Position x2, Position y2,
		                              list<GeometricObject*>& objects)
		{
			if (!RTTI::isKindOf<GLRenderer>(*renderer))
			{
				Log.error() << "RenderSetup::pickObjects not supported for this kind of renderer!" << std::endl;
				return;
			}

			MutexLocker ml(&render_mutex_);

			makeCurrent();

			((GLRenderer*)renderer)->pickObjects1(x1, y1, x2, y2);
			((GLRenderer*)renderer)->renderToBuffer(target, GLRenderer::DIRECT_RENDERING);
			((GLRenderer*)renderer)->pickObjects2(objects);
		}

		void RenderSetup::showRuler(bool show)
		{
			MutexLocker ml(&render_mutex_);
			show_ruler_ = show;
		}

		void RenderSetup::projectionModeChanged()
		{
			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				static_cast<GLRenderer*>(renderer)->initPerspective();
			}
		}
	}
}
<commit_msg>Improved FPS output on the command line.<commit_after>#include <BALL/VIEW/RENDERING/renderSetup.h>

#include <BALL/VIEW/RENDERING/bufferedRenderer.h>
#include <BALL/VIEW/RENDERING/tilingRenderer.h>
#include <BALL/VIEW/RENDERING/glRenderWindow.h>

#include <BALL/VIEW/WIDGETS/scene.h>

#include <BALL/SYSTEM/timer.h>

#ifdef BALL_HAS_RTFACT
#include <BALL/VIEW/RENDERING/RENDERERS/rtfactRenderer.h>

#define USE_TBB
#ifdef USE_TBB
# include <tbb/task_scheduler_init.h>
#endif
#endif

namespace BALL
{
	namespace VIEW
	{
		RenderSetup::RenderSetup(Renderer* r, RenderTarget* t, Scene* scene, const Stage* stage)
			: QThread(),
				renderer(r),
				target(t),
				rendering_paused_(false),
				receive_updates_(true),
				use_offset_(false),
				camera_(),
				camera_offset_(Vector3(0.)),
				stereo_setup_(NONE),
				use_continuous_loop_(false),
				scene_(scene),
				stage_(stage),
				render_mutex_(true),
				show_ruler_(false)
		{
			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);
		}

		RenderSetup::RenderSetup(const RenderSetup& rs)
			: QThread(),
				renderer(rs.renderer),
				target(rs.target),
				rendering_paused_(rs.rendering_paused_),
				receive_updates_(rs.receive_updates_),
				use_offset_(rs.use_offset_),
				camera_(rs.camera_),
				camera_offset_(rs.camera_offset_),
				stereo_setup_(rs.stereo_setup_),
				use_continuous_loop_(rs.use_continuous_loop_),
				scene_(rs.scene_),
				stage_(rs.stage_),
				render_mutex_(true),
				show_ruler_(rs.show_ruler_)
		{
			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);
		}

		const RenderSetup& RenderSetup::operator = (const RenderSetup& rs)
		{
			render_mutex_.lock();

			renderer = rs.renderer;
			target = rs.target;
			rendering_paused_ = rs.rendering_paused_;
			receive_updates_ = rs.receive_updates_;
			use_offset_ = rs.use_offset_;
			about_to_quit_ = rs.about_to_quit_;
			camera_ = rs.camera_;
			camera_offset_ = rs.camera_offset_;
			stereo_setup_ = rs.stereo_setup_;
			use_continuous_loop_ = rs.use_continuous_loop_;
			scene_ = rs.scene_;
			stage_ = rs.stage_;

			show_ruler_ = rs.show_ruler_;

			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);

			render_mutex_.unlock();

			return *this;
		}

		void RenderSetup::init()
		{
			render_mutex_.lock();

			makeCurrent();

			gl_target_   = dynamic_cast<GLRenderWindow*>(target);
			gl_renderer_ = dynamic_cast<GLRenderer*>(renderer);

			// initialize the rendering target
			target->init();

			// initialize the renderer
			if(!renderer->init(*scene_))
			{
				Log.error() << "Renderer failed to initialize" << std::endl;
				throw Exception::GeneralException(__FILE__, __LINE__);
			}

			if (gl_renderer_)
				gl_renderer_->enableVertexBuffers(scene_->want_to_use_vertex_buffer_);

			render_mutex_.unlock();
		}

		void RenderSetup::resize(Size width, Size height)
		{
			// prevent resizing of full screen Windows because they are
			// most probably stereo half images
			if (gl_target_ && gl_target_->isFullScreen())
				return;

			render_mutex_.lock();

			makeCurrent();

			if(!target->resize(width, height))
			{
				Log.error() << "Cannot resize window. Size "
										<< width  << " x "
										<< height << " is not supported" << std::endl;
			}

			renderer->setSize(width, height);
			if (RTTI::isKindOf<BufferedRenderer>(*renderer))
			{
				if(!(((BufferedRenderer*)renderer)->setFrameBufferFormat(target->getFormat())))
				{
					Log.error() << "Raytracing render does not support window framebuffer format. Seems to be configuration error" << std::endl;

					render_mutex_.unlock();

					throw Exception::GeneralException(__FILE__, __LINE__);
				}
			}

			renderer->setSize(width, height);
			render_mutex_.unlock();

			updateCamera();

			renderToBuffer_();

			render_mutex_.lock();

			if (gl_target_)
				gl_target_->swapBuffers();

			render_mutex_.unlock();
		}

		void RenderSetup::updateCamera(const Camera* camera)
		{
			Stage const& stage = renderer->getStage();

			camera_ = (camera == 0) ? stage.getCamera() : *camera;

			render_mutex_.lock();

			if (stereo_setup_ != NONE)
			{
				float eye_separation = stage.getEyeDistance() * 0.5;
				eye_separation *= (stereo_setup_ == LEFT_EYE) ? -1. : 1.;
				eye_separation *= stage.swapSideBySideStereo() ? -1. : 1.;

				renderer->setupStereo(eye_separation, stage.getFocalDistance());

				camera_offset_  = Vector3(eye_separation, 0., 0.);

				use_offset_ = true;
			}

			if (use_offset_)
			{
				Vector3 const& right = camera_.getRightVector();
				Vector3 const& up    = camera_.getLookUpVector();
				Vector3 const& view  = camera_.getViewVector();

				Vector3 absolute_offset = 	right * camera_offset_.x
																	+ up    * camera_offset_.y
																	+ view  * camera_offset_.z;

				camera_.setViewPoint(camera_.getViewPoint()+absolute_offset);
				camera_.setLookAtPosition(camera_.getLookAtPosition()+absolute_offset);
			}

			renderer->updateCamera(&camera_);

			render_mutex_.unlock();
		}

		void RenderSetup::setOffset(const Vector3& offset)
		{
			camera_offset_ = offset;

			if (offset.getSquareLength() > 0)
				use_offset_ = true;
			else
				use_offset_ = false;
		}

		void RenderSetup::useContinuousLoop(bool use_loop)
		{
			// TODO: mutex for use_continuous_loop_ just to be on the safe side
			use_continuous_loop_ = use_loop;

			render_mutex_.lock();
			renderer->useContinuousLoop(use_loop);
			render_mutex_.unlock();
		}

		void RenderSetup::makeCurrent()
		{
			if (gl_target_ &&
				   (QGLContext::currentContext() != gl_target_->context()))
				gl_target_->makeCurrent();
			else
				target->prepareRendering();
		}

		void RenderSetup::run()
		{
#ifdef USE_TBB
			tbb::task_scheduler_init init;
#endif
			if (gl_target_)
				gl_target_->ignoreEvents(true);
			Timer t;

			Size current_frame = 0;
			double fps = 0.;
			// to be stopped from the outside, someone needs to call useContinuousLoop(false)
			while (!about_to_quit_)
			{
				t.start();
				renderToBuffer_();
				t.stop();

				fps += t.getClockTime();

				if (current_frame % 10 == 0)
				{
					fps = 10./fps;
					printf("########## Average rendering FPS = %.2lf  #########\n", fps);

					fps = 0.;
				}
				loop_mutex.lock();
				qApp->postEvent(scene_, new RenderToBufferFinishedEvent(this));
				wait_for_render.wait(&loop_mutex);
				loop_mutex.unlock();
				t.reset();
				current_frame++;
			}
		}

		void RenderSetup::renderToBuffer()
		{
			if (!use_continuous_loop_)
				renderToBuffer_();
		}

		void RenderSetup::renderToBuffer_()
		{
			if (rendering_paused_)
			{
				if (use_continuous_loop_)
					msleep(100);
				return;
			}

			render_mutex_.lock();

			renderer->setPreviewMode(scene_->use_preview_ && scene_->preview_);
			renderer->showLightSources(scene_->show_light_sources_);

			updateCamera();

			if (RTTI::isKindOf<BufferedRenderer>(*renderer))
			{
				((BufferedRenderer*)renderer)->renderToBuffer(target, *stage_);
			}
			else if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				GLRenderer* current_gl_renderer = static_cast<GLRenderer*>(renderer);
				// TODO: what do we do here? should we push the gl calls somewhere else, i.e. in the GUI thread?
				// cannot call update here, because it calls updateGL
				current_gl_renderer->renderToBuffer(target, GLRenderer::DISPLAY_LISTS_RENDERING);

				glFlush();
			}
			else if (RTTI::isKindOf<TilingRenderer>(*renderer))
			{
				static_cast<TilingRenderer*>(renderer)->renderToBuffer(target);
				glFlush();
			}

			if (show_ruler_)
				renderer->renderRuler();

			render_mutex_.unlock();
		}

		bool RenderSetup::exportPNG(const String& filename)
		{
			if (!gl_target_)
				return false;

			render_mutex_.lock();

			makeCurrent();

			QImage image(target->grabFrameBuffer(true));

			render_mutex_.unlock();

			bool ok = image.save(filename.c_str(), "PNG");

			return ok;
		}

		void RenderSetup::bufferRepresentation(const Representation& rep)
		{
			if (receive_updates_)
			{
				render_mutex_.lock();

				makeCurrent();

				renderer->bufferRepresentation(rep);

				render_mutex_.unlock();
			}
		}

		void RenderSetup::removeRepresentation(const Representation& rep)
		{
			if (receive_updates_)
			{
				render_mutex_.lock();

				makeCurrent();

				renderer->removeRepresentation(rep);

				render_mutex_.unlock();
			}
		}

		void RenderSetup::setLights(bool reset_all)
		{
			render_mutex_.lock();

			makeCurrent();

			renderer->setLights(reset_all);

			render_mutex_.unlock();
		}

		void RenderSetup::updateBackgroundColor()
		{
			render_mutex_.lock();

			makeCurrent();

			renderer->updateBackgroundColor();

			render_mutex_.unlock();
		}

		Position RenderSetup::prepareGridTextures(const RegularData3D& grid, const ColorMap& map)
		{
			Position texname = 0;

			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				render_mutex_.lock();

				makeCurrent();

				texname = ((GLRenderer*)renderer)->createTextureFromGrid(grid, map);

				render_mutex_.unlock();
			}

			return texname;
		}

		void RenderSetup::removeGridTextures(const RegularData3D& grid)
		{
			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				MutexLocker ml(&render_mutex_);

				makeCurrent();

				((GLRenderer*)renderer)->removeTextureFor_(grid);
			}
		}

		Vector3 RenderSetup::mapViewportTo3D(Position x, Position y)
		{
			MutexLocker ml(&render_mutex_);
			render_mutex_.lock();

			makeCurrent();

			return renderer->mapViewportTo3D(x, y);
		}

		Vector2 RenderSetup::map3DToViewport(const Vector3& vec)
		{
			MutexLocker ml(&render_mutex_);

			makeCurrent();

			return renderer->map3DToViewport(vec);
		}

		void RenderSetup::pickObjects(Position x1, Position y1,
		                              Position x2, Position y2,
		                              list<GeometricObject*>& objects)
		{
			if (!RTTI::isKindOf<GLRenderer>(*renderer))
			{
				Log.error() << "RenderSetup::pickObjects not supported for this kind of renderer!" << std::endl;
				return;
			}

			MutexLocker ml(&render_mutex_);

			makeCurrent();

			((GLRenderer*)renderer)->pickObjects1(x1, y1, x2, y2);
			((GLRenderer*)renderer)->renderToBuffer(target, GLRenderer::DIRECT_RENDERING);
			((GLRenderer*)renderer)->pickObjects2(objects);
		}

		void RenderSetup::showRuler(bool show)
		{
			MutexLocker ml(&render_mutex_);
			show_ruler_ = show;
		}

		void RenderSetup::projectionModeChanged()
		{
			if (RTTI::isKindOf<GLRenderer>(*renderer))
			{
				static_cast<GLRenderer*>(renderer)->initPerspective();
			}
		}
	}
}
<|endoftext|>


<commit_before>#include "Platform.hpp"
#include "Neuron.hpp"
#include "Synapse.hpp"
#include "Branch.hpp"
#include "ActivityStats.hpp"
#include "genome.pb.h"
#include "Brain.hpp"
#include "SimpleProteinEnvironment.hpp"
#include "ProteinDensity.hpp"
#include "SpatialSearch.hpp"
#include <time.h>

namespace Elysia {

/**
 *	Description:	Deletes the protein density from memory and removes this neuron from the nearest-neighbor search
**/
Neuron::~Neuron() {
	//TODO Send a detach signal to all synapses presently attached
    delete mProteinDensity;
    mBrain->getSpatialSearch()->removeNeighbor(this);
	for(std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i){
		delete *i;
	}
}

/**
 *	@param Brain* brain - inherits a parent brain structure from somewhere
 *	@param float BaseBranchiness -
 *	@param float TipBranchiness -
 *	@param float TreeDepth -
 *	@param const Vector3f &location - neuron's location in space
 *	@param const Elysia::Genome::Gene &gene - parent gene info
 *
 *	Description:	Instantiates a new neuron object at some phyiscal location, setting the development counter at zero.
 *					The branch density is synched based upon some random parameters and some base parameters, as well as a defined tree depth
 *					This neuron is added to the nearest neighbor spatial search
**/
Neuron::Neuron(Brain* brain, float BaseBranchiness, float TipBranchiness, float TreeDepth, const Vector3f &location, const Elysia::Genome::Gene&gene):  mNeuronLocation(location){
    mProteinDensity = new ProteinDensity(brain->getProteinEnvironment(),gene);
    mBrain=brain;
    mDevelopmentCounter = 0;
    mWhere=brain->activeNeuronListSentinel();
    mRandomDepthDeterminer=rand()/(float)RAND_MAX;
    mRandomBranchDeterminer=rand()/(float)RAND_MAX;
    //mWhere=mBrain->activateNeuron(this); //JUST FOR TESTING REMOVE ME LATER
    this->syncBranchDensity(mRandomBranchDeterminer, mRandomDepthDeterminer, BaseBranchiness, TipBranchiness, TreeDepth, 0);
    mBrain->getSpatialSearch()->addNeighbor(this);
	mBaseBranchiness = BaseBranchiness;
    mTipBranchiness = TipBranchiness;
    mTreeDepth = TreeDepth;
	/* These are not yet used
    mBaseThreshold;
    mTipThreshold;
	*/
}

/**
 *	Description:	Fires neuron into all synapses connected to it
**/
void Neuron::fire() {
	printf("fire");
    for (std::vector<Synapse*>::iterator i=mConnectedSynapses.begin(),ie=mConnectedSynapses.end();
         i!=ie;
         ++i) {
        this->fireNeuron(*i);
    }
}

/**
 *	@param Brain& - unused, here for inheritance
 *	@param float signal - signal to add to activity
 *
 *	Description:	If last activity is not current sim time in the brain, reset activity to zero
 *					and make last activity time current brain time.
 *					Then, if the activity is under some treshold, the signal parameter is added to activity,
 *					after which the neuron is activated if the new activity level is above some threshold
**/
void Neuron::activateComponent(Brain&, float signal){
	if(mLastActivity != mBrain->mCurTime){
		mLastActivity = mBrain->mCurTime;
		mActivity = 0;
	}
	if(mActivity <= mThreshold){
	    mActivity += signal;
		if(mActivity > mThreshold){
			mBrain -> activateNeuron(this);     //Add to Neuron List
		}
	}
}

/**
 *	@param Synapse *synapse - pointer to some synapse you want to remove
 *
 *	Description:	Looks for the provided synapse in the connected synapses vector and removes it, if found.
 *					Prints an error message if not found
**/
void Neuron::removeSynapse(Synapse*synapse){
  std::vector<Synapse* >::iterator where=std::find(mConnectedSynapses.begin(),mConnectedSynapses.end(),synapse);
  if (where!=mConnectedSynapses.end()) {
    mConnectedSynapses.erase(where);
  }else {
    std::cerr<< "Could not find synapse\n";
  }
}

/**
 *	@param Synapse *target - pointer to a synapse to fire
 *
 *	Description:	Fires some synapse
**/
void Neuron::fireNeuron(Synapse*target){
	target->fireSynapse();
}

/**
 *	@param Synapse *target - pointer to a synapse to add
 *
 *	Description:	Puts the new synapse at the end of the connected synapses vector
**/
void Neuron::attachSynapse(Synapse*target){
	mConnectedSynapses.push_back(target);
}

/**
 *	@param float signal - signal to add to development signal
 *
 *	Description:	Adds some value to the development signal level
**/
void Neuron::passDevelopmentSignal(float signal){
	mDevelopmentSignal += signal;
}
/**
 *	@returns *mProteinDensity
**/
ProteinDensity& Neuron::getProteinDensityStructure(){
    return *mProteinDensity;
}

/**
 *	@param const ActivityStats& stats - activity statistics for something
 *
 *	Description:	Develops all synapses attached as child branches of this neuron
**/
void Neuron::developSynapse(const ActivityStats& stats){
for (std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i)
	(*i)->developSynapse(stats);
}

/**
 *	@param FILE *dendriteTree - output file for the visualized dendrite tree
 *	@param size_t parent - unused, please remove
 *
 *	Description:	Outputs a visualization of the dendrite tree to a file
**/
void Neuron::visualizeTree(FILE *dendriteTree, size_t parent){

    size_t self;

    self = (size_t)this;
    //fprintf(dendriteTree,"Graph Tree {\n");
    for (std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i)
         (*i) -> visualizeTree(dendriteTree, self);
   //fprintf(dendriteTree,"}");

   }

/**
 *	Description:	Executes one "tick" of the brain simulation for this neuron.
 *					If activity is over some threshold, fires the neuron.
 *					If development stage is not set and development counter is not at zero,
 *					the development counter is decremented.  If it is at zero, then we developSynapse(getActivityStats())
 *					and reset development counter to 30.
 *					mActivity always cleared at the end of this
**/
void Neuron::tick(){
	if(mActivity > mThreshold){
		fire();
	}
	if(mDevelopmentStage == 0){
		if(mDevelopmentCounter == 0){
			ActivityStats& stats = getActivityStats();
			developSynapse(stats);
			mDevelopmentCounter	= 30;					//number of timesteps before next development re-evaluation
		}
		else{ mDevelopmentCounter--;}
	}
	mActivity = 0;
}
}
<commit_msg>Committing synapse removal function<commit_after>#include "Platform.hpp"
#include "Neuron.hpp"
#include "Synapse.hpp"
#include "Branch.hpp"
#include "ActivityStats.hpp"
#include "genome.pb.h"
#include "Brain.hpp"
#include "SimpleProteinEnvironment.hpp"
#include "ProteinDensity.hpp"
#include "SpatialSearch.hpp"
#include <time.h>

namespace Elysia {

/**
 *	Description:	Deletes the protein density from memory and removes this neuron from the nearest-neighbor search
**/
Neuron::~Neuron() {
	//TODO Send a detach signal to all synapses presently attached
    for (std::ptrdiff_t i=(std::ptrdiff_t)mConnectedSynapses.size()-1;i>=0;--i) {
        mConnectedSynapses[i]->detach();
    }
    assert(mConnectedSynapses.size()==0);
    delete mProteinDensity;
    mBrain->getSpatialSearch()->removeNeighbor(this);
	for(std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i){
		delete *i;
	}
}

/**
 *	@param Brain* brain - inherits a parent brain structure from somewhere
 *	@param float BaseBranchiness -
 *	@param float TipBranchiness -
 *	@param float TreeDepth -
 *	@param const Vector3f &location - neuron's location in space
 *	@param const Elysia::Genome::Gene &gene - parent gene info
 *
 *	Description:	Instantiates a new neuron object at some phyiscal location, setting the development counter at zero.
 *					The branch density is synched based upon some random parameters and some base parameters, as well as a defined tree depth
 *					This neuron is added to the nearest neighbor spatial search
**/
Neuron::Neuron(Brain* brain, float BaseBranchiness, float TipBranchiness, float TreeDepth, const Vector3f &location, const Elysia::Genome::Gene&gene):  mNeuronLocation(location){
    mProteinDensity = new ProteinDensity(brain->getProteinEnvironment(),gene);
    mBrain=brain;
    mDevelopmentCounter = 0;
    mWhere=brain->activeNeuronListSentinel();
    mRandomDepthDeterminer=rand()/(float)RAND_MAX;
    mRandomBranchDeterminer=rand()/(float)RAND_MAX;
    //mWhere=mBrain->activateNeuron(this); //JUST FOR TESTING REMOVE ME LATER
    this->syncBranchDensity(mRandomBranchDeterminer, mRandomDepthDeterminer, BaseBranchiness, TipBranchiness, TreeDepth, 0);
    mBrain->getSpatialSearch()->addNeighbor(this);
	mBaseBranchiness = BaseBranchiness;
    mTipBranchiness = TipBranchiness;
    mTreeDepth = TreeDepth;
	/* These are not yet used
    mBaseThreshold;
    mTipThreshold;
	*/
}

/**
 *	Description:	Fires neuron into all synapses connected to it
**/
void Neuron::fire() {
	printf("fire");
    for (std::vector<Synapse*>::iterator i=mConnectedSynapses.begin(),ie=mConnectedSynapses.end();
         i!=ie;
         ++i) {
        this->fireNeuron(*i);
    }
}

/**
 *	@param Brain& - unused, here for inheritance
 *	@param float signal - signal to add to activity
 *
 *	Description:	If last activity is not current sim time in the brain, reset activity to zero
 *					and make last activity time current brain time.
 *					Then, if the activity is under some treshold, the signal parameter is added to activity,
 *					after which the neuron is activated if the new activity level is above some threshold
**/
void Neuron::activateComponent(Brain&, float signal){
	if(mLastActivity != mBrain->mCurTime){
		mLastActivity = mBrain->mCurTime;
		mActivity = 0;
	}
	if(mActivity <= mThreshold){
	    mActivity += signal;
		if(mActivity > mThreshold){
			mBrain -> activateNeuron(this);     //Add to Neuron List
		}
	}
}

/**
 *	@param Synapse *synapse - pointer to some synapse you want to remove
 *
 *	Description:	Looks for the provided synapse in the connected synapses vector and removes it, if found.
 *					Prints an error message if not found
**/
void Neuron::removeSynapse(Synapse*synapse){
  std::vector<Synapse* >::iterator where=std::find(mConnectedSynapses.begin(),mConnectedSynapses.end(),synapse);
  if (where!=mConnectedSynapses.end()) {
    mConnectedSynapses.erase(where);
  }else {
    std::cerr<< "Could not find synapse\n";
  }
}

/**
 *	@param Synapse *target - pointer to a synapse to fire
 *
 *	Description:	Fires some synapse
**/
void Neuron::fireNeuron(Synapse*target){
	target->fireSynapse();
}

/**
 *	@param Synapse *target - pointer to a synapse to add
 *
 *	Description:	Puts the new synapse at the end of the connected synapses vector
**/
void Neuron::attachSynapse(Synapse*target){
	mConnectedSynapses.push_back(target);
}

/**
 *	@param float signal - signal to add to development signal
 *
 *	Description:	Adds some value to the development signal level
**/
void Neuron::passDevelopmentSignal(float signal){
	mDevelopmentSignal += signal;
}
/**
 *	@returns *mProteinDensity
**/
ProteinDensity& Neuron::getProteinDensityStructure(){
    return *mProteinDensity;
}

/**
 *	@param const ActivityStats& stats - activity statistics for something
 *
 *	Description:	Develops all synapses attached as child branches of this neuron
**/
void Neuron::developSynapse(const ActivityStats& stats){
for (std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i)
	(*i)->developSynapse(stats);
}

/**
 *	@param FILE *dendriteTree - output file for the visualized dendrite tree
 *	@param size_t parent - unused, please remove
 *
 *	Description:	Outputs a visualization of the dendrite tree to a file
**/
void Neuron::visualizeTree(FILE *dendriteTree, size_t parent){

    size_t self;

    self = (size_t)this;
    //fprintf(dendriteTree,"Graph Tree {\n");
    for (std::vector<Branch*>::iterator i=mChildBranches.begin(),ie=mChildBranches.end();
         i!=ie;
         ++i)
         (*i) -> visualizeTree(dendriteTree, self);
   //fprintf(dendriteTree,"}");

   }

/**
 *	Description:	Executes one "tick" of the brain simulation for this neuron.
 *					If activity is over some threshold, fires the neuron.
 *					If development stage is not set and development counter is not at zero,
 *					the development counter is decremented.  If it is at zero, then we developSynapse(getActivityStats())
 *					and reset development counter to 30.
 *					mActivity always cleared at the end of this
**/
void Neuron::tick(){
	if(mActivity > mThreshold){
		fire();
	}
	if(mDevelopmentStage == 0){
		if(mDevelopmentCounter == 0){
			ActivityStats& stats = getActivityStats();
			developSynapse(stats);
			mDevelopmentCounter	= 30;					//number of timesteps before next development re-evaluation
		}
		else{ mDevelopmentCounter--;}
	}
	mActivity = 0;
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLStarBasicContextFactory.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:20:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLSTARBASICCONTEXTFACTORY_HXX
#include "XMLStarBasicContextFactory.hxx"
#endif

#ifndef _XMLOFF_XMLEVENTSIMPORTCONTEXT_HXX
#include "XMLEventsImportContext.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;

XMLStarBasicContextFactory::XMLStarBasicContextFactory() :
    sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
    sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
    sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")),
    sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic"))
{
}

XMLStarBasicContextFactory::~XMLStarBasicContextFactory()
{
}

SvXMLImportContext* XMLStarBasicContextFactory::CreateContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList,
    XMLEventsImportContext* rEvents,
    const OUString& rApiEventName,
    const OUString& rApiLanguage)
{
    OUString sLibraryVal;
    OUString sMacroNameVal;

    sal_Int16 nCount = xAttrList->getLength();
    for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = rImport.GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), &sLocalName );

        if (XML_NAMESPACE_SCRIPT == nPrefix)
        {
//          if (IsXMLToken(sLocalName, XML_LIBRARY))
//          {
//              sLibraryVal = xAttrList->getValueByIndex(nAttr);
//          }
//          if (IsXMLToken(sLocalName, XML_LOCATION))
//          {
//              sLibraryVal = xAttrList->getValueByIndex(nAttr);
//                if ( IsXMLToken( sLibraryVal, XML_APPLICATION ) )
//                    sLibraryVal =
//                        OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
//          }
//          else
            if (IsXMLToken(sLocalName, XML_MACRO_NAME))
            {
                sMacroNameVal = xAttrList->getValueByIndex(nAttr);
            }
            // else: ingore
        }
        // else: ignore
    }

    const OUString& rApp = GetXMLToken( XML_APPLICATION );
    const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
    if( sMacroNameVal.getLength() > rApp.getLength()+1 &&
        sMacroNameVal.copy(0,rApp.getLength()).equalsIgnoreAsciiCase( rApp ) &&
        ':' == sMacroNameVal[rApp.getLength()] )
    {
        sLibraryVal = OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
        sMacroNameVal = sMacroNameVal.copy( rApp.getLength()+1 );
    }
    else if( sMacroNameVal.getLength() > rDoc.getLength()+1 &&
        sMacroNameVal.copy(0,rDoc.getLength()).equalsIgnoreAsciiCase( rDoc ) &&
        ':' == sMacroNameVal[rDoc.getLength()] )
    {
        sLibraryVal = rDoc;
        sMacroNameVal = sMacroNameVal.copy( rDoc.getLength()+1 );
    }

    Sequence<PropertyValue> aValues(3);

    // EventType
    aValues[0].Name = sEventType;
    aValues[0].Value <<= sStarBasic;

    // library name
    aValues[1].Name = sLibrary;
    aValues[1].Value <<= sLibraryVal;

    // macro name
    aValues[2].Name = sMacroName;
    aValues[2].Value <<= sMacroNameVal;

    // add values for event now
    rEvents->AddEventValues(rApiEventName, aValues);

    // return dummy context
    return new SvXMLImportContext(rImport, nPrefix, rLocalName);
}
<commit_msg>INTEGRATION: CWS warnings01 (1.6.34); FILE MERGED 2005/11/16 22:47:14 pl 1.6.34.1: #i55991# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLStarBasicContextFactory.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:22:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLSTARBASICCONTEXTFACTORY_HXX
#include "XMLStarBasicContextFactory.hxx"
#endif

#ifndef _XMLOFF_XMLEVENTSIMPORTCONTEXT_HXX
#include "XMLEventsImportContext.hxx"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;

XMLStarBasicContextFactory::XMLStarBasicContextFactory() :
    sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
    sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
    sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")),
    sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic"))
{
}

XMLStarBasicContextFactory::~XMLStarBasicContextFactory()
{
}

SvXMLImportContext* XMLStarBasicContextFactory::CreateContext(
    SvXMLImport& rImport,
    sal_uInt16 p_nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList,
    XMLEventsImportContext* rEvents,
    const OUString& rApiEventName,
    const OUString& /*rApiLanguage*/)
{
    OUString sLibraryVal;
    OUString sMacroNameVal;

    sal_Int16 nCount = xAttrList->getLength();
    for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = rImport.GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(nAttr), &sLocalName );

        if (XML_NAMESPACE_SCRIPT == nPrefix)
        {
//          if (IsXMLToken(sLocalName, XML_LIBRARY))
//          {
//              sLibraryVal = xAttrList->getValueByIndex(nAttr);
//          }
//          if (IsXMLToken(sLocalName, XML_LOCATION))
//          {
//              sLibraryVal = xAttrList->getValueByIndex(nAttr);
//                if ( IsXMLToken( sLibraryVal, XML_APPLICATION ) )
//                    sLibraryVal =
//                        OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
//          }
//          else
            if (IsXMLToken(sLocalName, XML_MACRO_NAME))
            {
                sMacroNameVal = xAttrList->getValueByIndex(nAttr);
            }
            // else: ingore
        }
        // else: ignore
    }

    const OUString& rApp = GetXMLToken( XML_APPLICATION );
    const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
    if( sMacroNameVal.getLength() > rApp.getLength()+1 &&
        sMacroNameVal.copy(0,rApp.getLength()).equalsIgnoreAsciiCase( rApp ) &&
        ':' == sMacroNameVal[rApp.getLength()] )
    {
        sLibraryVal = OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
        sMacroNameVal = sMacroNameVal.copy( rApp.getLength()+1 );
    }
    else if( sMacroNameVal.getLength() > rDoc.getLength()+1 &&
        sMacroNameVal.copy(0,rDoc.getLength()).equalsIgnoreAsciiCase( rDoc ) &&
        ':' == sMacroNameVal[rDoc.getLength()] )
    {
        sLibraryVal = rDoc;
        sMacroNameVal = sMacroNameVal.copy( rDoc.getLength()+1 );
    }

    Sequence<PropertyValue> aValues(3);

    // EventType
    aValues[0].Name = sEventType;
    aValues[0].Value <<= sStarBasic;

    // library name
    aValues[1].Name = sLibrary;
    aValues[1].Value <<= sLibraryVal;

    // macro name
    aValues[2].Name = sMacroName;
    aValues[2].Value <<= sMacroNameVal;

    // add values for event now
    rEvents->AddEventValues(rApiEventName, aValues);

    // return dummy context
    return new SvXMLImportContext(rImport, p_nPrefix, rLocalName);
}
<|endoftext|>


<commit_before>namespace factor
{

static const cell card_starts_inside_object = 0xff;

struct old_space : zone {
	card *object_start_offsets;
	card *object_start_offsets_end;

	old_space(cell size_, cell start_);
	~old_space();

	cell old_space::first_object_in_card(cell card_index);
	cell find_object_containing_card(cell card_index);
	void record_object_start_offset(object *obj);
	object *allot(cell size);
	void clear_object_start_offsets();
	cell next_object_after(factor_vm *myvm, cell scan);
};

}
<commit_msg>vm: fix compile error<commit_after>namespace factor
{

static const cell card_starts_inside_object = 0xff;

struct old_space : zone {
	card *object_start_offsets;
	card *object_start_offsets_end;

	old_space(cell size_, cell start_);
	~old_space();

	cell first_object_in_card(cell card_index);
	cell find_object_containing_card(cell card_index);
	void record_object_start_offset(object *obj);
	object *allot(cell size);
	void clear_object_start_offsets();
	cell next_object_after(factor_vm *myvm, cell scan);
};

}
<|endoftext|>