<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 "vcl/vclevent.hxx"

#include "svdata.hxx"

#include <com/sun/star/accessibility/XAccessible.hpp>

using ::com::sun::star::uno::Reference;
using ::com::sun::star::accessibility::XAccessible;

TYPEINIT0(VclSimpleEvent);
TYPEINIT1(VclWindowEvent, VclSimpleEvent);
TYPEINIT1(VclMenuEvent, VclSimpleEvent);

VclAccessibleEvent::VclAccessibleEvent( sal_uLong n, const Reference<XAccessible>& rxAccessible ) :
    VclSimpleEvent(n),
    mxAccessible(rxAccessible)
{
}

VclAccessibleEvent::~VclAccessibleEvent()
{
}

Reference<XAccessible> VclAccessibleEvent::GetAccessible() const
{
    return mxAccessible;
}

void VclEventListeners::Call( VclSimpleEvent* pEvent ) const
{
    if ( m_aListeners.empty() )
        return;

    // Copy the list, because this can be destroyed when calling a Link...
    std::list<Link> aCopy( m_aListeners );
    std::list<Link>::iterator aIter( aCopy.begin() );
    if( pEvent->IsA( VclWindowEvent::StaticType() ) )
    {
        VclWindowEvent* pWinEvent = static_cast<VclWindowEvent*>(pEvent);
        ImplDelData aDel( pWinEvent->GetWindow() );
        while ( aIter != aCopy.end() && ! aDel.IsDead() )
        {
            (*aIter).Call( pEvent );
            aIter++;
        }
    }
    else
    {
        while ( aIter != aCopy.end() )
        {
            (*aIter).Call( pEvent );
            aIter++;
        }
    }
}

sal_Bool VclEventListeners::Process( VclSimpleEvent* pEvent ) const
{
    if ( m_aListeners.empty() )
        return sal_False;

    sal_Bool bProcessed = sal_False;
    // Copy the list, because this can be destroyed when calling a Link...
    std::list<Link> aCopy( m_aListeners );
    std::list<Link>::iterator aIter( aCopy.begin() );
    while ( aIter != aCopy.end() )
    {
        if( (*aIter).Call( pEvent ) != 0 )
        {
            bProcessed = sal_True;
            break;
        }
        aIter++;
    }
    return bProcessed;
}

void VclEventListeners::addListener( const Link& rListener )
{
    m_aListeners.push_back( rListener );
}

void VclEventListeners::removeListener( const Link& rListener )
{
    m_aListeners.remove( rListener );
}

VclEventListeners2::VclEventListeners2()
{
}

VclEventListeners2::~VclEventListeners2()
{
}

void VclEventListeners2::addListener( const Link& i_rLink )
{
    // ensure uniqueness
    for( std::list< Link >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
    {
        if( *it == i_rLink )
            return;
    }
    m_aListeners.push_back( i_rLink );
}

void VclEventListeners2::removeListener( const Link& i_rLink )
{
    size_t n = m_aIterators.size();
    for( size_t i = 0; i < n; i++ )
    {
        if( m_aIterators[i].m_aIt != m_aListeners.end() && *m_aIterators[i].m_aIt == i_rLink )
        {
            m_aIterators[i].m_bWasInvalidated = true;
            ++m_aIterators[i].m_aIt;
        }
    }
    m_aListeners.remove( i_rLink );
}

void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent )
{
    vcl::DeletionListener aDel( this );

    m_aIterators.push_back(ListenerIt(m_aListeners.begin()));
    size_t nIndex = m_aIterators.size() - 1;
    while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() )
    {
        m_aIterators[ nIndex ].m_aIt->Call( i_pEvent );
        if( m_aIterators[ nIndex ].m_bWasInvalidated )
            // check if the current element was removed and the iterator increased in the meantime
            m_aIterators[ nIndex ].m_bWasInvalidated = false;
        else
            ++m_aIterators[ nIndex ].m_aIt;
    }
    m_aIterators.pop_back();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fdo#47368 - fix one potential re-enterancy hazard around even emission<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 "vcl/vclevent.hxx"

#include "svdata.hxx"

#include <com/sun/star/accessibility/XAccessible.hpp>

using ::com::sun::star::uno::Reference;
using ::com::sun::star::accessibility::XAccessible;

TYPEINIT0(VclSimpleEvent);
TYPEINIT1(VclWindowEvent, VclSimpleEvent);
TYPEINIT1(VclMenuEvent, VclSimpleEvent);

VclAccessibleEvent::VclAccessibleEvent( sal_uLong n, const Reference<XAccessible>& rxAccessible ) :
    VclSimpleEvent(n),
    mxAccessible(rxAccessible)
{
}

VclAccessibleEvent::~VclAccessibleEvent()
{
}

Reference<XAccessible> VclAccessibleEvent::GetAccessible() const
{
    return mxAccessible;
}

void VclEventListeners::Call( VclSimpleEvent* pEvent ) const
{
    if ( m_aListeners.empty() )
        return;

    // Copy the list, because this can be destroyed when calling a Link...
    std::list<Link> aCopy( m_aListeners );
    std::list<Link>::iterator aIter( aCopy.begin() );
    if( pEvent->IsA( VclWindowEvent::StaticType() ) )
    {
        VclWindowEvent* pWinEvent = static_cast<VclWindowEvent*>(pEvent);
        ImplDelData aDel( pWinEvent->GetWindow() );
        while ( aIter != aCopy.end() && ! aDel.IsDead() )
        {
            Link &rLink = *aIter;
            // check this hasn't been removed in some re-enterancy scenario fdo#47368
            if( std::find(m_aListeners.begin(), m_aListeners.end(), rLink) != m_aListeners.end() )
                rLink.Call( pEvent );
            aIter++;
        }
    }
    else
    {
        while ( aIter != aCopy.end() )
        {
            Link &rLink = *aIter;
            if( std::find(m_aListeners.begin(), m_aListeners.end(), rLink) != m_aListeners.end() )
                rLink.Call( pEvent );
            aIter++;
        }
    }
}

sal_Bool VclEventListeners::Process( VclSimpleEvent* pEvent ) const
{
    if ( m_aListeners.empty() )
        return sal_False;

    sal_Bool bProcessed = sal_False;
    // Copy the list, because this can be destroyed when calling a Link...
    std::list<Link> aCopy( m_aListeners );
    std::list<Link>::iterator aIter( aCopy.begin() );
    while ( aIter != aCopy.end() )
    {
        if( (*aIter).Call( pEvent ) != 0 )
        {
            bProcessed = sal_True;
            break;
        }
        aIter++;
    }
    return bProcessed;
}

void VclEventListeners::addListener( const Link& rListener )
{
    m_aListeners.push_back( rListener );
}

void VclEventListeners::removeListener( const Link& rListener )
{
    m_aListeners.remove( rListener );
}

VclEventListeners2::VclEventListeners2()
{
}

VclEventListeners2::~VclEventListeners2()
{
}

void VclEventListeners2::addListener( const Link& i_rLink )
{
    // ensure uniqueness
    for( std::list< Link >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
    {
        if( *it == i_rLink )
            return;
    }
    m_aListeners.push_back( i_rLink );
}

void VclEventListeners2::removeListener( const Link& i_rLink )
{
    size_t n = m_aIterators.size();
    for( size_t i = 0; i < n; i++ )
    {
        if( m_aIterators[i].m_aIt != m_aListeners.end() && *m_aIterators[i].m_aIt == i_rLink )
        {
            m_aIterators[i].m_bWasInvalidated = true;
            ++m_aIterators[i].m_aIt;
        }
    }
    m_aListeners.remove( i_rLink );
}

void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent )
{
    vcl::DeletionListener aDel( this );

    m_aIterators.push_back(ListenerIt(m_aListeners.begin()));
    size_t nIndex = m_aIterators.size() - 1;
    while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() )
    {
        m_aIterators[ nIndex ].m_aIt->Call( i_pEvent );
        if( m_aIterators[ nIndex ].m_bWasInvalidated )
            // check if the current element was removed and the iterator increased in the meantime
            m_aIterators[ nIndex ].m_bWasInvalidated = false;
        else
            ++m_aIterators[ nIndex ].m_aIt;
    }
    m_aIterators.pop_back();
}

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


<commit_before><commit_msg>Fix radial gradient offset<commit_after><|endoftext|>


<commit_before><commit_msg>vcl: no such thing as GtkSalInstance, remove commented code<commit_after><|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX64M/RX71M グループ・フラッシュ 定義
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/io_utils.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  フラッシュ・メモリー制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct flash_t {

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E プロテクトレジスタ（FWEPROR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fwepror_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 2> FLWE;
		};
		static fwepror_t<0x0008C296> FWEPROR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュアクセスステータスレジスタ（FASTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fastat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_rw_t<io_, bitpos::B0>  ECRCT;
#endif
			bit_rw_t<io_, bitpos::B3>  DFAE;
			bit_rw_t<io_, bitpos::B4>  CMDLK;
			bit_rw_t<io_, bitpos::B7>  CFAE;

		};
		static fastat_t<0x007FE010> FASTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュアクセスエラー割り込み許可レジスタ（FAEINT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct faeint_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_rw_t<io_, bitpos::B0>  ECRCTIE;
#endif
			bit_rw_t<io_, bitpos::B3>  DFAEIE;
			bit_rw_t<io_, bitpos::B4>  CMDLKIE;
			bit_rw_t<io_, bitpos::B7>  CFAEIE;

		};
		static faeint_t<0x007FE014> FAEINT;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュレディ割り込み許可レジスタ（FRDYIE）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct frdyie_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  FRDYIE;
		};
		static frdyie_t<0x007FE018> FRDYIE;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンド処理開始アドレスレジスタ（FSADDR）
		*/
		//-----------------------------------------------------------------//
		static rw32_t<0x007FE030> FSADDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンド処理終了アドレスレジスタ（FEADDR）
		*/
		//-----------------------------------------------------------------//
		static rw32_t<0x007FE034> FEADDR;

#if defined(SIG_RX64M) || defined(SIG_RX71M)
		//-----------------------------------------------------------------//
		/*!
			@brief  FCURAM イネーブルレジスタ（FCURAME）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcurame_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FCRME;
			bit_rw_t <io_, bitpos::B1>     FRAMTRAN;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fcurame_t<0x007FE054> FCURAME;
#endif

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュステータスレジスタ（FSTATR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fstatr_t : public ro32_t<base> {
			typedef ro32_t<base> io_;
			using io_::operator ();
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_ro_t <io_, bitpos::B0>   FRCRCT;
			bit_ro_t <io_, bitpos::B1>   FRDTCT;
#endif
			bit_ro_t <io_, bitpos::B6>   FLWEERR;
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_ro_t <io_, bitpos::B7>   FCUERR;
#endif
			bit_ro_t <io_, bitpos::B8>   PRGSPD;
			bit_ro_t <io_, bitpos::B9>   ERSSPD;
			bit_ro_t <io_, bitpos::B10>  DBFULL;
			bit_ro_t <io_, bitpos::B11>  SUSRDY;
			bit_ro_t <io_, bitpos::B12>  PRGERR;
			bit_ro_t <io_, bitpos::B13>  ERSERR;
			bit_ro_t <io_, bitpos::B14>  ILGERR;
			bit_ro_t <io_, bitpos::B15>  FRDY;
#if defined(SIG_RX65N)

#endif
		};
		static fstatr_t<0x007FE080> FSTATR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E モードエントリレジスタ（FENTRYR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fentryr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FENTRYC;
			bit_rw_t <io_, bitpos::B7>     FENTRYD;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fentryr_t<0x007FE084> FENTRYR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュプロテクトレジスタ（FPROTR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fprotr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FPROTCN;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fprotr_t<0x007FE088> FPROTR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ設定初期化レジスタ（FSUINITR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fsuinitr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     SUINIT;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fsuinitr_t<0x007FE08C> FSUINITR;

		//-----------------------------------------------------------------//
		/*!
			@brief  ロックビットステータスレジスタ（FLKSTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct flkstat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>  FLOCKST;
		};
		static flkstat_t<0x007FE090> FLKSTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンドレジスタ（FCMDR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcmdr_t : public ro16_t<base> {
			typedef ro16_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 8>  PCMDR;
			bits_ro_t<io_, bitpos::B8, 8>  CMDDR;
		};
		static fcmdr_t<0x007FE0A0> FCMDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E ステータスレジスタ（FPESTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpestat_t : public ro16_t<base> {
			typedef ro16_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 8>  PEERRST;
		};
		static fpestat_t<0x007FE0C0> FPESTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュブランクチェック制御レジスタ（FBCCNT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fbccnt_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  BCDIR;
		};
		static fbccnt_t<0x007FE0D0> FBCCNT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュブランクチェックステータスレジスタ（FBCSTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fbcstat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  BCST;
		};
		static fbcstat_t<0x007FE0D4> FBCSTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュ書き込み開始アドレスレジスタ（FPSADDR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpsaddr_t : public ro32_t<base> {
			typedef ro32_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 19>  PSADR;
		};
		static fpsaddr_t<0x007FE0D8> FPSADDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ処理切り替えレジスタ（FCPSR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcpsr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  ESUSPMD;
		};
		static fcpsr_t<0x007FE0E0> FCPSR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ処理クロック通知レジスタ（FPCKAR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpckar_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 8>  PCKA;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fpckar_t<0x007FE0E4> FPCKAR;
	};
	typedef flash_t FLASH;
}
<commit_msg>update: RX65N<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX64M/RX71M グループ・フラッシュ 定義
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/io_utils.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  フラッシュ・メモリー制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct flash_t {

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E プロテクトレジスタ（FWEPROR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fwepror_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 2> FLWE;
		};
		static fwepror_t<0x0008C296> FWEPROR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュアクセスステータスレジスタ（FASTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fastat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_rw_t<io_, bitpos::B0>  ECRCT;
#endif
			bit_rw_t<io_, bitpos::B3>  DFAE;
			bit_rw_t<io_, bitpos::B4>  CMDLK;
			bit_rw_t<io_, bitpos::B7>  CFAE;

		};
		static fastat_t<0x007FE010> FASTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュアクセスエラー割り込み許可レジスタ（FAEINT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct faeint_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_rw_t<io_, bitpos::B0>  ECRCTIE;
#endif
			bit_rw_t<io_, bitpos::B3>  DFAEIE;
			bit_rw_t<io_, bitpos::B4>  CMDLKIE;
			bit_rw_t<io_, bitpos::B7>  CFAEIE;

		};
		static faeint_t<0x007FE014> FAEINT;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュレディ割り込み許可レジスタ（FRDYIE）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct frdyie_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  FRDYIE;
		};
		static frdyie_t<0x007FE018> FRDYIE;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンド処理開始アドレスレジスタ（FSADDR）
		*/
		//-----------------------------------------------------------------//
		static rw32_t<0x007FE030> FSADDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンド処理終了アドレスレジスタ（FEADDR）
		*/
		//-----------------------------------------------------------------//
		static rw32_t<0x007FE034> FEADDR;

#if defined(SIG_RX64M) || defined(SIG_RX71M) || defined(SIG_RX65N)
		//-----------------------------------------------------------------//
		/*!
			@brief  FCURAM イネーブルレジスタ（FCURAME）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcurame_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FCRME;
			bit_rw_t <io_, bitpos::B1>     FRAMTRAN;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fcurame_t<0x007FE054> FCURAME;
#endif

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュステータスレジスタ（FSTATR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fstatr_t : public ro32_t<base> {
			typedef ro32_t<base> io_;
			using io_::operator ();
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_ro_t <io_, bitpos::B0>   FRCRCT;
			bit_ro_t <io_, bitpos::B1>   FRDTCT;
#endif
			bit_ro_t <io_, bitpos::B6>   FLWEERR;
#if defined(SIG_RX64M) || defined(SIG_RX71M)
			bit_ro_t <io_, bitpos::B7>   FCUERR;
#endif
			bit_ro_t <io_, bitpos::B8>   PRGSPD;
			bit_ro_t <io_, bitpos::B9>   ERSSPD;
			bit_ro_t <io_, bitpos::B10>  DBFULL;
			bit_ro_t <io_, bitpos::B11>  SUSRDY;
			bit_ro_t <io_, bitpos::B12>  PRGERR;
			bit_ro_t <io_, bitpos::B13>  ERSERR;
			bit_ro_t <io_, bitpos::B14>  ILGERR;
			bit_ro_t <io_, bitpos::B15>  FRDY;
#if defined(SIG_RX65N)

#endif
		};
		static fstatr_t<0x007FE080> FSTATR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E モードエントリレジスタ（FENTRYR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fentryr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FENTRYC;
			bit_rw_t <io_, bitpos::B7>     FENTRYD;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fentryr_t<0x007FE084> FENTRYR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュプロテクトレジスタ（FPROTR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fprotr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     FPROTCN;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fprotr_t<0x007FE088> FPROTR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ設定初期化レジスタ（FSUINITR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fsuinitr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     SUINIT;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fsuinitr_t<0x007FE08C> FSUINITR;

		//-----------------------------------------------------------------//
		/*!
			@brief  ロックビットステータスレジスタ（FLKSTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct flkstat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>  FLOCKST;
		};
		static flkstat_t<0x007FE090> FLKSTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  FACI コマンドレジスタ（FCMDR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcmdr_t : public ro16_t<base> {
			typedef ro16_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 8>  PCMDR;
			bits_ro_t<io_, bitpos::B8, 8>  CMDDR;
		};
		static fcmdr_t<0x007FE0A0> FCMDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュ P/E ステータスレジスタ（FPESTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpestat_t : public ro16_t<base> {
			typedef ro16_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 8>  PEERRST;
		};
		static fpestat_t<0x007FE0C0> FPESTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュブランクチェック制御レジスタ（FBCCNT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fbccnt_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  BCDIR;
		};
		static fbccnt_t<0x007FE0D0> FBCCNT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュブランクチェックステータスレジスタ（FBCSTAT）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fbcstat_t : public rw8_t<base> {
			typedef rw8_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  BCST;
		};
		static fbcstat_t<0x007FE0D4> FBCSTAT;

		//-----------------------------------------------------------------//
		/*!
			@brief  データフラッシュ書き込み開始アドレスレジスタ（FPSADDR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpsaddr_t : public ro32_t<base> {
			typedef ro32_t<base> io_;
			using io_::operator ();

			bits_ro_t<io_, bitpos::B0, 19>  PSADR;
		};
		static fpsaddr_t<0x007FE0D8> FPSADDR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ処理切り替えレジスタ（FCPSR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fcpsr_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t<io_, bitpos::B0>  ESUSPMD;
		};
		static fcpsr_t<0x007FE0E0> FCPSR;

		//-----------------------------------------------------------------//
		/*!
			@brief  フラッシュシーケンサ処理クロック通知レジスタ（FPCKAR）
			@param[in]	base	ベース
		*/
		//-----------------------------------------------------------------//
		template <uint32_t base>
		struct fpckar_t : public rw16_t<base> {
			typedef rw16_t<base> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 8>  PCKA;
			bits_rw_t<io_, bitpos::B8, 8>  KEY;
		};
		static fpckar_t<0x007FE0E4> FPCKAR;
	};
	typedef flash_t FLASH;
}
<|endoftext|>


<commit_before>#include "debug.h"

#include <thread>

#include "../../NULLC/nullc.h"
#include "../../NULLC/nullc_debug.h"

#include "context.h"
#include "handler.h"
#include "schema.h"

unsigned OnDebugBreak(void *context, unsigned instruction)
{
	Context &ctx = *(Context*)context;

	unsigned moduleIndex = 0;
	auto line = ConvertInstructionToLineAndModule(instruction, moduleIndex);

	// Skip instructions on same line
	unsigned lastAction = ctx.breakpointAction.load();

	if(lastAction == NULLC_BREAK_STEP || lastAction == NULLC_BREAK_STEP_INTO || lastAction == NULLC_BREAK_STEP_OUT)
	{
		if(ctx.breakpointLastLine.load() == line && ctx.breakpointLastModule.load() == moduleIndex)
			return lastAction;
	}

	//SendEventStopped(ctx, StoppedEventData("breakpoint", "Breakpoint Hit", 1, false, "Manual Breakpoint", true));

	ctx.breakpointActive.store(true);

	ctx.breakpointLastLine.store(line);
	ctx.breakpointLastModule.store(moduleIndex);

	if(ctx.infoMode)
		fprintf(stderr, "INFO: Breaking on instruction %d at line %d of module %d\r\n", instruction, line, moduleIndex);

	SendEventStopped(ctx, StoppedEventData("breakpoint", 1));

	{
		std::unique_lock<std::mutex> lock(ctx.breakpointMutex);

		ctx.breakpointWait.wait(lock);
	}

	ctx.breakpointActive.store(false);

	return ctx.breakpointAction.load();
}

void ApplicationThread(Context &ctx)
{
	if(nullcRunFunction(NULL))
	{
		const char *val = nullcGetResult();

		nullcFinalize();

		SendEventOutput(ctx, OutputEventData("console", val));

		ctx.running.store(false);

		SendEventThread(ctx, ThreadEventData("exited", 1));
		SendEventExited(ctx, atoi(val));
		SendEventTerminated(ctx);
	}
	else
	{
		SendEventOutput(ctx, OutputEventData("stderr", nullcGetLastError()));

		ctx.running.store(false);

		SendEventThread(ctx, ThreadEventData("exited", 1));
		SendEventExited(ctx, -1);

		if(!ctx.pendingRestart.load())
			SendEventTerminated(ctx);
	}
}

void LaunchApplicationThread(Context &ctx)
{
	ctx.applicationThread = std::thread([&ctx]{
		ApplicationThread(ctx);
	});
}

std::string NormalizePath(std::string path)
{
	// Lowercase and transform folder slashes in a consistent way
	for(auto &&el : path)
	{
		if(el == '\\')
			el = '/';
		else if(isalpha(el))
			el = (char)tolower(el);
	}

	return path;
}

const char* GetModuleSourceCode(Context &ctx, const Source& source)
{
	// Name is required
	if(!source.name)
		return nullptr;

	std::string name = NormalizePath(*source.name);

	auto symbols = nullcDebugSymbols(nullptr);

	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < moduleCount; i++)
	{
		ExternModuleInfo &moduleInfo = modules[i];

		std::string moduleName = NormalizePath(symbols + moduleInfo.nameOffset);

		if(const char *pos = strstr(moduleName.c_str(), name.c_str()))
		{
			if(strlen(pos) == name.length())
				return fullSource + modules[i].sourceOffset;
		}
	}

	const char *mainModuleSource = fullSource + modules[moduleCount - 1].sourceOffset + modules[moduleCount - 1].sourceSize;

	std::string program = NormalizePath(*ctx.launchArgs.program);

	if(const char *pos = strstr(program.c_str(), name.c_str()))
	{
		if(strlen(pos) == name.length())
			return mainModuleSource;
	}

	return nullptr;
}

const char* GetLineStart(const char *sourceCode, int line)
{
	const char *start = sourceCode;
	int startLine = 0;

	while(*start && startLine < line)
	{
		if(*start == '\r')
		{
			start++;

			if(*start == '\n')
				start++;

			startLine++;
		}
		else if(*start == '\n')
		{
			start++;

			startLine++;
		}
		else
		{
			start++;
		}
	}

	return start;
}

const char* GetLineEnd(const char *lineStart)
{
	const char *pos = lineStart;

	while(*pos)
	{
		if(*pos == '\r')
			return pos;

		if(*pos == '\n')
			return pos;

		pos++;
	}

	return pos;
}

unsigned ConvertPositionToInstruction(unsigned lineStartOffset, unsigned lineEndOffset)
{
	unsigned infoSize = 0;
	auto sourceInfo = nullcDebugSourceInfo(&infoSize);

	// Find instruction
	for(unsigned i = 0; i < infoSize; i++)
	{
		if(sourceInfo[i].sourceOffset >= lineStartOffset && sourceInfo[i].sourceOffset <= lineEndOffset)
			return sourceInfo[i].instruction;
	}

	return 0;
}

unsigned ConvertLineToInstruction(const char *sourceCode, int line)
{
	const char *lineStart = GetLineStart(sourceCode, line);

	if(!*lineStart)
		return 0;

	const char *lineEnd = GetLineEnd(lineStart);

	auto fullSource = nullcDebugSource();

	unsigned lineStartOffset = unsigned(lineStart - fullSource);
	unsigned lineEndOffset = unsigned(lineEnd - fullSource);

	return ConvertPositionToInstruction(lineStartOffset, lineEndOffset);
}

const char* GetInstructionSourceLocation(unsigned instruction)
{
	unsigned infoSize = 0;
	auto sourceInfo = nullcDebugSourceInfo(&infoSize);

	if(!infoSize)
		return nullptr;

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < infoSize; i++)
	{
		if(instruction == sourceInfo[i].instruction)
			return fullSource + sourceInfo[i].sourceOffset;

		if(i + 1 < infoSize && instruction < sourceInfo[i + 1].instruction)
			return fullSource + sourceInfo[i].sourceOffset;
	}

	return fullSource + sourceInfo[infoSize - 1].sourceOffset;
}

unsigned GetSourceLocationModuleIndex(const char *sourceLocation)
{
	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < moduleCount; i++)
	{
		auto &moduleInfo = modules[i];

		const char *start = fullSource + moduleInfo.sourceOffset;
		const char *end = start + moduleInfo.sourceSize;

		if(sourceLocation >= start && sourceLocation < end)
			return i;
	}

	return ~0u;
}

unsigned ConvertSourceLocationToLine(const char *sourceLocation, unsigned moduleIndex, unsigned &column)
{
	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	const char *sourceStart = fullSource + (moduleIndex < moduleCount ? modules[moduleIndex].sourceOffset : modules[moduleCount - 1].sourceOffset + modules[moduleCount - 1].sourceSize);

	unsigned line = 0;

	const char *pos = sourceStart;
	const char *lastLineStart = pos;

	while(pos < sourceLocation)
	{
		if(*pos == '\r')
		{
			line++;

			pos++;

			if(*pos == '\n')
				pos++;

			lastLineStart = pos;
		}
		else if(*pos == '\n')
		{
			line++;

			pos++;

			lastLineStart = pos;
		}
		else
		{
			pos++;
		}
	}

	column = int(pos - lastLineStart);

	return line;
}

unsigned ConvertInstructionToLineAndModule(unsigned instruction, unsigned &moduleIndex)
{
	auto sourceLocation = GetInstructionSourceLocation(instruction);

	moduleIndex = GetSourceLocationModuleIndex(sourceLocation);

	unsigned column = 0;
	return ConvertSourceLocationToLine(sourceLocation, moduleIndex, column);
}

std::string GetBasicVariableInfo(unsigned typeIndex, char* ptr, bool hex)
{
	char buf[1024];

	unsigned typeCount = 0;
	auto types = nullcDebugTypeInfo(&typeCount);

	auto &type = types[typeIndex];

	if(type.subCat == ExternTypeInfo::CAT_POINTER)
	{
		snprintf(buf, 256, "0x%p", *(void**)ptr);
		return buf;
	}

	if(type.subCat == ExternTypeInfo::CAT_CLASS)
	{
		if(type.type == ExternTypeInfo::TYPE_INT)
		{
			auto symbols = nullcDebugSymbols(nullptr);

			const char *memberName = symbols + type.offsetToName + (unsigned int)strlen(symbols + type.offsetToName) + 1;

			for(unsigned i = 0; i < *(unsigned*)ptr; i++)
				memberName += strlen(memberName) + 1;

			snprintf(buf, 256, hex ? "%s (0x%x)" : "%s (%d)", memberName, *(int*)ptr);
			return buf;
		}

		return "{}";
	}

	if(type.subCat == ExternTypeInfo::CAT_ARRAY)
	{
		if(type.arrSize == ~0u)
		{
			NULLCArray &arr = *(NULLCArray*)ptr;

			snprintf(buf, 256, "0x%p [%d]", arr.ptr, arr.len);
			return buf;
		}

		snprintf(buf, 256, "[%d]", type.arrSize);
		return buf;
	}

	if(type.subCat == ExternTypeInfo::CAT_FUNCTION)
	{
		unsigned functionCount = 0;
		auto functions = nullcDebugFunctionInfo(&functionCount);

		unsigned typeExtraCount = 0;
		auto typeExtras = nullcDebugTypeExtraInfo(&typeExtraCount);

		unsigned localCount = 0;
		auto locals = nullcDebugLocalInfo(&localCount);

		auto symbols = nullcDebugSymbols(nullptr);

		NULLCFuncPtr &funcPtr = *(NULLCFuncPtr*)ptr;

		auto &function = functions[funcPtr.id];
		auto &returnType = types[typeExtras[type.memberOffset].type];

		char *pos = buf;
		*pos = 0;

		pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), "%s %s(", symbols + returnType.offsetToName, symbols + function.offsetToName);

		for(unsigned i = 0; i < function.paramCount; i++)
		{
			auto &localInfo = locals[function.offsetToFirstLocal + i];

			pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), "%s %s%s", symbols + types[localInfo.type].offsetToName, symbols + localInfo.offsetToName, i == function.paramCount - 1 ? "" : ", ");
		}
		pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), ")");

		return buf;
	}

	if(typeIndex == NULLC_TYPE_BOOL)
	{
		snprintf(buf, 256, *(unsigned char*)ptr ? "true" : "false");
		return buf;
	}

	if(typeIndex == NULLC_TYPE_TYPEID)
	{
		auto symbols = nullcDebugSymbols(nullptr);

		snprintf(buf, 256, symbols + types[*(int*)ptr].offsetToName);
		return buf;
	}

	switch(type.type)
	{
	case ExternTypeInfo::TYPE_CHAR:
		if(*(char*)ptr > 0)
			snprintf(buf, 256, hex ? "'%c' (0x%x)" : "'%c' (%d)", *(char*)ptr, (int)*(char*)ptr);
		else
			snprintf(buf, 256, hex ? "0x%x" : "%d", *(char*)ptr);
		break;
	case ExternTypeInfo::TYPE_SHORT:
		snprintf(buf, 256, "%d", *(short*)ptr);
		break;
	case ExternTypeInfo::TYPE_INT:
		snprintf(buf, 256, hex ? "0x%x" : "%d", *(int*)ptr);
		break;
	case ExternTypeInfo::TYPE_LONG:
		snprintf(buf, 256, hex ? "0x%llx" : "%lld", *(long long*)ptr);
		break;
	case ExternTypeInfo::TYPE_FLOAT:
		snprintf(buf, 256, "%f", *(float*)ptr);
		break;
	case ExternTypeInfo::TYPE_DOUBLE:
		snprintf(buf, 256, "%f", *(double*)ptr);
		break;
	default:
		snprintf(buf, 256, "...");
	}

	return buf;
}

bool SetBasicVariableValue(unsigned typeIndex, char* ptr, const std::string& value)
{
	unsigned typeCount = 0;
	auto types = nullcDebugTypeInfo(&typeCount);

	auto &type = types[typeIndex];

	if(type.subCat == ExternTypeInfo::CAT_POINTER)
		return false;

	if(type.subCat == ExternTypeInfo::CAT_CLASS)
	{
		if(type.type == ExternTypeInfo::TYPE_INT)
		{
			*(int*)ptr = strtol(value.c_str(), nullptr, 10);
			return true;
		}

		return false;
	}

	if(type.subCat == ExternTypeInfo::CAT_ARRAY)
		return false;

	if(type.subCat == ExternTypeInfo::CAT_FUNCTION)
		return false;

	switch(type.type)
	{
	case ExternTypeInfo::TYPE_CHAR:
		if(typeIndex == NULLC_TYPE_BOOL)
		{
			if(value == "true")
				*(char*)ptr = 1;
			else if(value == "false")
				*(char*)ptr = 0;
			else
				*(char*)ptr = strtol(value.c_str(), nullptr, 10) != 0;
		}
		else
		{
			*(char*)ptr = (char)strtol(value.c_str(), nullptr, 10);
		}
		break;
	case ExternTypeInfo::TYPE_SHORT:
		*(short*)ptr = (short)strtol(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_INT:
		*(int*)ptr = strtol(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_LONG:
		*(long long*)ptr = strtoll(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_FLOAT:
		*(float*)ptr = strtof(value.c_str(), nullptr);
		break;
	case ExternTypeInfo::TYPE_DOUBLE:
		*(double*)ptr = strtod(value.c_str(), nullptr);
		break;
	default:
		return false;
	}

	return true;
}

unsigned OnIoWrite(void *context, char *data, unsigned length)
{
	Context &ctx = *(Context*)context;

	SendEventOutput(ctx, OutputEventData("stdout", std::string(data, data + length)));

	return length;
}
<commit_msg>Extension update: fixed unsafe formatting<commit_after>#include "debug.h"

#include <thread>

#include "../../NULLC/nullc.h"
#include "../../NULLC/nullc_debug.h"

#include "context.h"
#include "handler.h"
#include "schema.h"

unsigned OnDebugBreak(void *context, unsigned instruction)
{
	Context &ctx = *(Context*)context;

	unsigned moduleIndex = 0;
	auto line = ConvertInstructionToLineAndModule(instruction, moduleIndex);

	// Skip instructions on same line
	unsigned lastAction = ctx.breakpointAction.load();

	if(lastAction == NULLC_BREAK_STEP || lastAction == NULLC_BREAK_STEP_INTO || lastAction == NULLC_BREAK_STEP_OUT)
	{
		if(ctx.breakpointLastLine.load() == line && ctx.breakpointLastModule.load() == moduleIndex)
			return lastAction;
	}

	//SendEventStopped(ctx, StoppedEventData("breakpoint", "Breakpoint Hit", 1, false, "Manual Breakpoint", true));

	ctx.breakpointActive.store(true);

	ctx.breakpointLastLine.store(line);
	ctx.breakpointLastModule.store(moduleIndex);

	if(ctx.infoMode)
		fprintf(stderr, "INFO: Breaking on instruction %d at line %d of module %d\r\n", instruction, line, moduleIndex);

	SendEventStopped(ctx, StoppedEventData("breakpoint", 1));

	{
		std::unique_lock<std::mutex> lock(ctx.breakpointMutex);

		ctx.breakpointWait.wait(lock);
	}

	ctx.breakpointActive.store(false);

	return ctx.breakpointAction.load();
}

void ApplicationThread(Context &ctx)
{
	if(nullcRunFunction(NULL))
	{
		const char *val = nullcGetResult();

		nullcFinalize();

		SendEventOutput(ctx, OutputEventData("console", val));

		ctx.running.store(false);

		SendEventThread(ctx, ThreadEventData("exited", 1));
		SendEventExited(ctx, atoi(val));
		SendEventTerminated(ctx);
	}
	else
	{
		SendEventOutput(ctx, OutputEventData("stderr", nullcGetLastError()));

		ctx.running.store(false);

		SendEventThread(ctx, ThreadEventData("exited", 1));
		SendEventExited(ctx, -1);

		if(!ctx.pendingRestart.load())
			SendEventTerminated(ctx);
	}
}

void LaunchApplicationThread(Context &ctx)
{
	ctx.applicationThread = std::thread([&ctx]{
		ApplicationThread(ctx);
	});
}

std::string NormalizePath(std::string path)
{
	// Lowercase and transform folder slashes in a consistent way
	for(auto &&el : path)
	{
		if(el == '\\')
			el = '/';
		else if(isalpha(el))
			el = (char)tolower(el);
	}

	return path;
}

const char* GetModuleSourceCode(Context &ctx, const Source& source)
{
	// Name is required
	if(!source.name)
		return nullptr;

	std::string name = NormalizePath(*source.name);

	auto symbols = nullcDebugSymbols(nullptr);

	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < moduleCount; i++)
	{
		ExternModuleInfo &moduleInfo = modules[i];

		std::string moduleName = NormalizePath(symbols + moduleInfo.nameOffset);

		if(const char *pos = strstr(moduleName.c_str(), name.c_str()))
		{
			if(strlen(pos) == name.length())
				return fullSource + modules[i].sourceOffset;
		}
	}

	const char *mainModuleSource = fullSource + modules[moduleCount - 1].sourceOffset + modules[moduleCount - 1].sourceSize;

	std::string program = NormalizePath(*ctx.launchArgs.program);

	if(const char *pos = strstr(program.c_str(), name.c_str()))
	{
		if(strlen(pos) == name.length())
			return mainModuleSource;
	}

	return nullptr;
}

const char* GetLineStart(const char *sourceCode, int line)
{
	const char *start = sourceCode;
	int startLine = 0;

	while(*start && startLine < line)
	{
		if(*start == '\r')
		{
			start++;

			if(*start == '\n')
				start++;

			startLine++;
		}
		else if(*start == '\n')
		{
			start++;

			startLine++;
		}
		else
		{
			start++;
		}
	}

	return start;
}

const char* GetLineEnd(const char *lineStart)
{
	const char *pos = lineStart;

	while(*pos)
	{
		if(*pos == '\r')
			return pos;

		if(*pos == '\n')
			return pos;

		pos++;
	}

	return pos;
}

unsigned ConvertPositionToInstruction(unsigned lineStartOffset, unsigned lineEndOffset)
{
	unsigned infoSize = 0;
	auto sourceInfo = nullcDebugSourceInfo(&infoSize);

	// Find instruction
	for(unsigned i = 0; i < infoSize; i++)
	{
		if(sourceInfo[i].sourceOffset >= lineStartOffset && sourceInfo[i].sourceOffset <= lineEndOffset)
			return sourceInfo[i].instruction;
	}

	return 0;
}

unsigned ConvertLineToInstruction(const char *sourceCode, int line)
{
	const char *lineStart = GetLineStart(sourceCode, line);

	if(!*lineStart)
		return 0;

	const char *lineEnd = GetLineEnd(lineStart);

	auto fullSource = nullcDebugSource();

	unsigned lineStartOffset = unsigned(lineStart - fullSource);
	unsigned lineEndOffset = unsigned(lineEnd - fullSource);

	return ConvertPositionToInstruction(lineStartOffset, lineEndOffset);
}

const char* GetInstructionSourceLocation(unsigned instruction)
{
	unsigned infoSize = 0;
	auto sourceInfo = nullcDebugSourceInfo(&infoSize);

	if(!infoSize)
		return nullptr;

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < infoSize; i++)
	{
		if(instruction == sourceInfo[i].instruction)
			return fullSource + sourceInfo[i].sourceOffset;

		if(i + 1 < infoSize && instruction < sourceInfo[i + 1].instruction)
			return fullSource + sourceInfo[i].sourceOffset;
	}

	return fullSource + sourceInfo[infoSize - 1].sourceOffset;
}

unsigned GetSourceLocationModuleIndex(const char *sourceLocation)
{
	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	for(unsigned i = 0; i < moduleCount; i++)
	{
		auto &moduleInfo = modules[i];

		const char *start = fullSource + moduleInfo.sourceOffset;
		const char *end = start + moduleInfo.sourceSize;

		if(sourceLocation >= start && sourceLocation < end)
			return i;
	}

	return ~0u;
}

unsigned ConvertSourceLocationToLine(const char *sourceLocation, unsigned moduleIndex, unsigned &column)
{
	unsigned moduleCount = 0;
	auto modules = nullcDebugModuleInfo(&moduleCount);

	auto fullSource = nullcDebugSource();

	const char *sourceStart = fullSource + (moduleIndex < moduleCount ? modules[moduleIndex].sourceOffset : modules[moduleCount - 1].sourceOffset + modules[moduleCount - 1].sourceSize);

	unsigned line = 0;

	const char *pos = sourceStart;
	const char *lastLineStart = pos;

	while(pos < sourceLocation)
	{
		if(*pos == '\r')
		{
			line++;

			pos++;

			if(*pos == '\n')
				pos++;

			lastLineStart = pos;
		}
		else if(*pos == '\n')
		{
			line++;

			pos++;

			lastLineStart = pos;
		}
		else
		{
			pos++;
		}
	}

	column = int(pos - lastLineStart);

	return line;
}

unsigned ConvertInstructionToLineAndModule(unsigned instruction, unsigned &moduleIndex)
{
	auto sourceLocation = GetInstructionSourceLocation(instruction);

	moduleIndex = GetSourceLocationModuleIndex(sourceLocation);

	unsigned column = 0;
	return ConvertSourceLocationToLine(sourceLocation, moduleIndex, column);
}

std::string GetBasicVariableInfo(unsigned typeIndex, char* ptr, bool hex)
{
	char buf[1024];

	unsigned typeCount = 0;
	auto types = nullcDebugTypeInfo(&typeCount);

	auto &type = types[typeIndex];

	if(type.subCat == ExternTypeInfo::CAT_POINTER)
	{
		snprintf(buf, 256, "0x%p", *(void**)ptr);
		return buf;
	}

	if(type.subCat == ExternTypeInfo::CAT_CLASS)
	{
		if(type.type == ExternTypeInfo::TYPE_INT)
		{
			auto symbols = nullcDebugSymbols(nullptr);

			const char *memberName = symbols + type.offsetToName + (unsigned int)strlen(symbols + type.offsetToName) + 1;

			for(unsigned i = 0; i < *(unsigned*)ptr; i++)
				memberName += strlen(memberName) + 1;

			snprintf(buf, 256, hex ? "%s (0x%x)" : "%s (%d)", memberName, *(int*)ptr);
			return buf;
		}

		return "{}";
	}

	if(type.subCat == ExternTypeInfo::CAT_ARRAY)
	{
		if(type.arrSize == ~0u)
		{
			NULLCArray &arr = *(NULLCArray*)ptr;

			snprintf(buf, 256, "0x%p [%d]", arr.ptr, arr.len);
			return buf;
		}

		snprintf(buf, 256, "[%d]", type.arrSize);
		return buf;
	}

	if(type.subCat == ExternTypeInfo::CAT_FUNCTION)
	{
		unsigned functionCount = 0;
		auto functions = nullcDebugFunctionInfo(&functionCount);

		unsigned typeExtraCount = 0;
		auto typeExtras = nullcDebugTypeExtraInfo(&typeExtraCount);

		unsigned localCount = 0;
		auto locals = nullcDebugLocalInfo(&localCount);

		auto symbols = nullcDebugSymbols(nullptr);

		NULLCFuncPtr &funcPtr = *(NULLCFuncPtr*)ptr;

		auto &function = functions[funcPtr.id];
		auto &returnType = types[typeExtras[type.memberOffset].type];

		char *pos = buf;
		*pos = 0;

		pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), "%s %s(", symbols + returnType.offsetToName, symbols + function.offsetToName);

		for(unsigned i = 0; i < function.paramCount; i++)
		{
			auto &localInfo = locals[function.offsetToFirstLocal + i];

			pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), "%s %s%s", symbols + types[localInfo.type].offsetToName, symbols + localInfo.offsetToName, i == function.paramCount - 1 ? "" : ", ");
		}
		pos += NULLC::SafeSprintf(pos, 1024 - int(pos - buf), ")");

		return buf;
	}

	if(typeIndex == NULLC_TYPE_BOOL)
	{
		snprintf(buf, 256, *(unsigned char*)ptr ? "true" : "false");
		return buf;
	}

	if(typeIndex == NULLC_TYPE_TYPEID)
	{
		auto symbols = nullcDebugSymbols(nullptr);

		snprintf(buf, 256, "%s", symbols + types[*(int*)ptr].offsetToName);
		return buf;
	}

	switch(type.type)
	{
	case ExternTypeInfo::TYPE_CHAR:
		if(*(char*)ptr > 0)
			snprintf(buf, 256, hex ? "'%c' (0x%x)" : "'%c' (%d)", *(char*)ptr, (int)*(char*)ptr);
		else
			snprintf(buf, 256, hex ? "0x%x" : "%d", *(char*)ptr);
		break;
	case ExternTypeInfo::TYPE_SHORT:
		snprintf(buf, 256, "%d", *(short*)ptr);
		break;
	case ExternTypeInfo::TYPE_INT:
		snprintf(buf, 256, hex ? "0x%x" : "%d", *(int*)ptr);
		break;
	case ExternTypeInfo::TYPE_LONG:
		snprintf(buf, 256, hex ? "0x%llx" : "%lld", *(long long*)ptr);
		break;
	case ExternTypeInfo::TYPE_FLOAT:
		snprintf(buf, 256, "%f", *(float*)ptr);
		break;
	case ExternTypeInfo::TYPE_DOUBLE:
		snprintf(buf, 256, "%f", *(double*)ptr);
		break;
	default:
		snprintf(buf, 256, "...");
	}

	return buf;
}

bool SetBasicVariableValue(unsigned typeIndex, char* ptr, const std::string& value)
{
	unsigned typeCount = 0;
	auto types = nullcDebugTypeInfo(&typeCount);

	auto &type = types[typeIndex];

	if(type.subCat == ExternTypeInfo::CAT_POINTER)
		return false;

	if(type.subCat == ExternTypeInfo::CAT_CLASS)
	{
		if(type.type == ExternTypeInfo::TYPE_INT)
		{
			*(int*)ptr = strtol(value.c_str(), nullptr, 10);
			return true;
		}

		return false;
	}

	if(type.subCat == ExternTypeInfo::CAT_ARRAY)
		return false;

	if(type.subCat == ExternTypeInfo::CAT_FUNCTION)
		return false;

	switch(type.type)
	{
	case ExternTypeInfo::TYPE_CHAR:
		if(typeIndex == NULLC_TYPE_BOOL)
		{
			if(value == "true")
				*(char*)ptr = 1;
			else if(value == "false")
				*(char*)ptr = 0;
			else
				*(char*)ptr = strtol(value.c_str(), nullptr, 10) != 0;
		}
		else
		{
			*(char*)ptr = (char)strtol(value.c_str(), nullptr, 10);
		}
		break;
	case ExternTypeInfo::TYPE_SHORT:
		*(short*)ptr = (short)strtol(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_INT:
		*(int*)ptr = strtol(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_LONG:
		*(long long*)ptr = strtoll(value.c_str(), nullptr, 10);
		break;
	case ExternTypeInfo::TYPE_FLOAT:
		*(float*)ptr = strtof(value.c_str(), nullptr);
		break;
	case ExternTypeInfo::TYPE_DOUBLE:
		*(double*)ptr = strtod(value.c_str(), nullptr);
		break;
	default:
		return false;
	}

	return true;
}

unsigned OnIoWrite(void *context, char *data, unsigned length)
{
	Context &ctx = *(Context*)context;

	SendEventOutput(ctx, OutputEventData("stdout", std::string(data, data + length)));

	return length;
}
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <cstdint>

#include "zcm/zcm-cpp.hpp"

//
// Remember you must inherit from this class and implement your functions
// inside your cpp file. That way you can then compile a shared library of your
// plugins.
//
// REPEAT: ALL FUNCTIONS MUST BE *DEFINED* OUTSIDE OF CLASS *DECLARATION*
//
// Do this:
//
// class CustomPlugin : TranscoderPlugin
// {
//     static TranscoderPlugin* makeTranscoderPlugin();
// };
// TranscoderPlugin* CustomPlugin::makeTranscoderPlugin() { return new CustomPlugin(); }
//
//
// Not This:
//
// class CustomPlugin : TranscoderPlugin
// {
//     static TranscoderPlugin* makeTranscoderPlugin() { return new CustomPlugin(); }
// };
//
//
// Note that an hpp file is not even required. You only need a cpp file containing
// your custom plugin. Then compile it into a shared library by doing the following:
//
// g++ -std=c++11 -fPIC -shared CustomPlugin.cpp -o plugins.so
//

namespace zcm {

class TranscoderPlugin
{
  public:
    // Must declare the following function for your plugin. Unable to enforce
    // declaration of static functions in inheritance, so this API trusts you
    // to define this function for your type
    static TranscoderPlugin* makeTranscoderPlugin() { return new TranscoderPlugin(); }

    virtual ~TranscoderPlugin() {}

    //
    // channel is the channel name of the event
    //
    // typeName is the name of the zcmtype encoded inside the event
    //
    // timestamp is the timestamp of the event. Not to be confused with any
    // fields contained in the zcmtype message itself. This is the timestamp
    // of the event as reported by the transport that originally received it.
    //
    // hash is the hash of the type encoded inside the event
    //
    // data and datalen is the payload of the event
    // To recover the zcmtype message from these arguments, simply call:
    //
    //  if (hash == msg_t::getHash()) {
    //      old_t oldMsg;
    //      oldMsg.decode(evt->data, 0, evt->datalen);
    //  }
    //  new_t newMsg;
    //  ...
    //  convert(newMsg, oldMsg);
    //  ...
    //  int size = newMsg.getEncodedSize();
    //  delete newData; // this variable would be a class variable
    //  newData = new uint8_t[size];
    //  size = newMsg.encode(newData, 0, size);
    //
    //  // newEvt would be a class variable
    //  newEvt.timestamp = evt->timestamp;
    //  newEvt.channel = evt->channel;
    //  newEvt.data = newData;
    //  newEvt.datalen = size;
    //
    //  return { newEvt };
    //
    //  return a vector of events you want to replace this event with.
    //  can return TranscoderPlugin::transcodeEvent(hash,evt) if you dont want
    //  to change the input event
    //
    virtual std::vector<const LogEvent*> transcodeEvent(int64_t hash, const LogEvent* evt)
    {
        return { evt };
    }
};

}
<commit_msg>Edited default transcoder plugin to not transcode event<commit_after>#pragma once

#include <string>
#include <cstdint>

#include "zcm/zcm-cpp.hpp"

//
// Remember you must inherit from this class and implement your functions
// inside your cpp file. That way you can then compile a shared library of your
// plugins.
//
// REPEAT: ALL FUNCTIONS MUST BE *DEFINED* OUTSIDE OF CLASS *DECLARATION*
//
// Do this:
//
// class CustomPlugin : TranscoderPlugin
// {
//     static TranscoderPlugin* makeTranscoderPlugin();
// };
// TranscoderPlugin* CustomPlugin::makeTranscoderPlugin() { return new CustomPlugin(); }
//
//
// Not This:
//
// class CustomPlugin : TranscoderPlugin
// {
//     static TranscoderPlugin* makeTranscoderPlugin() { return new CustomPlugin(); }
// };
//
//
// Note that an hpp file is not even required. You only need a cpp file containing
// your custom plugin. Then compile it into a shared library by doing the following:
//
// g++ -std=c++11 -fPIC -shared CustomPlugin.cpp -o plugins.so
//

namespace zcm {

class TranscoderPlugin
{
  public:
    // Must declare the following function for your plugin. Unable to enforce
    // declaration of static functions in inheritance, so this API trusts you
    // to define this function for your type
    static TranscoderPlugin* makeTranscoderPlugin() { return new TranscoderPlugin(); }

    virtual ~TranscoderPlugin() {}

    //
    // channel is the channel name of the event
    //
    // typeName is the name of the zcmtype encoded inside the event
    //
    // timestamp is the timestamp of the event. Not to be confused with any
    // fields contained in the zcmtype message itself. This is the timestamp
    // of the event as reported by the transport that originally received it.
    //
    // hash is the hash of the type encoded inside the event
    //
    // data and datalen is the payload of the event
    // To recover the zcmtype message from these arguments, simply call:
    //
    //  if (hash == msg_t::getHash()) {
    //      old_t oldMsg;
    //      oldMsg.decode(evt->data, 0, evt->datalen);
    //  }
    //  new_t newMsg;
    //  ...
    //  convert(newMsg, oldMsg);
    //  ...
    //  int size = newMsg.getEncodedSize();
    //  delete newData; // this variable would be a class variable
    //  newData = new uint8_t[size];
    //  size = newMsg.encode(newData, 0, size);
    //
    //  // newEvt would be a class variable
    //  newEvt.timestamp = evt->timestamp;
    //  newEvt.channel = evt->channel;
    //  newEvt.data = newData;
    //  newEvt.datalen = size;
    //
    //  return { newEvt };
    //
    //  return a vector of events you want to replace this event with.
    //  return TranscoderPlugin::transcodeEvent(hash,evt) to not transcode
    //  this event into the output log
    //
    virtual std::vector<const LogEvent*> transcodeEvent(int64_t hash, const LogEvent* evt)
    {
        return {};
    }
};

}
<|endoftext|>


<commit_before>#include "master.hpp"

namespace factor
{

THREADHANDLE start_thread(void *(*start_routine)(void *), void *args)
{
	return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
}

DWORD dwTlsIndex;

void init_platform_globals()
{
	if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
		fatal_error("TlsAlloc failed - out of indexes",0);
}

void register_vm_with_thread(factor_vm *vm)
{
	if (! TlsSetValue(dwTlsIndex, vm))
		fatal_error("TlsSetValue failed",0);
}

factor_vm *tls_vm()
{
	factor_vm *vm = (factor_vm*)TlsGetValue(dwTlsIndex);
	assert(vm != NULL);
	return vm;
}

u64 system_micros()
{
	FILETIME t;
	GetSystemTimeAsFileTime(&t);
	return (((u64)t.dwLowDateTime | (u64)t.dwHighDateTime<<32)
		- EPOCH_OFFSET) / 10;
}

/* On VirtualBox, QueryPerformanceCounter does not increment
the high part every time the low part overflows.  Workaround. */
u64 nano_count()
{
	LARGE_INTEGER count;
	LARGE_INTEGER frequency;
	static u32 hi_correction = 0;
	static u32 hi = 0xffffffff;
	static u32 lo = 0xffffffff;
	BOOL ret;
	ret = QueryPerformanceCounter(&count);
	if(ret == 0)
		fatal_error("QueryPerformanceCounter", 0);
	ret = QueryPerformanceFrequency(&frequency);
	if(ret == 0)
		fatal_error("QueryPerformanceFrequency", 0);

	if((u32)count.LowPart < lo && (u32)count.HighPart == hi)
		hi_correction++;

	hi = count.HighPart;
	lo = count.LowPart;
	count.HighPart += hi_correction;

	return count.QuadPart*(1000000000/frequency.QuadPart);
}

void sleep_nanos(u64 nsec)
{
	Sleep((DWORD)(nsec/1000000));
}

LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe)
{
	PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
	CONTEXT *c = (CONTEXT*)pe->ContextRecord;

	if(in_code_heap_p(c->EIP))
		signal_callstack_top = (stack_frame *)c->ESP;
	else
		signal_callstack_top = NULL;

        switch (e->ExceptionCode)
        {
        case EXCEPTION_ACCESS_VIOLATION:
		signal_fault_addr = e->ExceptionInformation[1];
		c->EIP = (cell)factor::memory_signal_handler_impl;
                break;

	case STATUS_FLOAT_DENORMAL_OPERAND:
	case STATUS_FLOAT_DIVIDE_BY_ZERO:
	case STATUS_FLOAT_INEXACT_RESULT:
	case STATUS_FLOAT_INVALID_OPERATION:
	case STATUS_FLOAT_OVERFLOW:
	case STATUS_FLOAT_STACK_CHECK:
	case STATUS_FLOAT_UNDERFLOW:
	case STATUS_FLOAT_MULTIPLE_FAULTS:
	case STATUS_FLOAT_MULTIPLE_TRAPS:
		signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
		X87SW(c) = 0;
		MXCSR(c) &= 0xffffffc0;
		c->EIP = (cell)factor::fp_signal_handler_impl;
		break;
	case 0x40010006:
		/* If the Widcomm bluetooth stack is installed, the BTTray.exe
		process injects code into running programs. For some reason this
		results in random SEH exceptions with this (undocumented)
		exception code being raised. The workaround seems to be ignoring
		this altogether, since that is what happens if SEH is not
		enabled. Don't really have any idea what this exception means. */
		break;
	case 0xe06d7363:
		/* This exception comes from a Visual Studio C++ app that uses
		throw. Ignore it.
		http://support.microsoft.com/kb/185294 */
		break;
	default:
		signal_number = e->ExceptionCode;
		c->EIP = (cell)factor::misc_signal_handler_impl;
		break;
	}
	return EXCEPTION_CONTINUE_EXECUTION;
}

FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
{
	return tls_vm()->exception_handler(pe);
}

bool handler_added = 0;

void factor_vm::c_to_factor_toplevel(cell quot)
{
	if(!handler_added){
		if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
			fatal_error("AddVectoredExceptionHandler failed", 0);
		handler_added = 1;
	}
	c_to_factor(quot,this);
 	RemoveVectoredExceptionHandler((void *)factor::exception_handler);
}

void factor_vm::open_console()
{
}

}
<commit_msg>try a different approach to fix the windows monotonic counter<commit_after>#include "master.hpp"

namespace factor
{

THREADHANDLE start_thread(void *(*start_routine)(void *), void *args)
{
	return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
}

DWORD dwTlsIndex;

void init_platform_globals()
{
	if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
		fatal_error("TlsAlloc failed - out of indexes",0);
}

void register_vm_with_thread(factor_vm *vm)
{
	if (! TlsSetValue(dwTlsIndex, vm))
		fatal_error("TlsSetValue failed",0);
}

factor_vm *tls_vm()
{
	factor_vm *vm = (factor_vm*)TlsGetValue(dwTlsIndex);
	assert(vm != NULL);
	return vm;
}

u64 system_micros()
{
	FILETIME t;
	GetSystemTimeAsFileTime(&t);
	return (((u64)t.dwLowDateTime | (u64)t.dwHighDateTime<<32)
		- EPOCH_OFFSET) / 10;
}

/* On VirtualBox, QueryPerformanceCounter does not increment
the high part every time the low part overflows.  Workaround. */
u64 nano_count()
{
	LARGE_INTEGER count;
	LARGE_INTEGER frequency;
	static u32 hi = 0;
	static u32 lo = 0;
	BOOL ret;
	ret = QueryPerformanceCounter(&count);
	if(ret == 0)
		fatal_error("QueryPerformanceCounter", 0);
	ret = QueryPerformanceFrequency(&frequency);
	if(ret == 0)
		fatal_error("QueryPerformanceFrequency", 0);

	printf("hi = %u, lo = %u\n", hi, lo);

	if(count.LowPart < lo)
		hi += 1;
	lo = count.LowPart;

	return (((u64)hi << 32) | (u64)lo)*(1000000000/frequency.QuadPart);
}

void sleep_nanos(u64 nsec)
{
	Sleep((DWORD)(nsec/1000000));
}

LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe)
{
	PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
	CONTEXT *c = (CONTEXT*)pe->ContextRecord;

	if(in_code_heap_p(c->EIP))
		signal_callstack_top = (stack_frame *)c->ESP;
	else
		signal_callstack_top = NULL;

        switch (e->ExceptionCode)
        {
        case EXCEPTION_ACCESS_VIOLATION:
		signal_fault_addr = e->ExceptionInformation[1];
		c->EIP = (cell)factor::memory_signal_handler_impl;
                break;

	case STATUS_FLOAT_DENORMAL_OPERAND:
	case STATUS_FLOAT_DIVIDE_BY_ZERO:
	case STATUS_FLOAT_INEXACT_RESULT:
	case STATUS_FLOAT_INVALID_OPERATION:
	case STATUS_FLOAT_OVERFLOW:
	case STATUS_FLOAT_STACK_CHECK:
	case STATUS_FLOAT_UNDERFLOW:
	case STATUS_FLOAT_MULTIPLE_FAULTS:
	case STATUS_FLOAT_MULTIPLE_TRAPS:
		signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
		X87SW(c) = 0;
		MXCSR(c) &= 0xffffffc0;
		c->EIP = (cell)factor::fp_signal_handler_impl;
		break;
	case 0x40010006:
		/* If the Widcomm bluetooth stack is installed, the BTTray.exe
		process injects code into running programs. For some reason this
		results in random SEH exceptions with this (undocumented)
		exception code being raised. The workaround seems to be ignoring
		this altogether, since that is what happens if SEH is not
		enabled. Don't really have any idea what this exception means. */
		break;
	case 0xe06d7363:
		/* This exception comes from a Visual Studio C++ app that uses
		throw. Ignore it.
		http://support.microsoft.com/kb/185294 */
		break;
	default:
		signal_number = e->ExceptionCode;
		c->EIP = (cell)factor::misc_signal_handler_impl;
		break;
	}
	return EXCEPTION_CONTINUE_EXECUTION;
}

FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
{
	return tls_vm()->exception_handler(pe);
}

bool handler_added = 0;

void factor_vm::c_to_factor_toplevel(cell quot)
{
	if(!handler_added){
		if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
			fatal_error("AddVectoredExceptionHandler failed", 0);
		handler_added = 1;
	}
	c_to_factor(quot,this);
 	RemoveVectoredExceptionHandler((void *)factor::exception_handler);
}

void factor_vm::open_console()
{
}

}
<|endoftext|>


<commit_before>/*-------------viral_video.cpp------------------------------------------------//
*
* Purpose: To simulate how a video becomes viral
*
*   Notes: videos represented as integers, we don't care about their name
*          videos_seen will hold history for the viewer, we may cut this off
*          viewers have seen ~10 videos at the start of the simulation
*          the video we are propagating is video 0
*          Now, viewers may watch the same videos over gain, check affinity
*          Compile with "g++ viral_video.cpp"
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <random>
#include <algorithm>

// Struct to hold all information for each individual viewer
struct viewer{
    std::vector<int> videos_seen;
    std::vector<double> affinities;
};

// Function to initialize all the people in the simulation
std::vector<viewer> init_viewers(int viewer_num, int num_videos);

// Function to find affinity with all other people
std::vector<double> find_affinities(int individual,
                                    std::vector<viewer> &viewers);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(){

    std::vector<viewer> viewers;
    viewers = init_viewers(100, 10);

    for (int i = 0; i < viewers.size(); i++){
        std::cout << i << '\t' << viewers[i].videos_seen[0] << '\t'
                  << viewers[i].affinities[0] << '\n';
    }
}

/*----------------------------------------------------------------------------//
* SUBROUTINE
*-----------------------------------------------------------------------------*/

// Function to initialize all the people in the simulation
std::vector<viewer> init_viewers(int viewer_num, int num_videos){

    int history = 10;

    // Defining random distribution for videos seen by people
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_int_distribution<int>
        chosen_videos_dist(1, num_videos);

    std::vector<viewer> viewers(viewer_num);

    // Defining videos seen by each person
    for (int i = 0; i < viewer_num; i++){
        viewers[i].videos_seen.reserve(history);
        for (int j = 0; j < history; j++){
            viewers[i].videos_seen.push_back(chosen_videos_dist(gen));
        }
    }

    // Denfining all the initial affinities
    for (int i = 0; i < viewer_num; i++){
        std::cout << i << '\n';
        viewers[i].affinities = find_affinities(i, viewers);
    }

    return viewers;
}

// Function to find affinity with all other people
std::vector<double> find_affinities(int individual,
                                    std::vector<viewer> &viewers){

    std::vector<double> affinities(viewers.size());
    std::vector<int>::iterator it;
    double affinity;
    int shared = 0;

    // Searching through all the other viewers to find videos in common
    for (int i = 0; i < viewers.size(); i++){
        std::cout << i << '\n';
        if (individual != i){
            // Naive method to find all videos shared between to folks
            for (int j = 0; j < viewers[individual].videos_seen.size(); j++){
                it = find(viewers[i].videos_seen.begin(),
                          viewers[i].videos_seen.end(),
                          viewers[individual].videos_seen[j]);
                if (it != viewers[i].videos_seen.end()){
                    shared++;
                }
            }
            affinity = (double)shared
                       / (double)viewers[individual].videos_seen.size();
            affinities[i] = affinity;

            shared = 0;
        }
        else{
            affinities[i] = 0;
        }
    }

    return affinities;
}
<commit_msg>Adding the ability to provide a video list by our video service provider.<commit_after>/*-------------viral_video.cpp------------------------------------------------//
*
* Purpose: To simulate how a video becomes viral
*
*   Notes: videos represented as integers, we don't care about their name
*          videos_seen will hold history for the viewer, we may cut this off
*          viewers have seen ~10 videos at the start of the simulation
*          the video we are propagating is video 0
*          Now, viewers may watch the same videos over gain, check affinity
*          Compile with "g++ viral_video.cpp -std=c++11"
*
*          Sort the videos to find the videos to provide.
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <unordered_map>

// Struct for videos
struct video{
    int id;
    double val = 1.0;
};

// equality operator for videos
bool operator==(const video& a, const video& b){
    return (a.id == b.id);
}

// Struct to hold all information for each individual viewer
struct viewer{
    std::vector<video> video_list;
    //std::vector<video> videos_seen;
    std::unordered_map<int, double> videos_seen;
    std::vector<double> affinities;
    int index;
};

// Function to initialize all the people in the simulation
std::vector<viewer> init_viewers(int viewer_num, int num_videos);

// Function to find affinity with all other people
std::vector<double> find_affinities(int individual,
                                    std::vector<viewer> &viewers);

// Function to provide videos to all viewers
void provide_videos(std::vector<viewer> &viewers, int cutoff, int num_videos);

// Function for each individual to choose a video from their video_list and
// rate it randomly between 0, 1, and 2
void watch_video(std::vector<viewer> &viewers);

// Function to share videos with other people randomly in the network
// Note that this simply forces the individuals to watch a particular video
// next timestep
void share(std::vector<viewer> &viewers, std::vector<int> &network,
           int video_id);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(){

    std::vector<viewer> viewers;
    int num_videos = 10;
    viewers = init_viewers(100, num_videos);

    for (int i = 0; i < viewers.size(); i++){
        std::cout << i << '\t' << viewers[i].videos_seen[0] << '\t'
                  << viewers[i].affinities[0] << '\n';
    }

    provide_videos(viewers, 10, num_videos);
}

/*----------------------------------------------------------------------------//
* SUBROUTINE
*-----------------------------------------------------------------------------*/

// Function to initialize all the people in the simulation
std::vector<viewer> init_viewers(int viewer_num, int num_videos){

    int history = 10;
    video chosen_video;

    // Defining random distribution for videos seen by people
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_int_distribution<int>
        chosen_videos_dist(1, num_videos-1);

    std::vector<viewer> viewers(viewer_num);

    // Defining videos seen by each person
    for (int i = 0; i < viewer_num; i++){
        //viewers[i].videos_seen.reserve(history);
        viewers[i].video_list.reserve(10);
        viewers[i].index = i;
        for (int j = 0; j < history; j++){
            chosen_video.id = chosen_videos_dist(gen);
            //viewers[i].videos_seen.push_back(chosen_video);
            viewers[i].videos_seen[chosen_video.id] = 1.0;
        }
    }

    // Denfining all the initial affinities
    for (int i = 0; i < viewer_num; i++){
        std::cout << i << '\n';
        viewers[i].affinities = find_affinities(i, viewers);
    }

    return viewers;
}

// Function to find affinity with all other people
std::vector<double> find_affinities(int individual,
                                    std::vector<viewer> &viewers){

    std::vector<double> affinities(viewers.size());
    std::vector<video>::iterator it;
    double affinity;
    int shared;

    // Searching through all the other viewers to find videos in common
    for (int i = 0; i < viewers.size(); i++){
        std::cout << i << '\n';
        shared = 0;
        if (individual != i){
            // Naive method to find all videos shared between to folks
            for (const auto& vid : viewers[individual].videos_seen){
                if (viewers[i].videos_seen.find(vid.first) !=
                    viewers[i].videos_seen.end()){
                    shared++;
                }
            }
/*
            for (int j = 0; j < viewers[individual].videos_seen.size(); j++){
                it = find(viewers[i].videos_seen.begin(),
                          viewers[i].videos_seen.end(),
                          viewers[individual].videos_seen[j]);
                if (it != viewers[i].videos_seen.end()){
                    shared++;
                }
            }
*/
            affinity = (double)shared
                       / (double)viewers[individual].videos_seen.size();
            affinities[i] = affinity;

            shared = 0;
        }
        else{
            affinities[i] = 0;
        }
    }

    return affinities;
}

// Function to provide videos to all viewers
void provide_videos(std::vector<viewer> &viewers, int cutoff, int num_videos){

    // Creating list for how individuals see the rest of the community.
    std::vector<viewer> similarity_list = viewers;
    std::vector<video> video_values(num_videos);

    for (int i = 0; i < video_values.size(); i++){
        video_values[i].id = i;
    }

    // Updating video list for all viewers
    for (int i = 0; i < viewers.size(); i++){

        // Sorting procedure written by Gustorn
        std::sort(similarity_list.begin(), similarity_list.end(),
                  [&viewers, &i](viewer& a, viewer& b){
                      return viewers[i].affinities[a.index] >
                             viewers[i].affinities[b.index];
                  });

        // Populating the video_values with doubles
        for (int j = 0; j < cutoff; j++){
            // Going through people's video history
            for (auto &k : similarity_list[j].videos_seen){
                video_values[k.first].val +=
                    viewers[i].affinities[similarity_list[j].index]
                    * k.second;
            }
        }

        std::sort(video_values.begin(), video_values.end(),
                  [](const video& a, const video& b){return a.val > b.val;});

        viewers[i].video_list.clear();
        for (int j = 0; j < 10; j++){
            viewers[i].video_list.push_back(video_values[j]);
        }

        // Setting the similarity list back to what it was before.
        similarity_list = viewers;
    }

    for (int i = 0; i < viewers.size(); i++){
        std::cout << viewers[i].video_list[5].id << '\n';
    }
}

// Function for each individual to choose a video from their video_list and
// rate it randomly between 0, 1, and 2
void watch_video(std::vector<viewer> &viewers){
}

// Function to share videos with other people randomly in the network
// Note that this simply forces the individuals to watch a particular video
// next timestep
void share(std::vector<viewer> &viewers, std::vector<int> &network,
           int video_id);

<|endoftext|>


<commit_before>#include "ScoreEditor.h"
#include "Rainbow.h"

using namespace WTS;

const int ScoreEditor::s_wheelColorCount = 8;
const float ScoreEditor::s_wheelInnerRadius = 7;
const float ScoreEditor::s_wheelOuterRadius = 18;

ScoreEditor::ScoreEditor(QWidget *parent)
    : TimeLineWidget(parent)
    , m_gridStep(5)
    , m_newSymbol(0)
    , m_colorSelCircle(0)
{
    initNewSymbol();
    setRenderHints(QPainter::Antialiasing);

    // make color wheel
    m_colorWheel = new QGraphicsItemGroup(0,scene());

    float arcRun = 360.0 / s_wheelColorCount;

    QRectF outerRect( - s_wheelOuterRadius, - s_wheelOuterRadius, 2.0*s_wheelOuterRadius, 2.0*s_wheelOuterRadius);
    QRectF innerRect( - s_wheelInnerRadius, - s_wheelInnerRadius, 2.0*s_wheelInnerRadius, 2.0*s_wheelInnerRadius);

    for(int i = 0; i<s_wheelColorCount; ++i) {
        float startAngle = arcRun * i;
        float a0 = startAngle / 180.0 * M_PI;
        float a1 = (startAngle + arcRun) / 180.0 * M_PI;

        QPainterPath petalShape;

        // is Qt inconsistent in the orientation of Y and angles?
        petalShape.moveTo( s_wheelInnerRadius * cos(a1), -s_wheelInnerRadius * sin(a1) );
        petalShape.arcTo(  innerRect, startAngle+arcRun, -arcRun );
        petalShape.lineTo( s_wheelOuterRadius * cos(a0), -s_wheelOuterRadius * sin(a0));
        petalShape.arcTo(  outerRect, startAngle, arcRun );
        petalShape.closeSubpath();

        QGraphicsPathItem * petal = new QGraphicsPathItem(petalShape, m_colorWheel);
        petal->setPen(QPen(Rainbow::getColor(i,255,80)));
        petal->setBrush(QBrush(Rainbow::getColor(i,200)));

        petal->setData(PetalIndex, i);

    }
    m_colorSelCircle = new QGraphicsEllipseItem(innerRect,m_colorWheel);
    selectPetal( m_colorWheel->childItems()[0] );
}

void ScoreEditor::drawBackground(QPainter *painter, const QRectF &rect)
{
    TimeLineWidget::drawBackground(painter, rect);
    painter->setPen(QColor(0,64,0,16));

    /* FIXME restrict to rect? */
    for(int i=0; i<width(); i+=m_gridStep) {
        float x = (float)i/width();
        painter->drawLine(QPointF(x,0.0),QPointF(x,1.0));
    }
    for(int j=0; j<height(); j+=m_gridStep) {
        float y = (float)j/height();
        painter->drawLine(QPointF(0.0,y),QPointF(1.0,y));
    }
}

void ScoreEditor::mouseReleaseEvent(QMouseEvent * event)
{
    TimeLineWidget::mouseReleaseEvent(event);
    if (editMode()) {
        if (m_newSymbol->finish())
            m_newSymbol->setSelected(true);

        initNewSymbol();
        emit dataChanged();
    }
}

void ScoreEditor::mousePressEvent(QMouseEvent * event)
{
    TimeLineWidget::mousePressEvent(event);
    if (editMode()) {

        if (scene()->selectedItems().size() > 0) {
            // something is selected - don't bother...
            return;
        }

        if (event->buttons() & Qt::LeftButton) {
            QGraphicsItem * hitItem = itemAt( event->pos() );

            if (hitItem && hitItem != m_cursorLine) {
                // FIXME: color wheel should be a custom item handling the mouse
                QVariant vpindex = hitItem->data(PetalIndex);
                if (vpindex.isValid() && !vpindex.isNull()) {
                    // yes, a petal, use its color
                    selectPetal(hitItem);
                }
            } else
                m_newSymbol->start(mapToScene(event->pos()));
        }
    }
}

void ScoreEditor::mouseMoveEvent(QMouseEvent * event)
{
    TimeLineWidget::mouseMoveEvent(event);
    if (editMode()) {
        m_newSymbol->pull(mapToScene(event->pos()));
    }
}

void ScoreEditor::resizeEvent(QResizeEvent *event)
{
    scene()->clearSelection();
    scene()->clearFocus();

    TimeLineWidget::resizeEvent(event);
    m_newSymbol->configure(scene(), width(), height());

    /*
      First copy only symbols then resize them. Two phases are necessary because reconfiguring /
      updating a symbol destroys some items which scene()->items() would return and trying to
      access those causes software to crash
    */
    QList<ScoreSymbol*> symbols;
    foreach(QGraphicsItem * item, scene()->items()) {
        ScoreSymbol * symbol = dynamic_cast<ScoreSymbol *>(item);
        if (symbol) symbols << symbol;
    }

    foreach(ScoreSymbol * symbol, symbols) {
        symbol->configure(scene(), width(), height());
        symbol->updateGraphics();
    }

    m_colorWheel->setTransform( QTransform::fromScale( 1.0/width(), 1.0/height() ) );
    m_colorWheel->setTransform( QTransform::fromTranslate(
                                   s_wheelOuterRadius,
                                   s_wheelOuterRadius ),
                               true);
}

void ScoreEditor::selectPetal(QGraphicsItem * item)
{
    QGraphicsPathItem * petal =
            dynamic_cast<QGraphicsPathItem *>(item);

    if (!petal) return;

    m_colorSelCircle->setPen(petal->pen());
    m_colorSelCircle->setBrush(petal->brush());
    m_newSymbol->setColors(petal->pen(), petal->brush());
}

void ScoreEditor::initNewSymbol()
{
    m_newSymbol = new ScoreSymbol();
    m_newSymbol->configure(scene(), width(), height());
    if (m_colorSelCircle)
        m_newSymbol->setColors( m_colorSelCircle->pen(),
                               m_colorSelCircle->brush() );
    connect(m_newSymbol->inkTimer(), SIGNAL(timeout()), SLOT(passInk()));
}

void ScoreEditor::saveData(QXmlStreamWriter &xml)
{
    foreach(QGraphicsItem * item, scene()->items()) {
        ScoreSymbol * symbol = dynamic_cast<ScoreSymbol *>(item);
        if (!symbol) continue;
        symbol->saveData(xml);
    }
}

void ScoreEditor::loadData(QXmlStreamReader &xml)
{
    while(xml.readNextStartElement()) {
        ScoreSymbol * symbol = new ScoreSymbol();
        symbol->configure(scene(), width(), height());
        symbol->loadData(xml);
        xml.readElementText();
    }
}

<commit_msg>don't produce spurious symbols<commit_after>#include "ScoreEditor.h"
#include "Rainbow.h"

using namespace WTS;

const int ScoreEditor::s_wheelColorCount = 8;
const float ScoreEditor::s_wheelInnerRadius = 7;
const float ScoreEditor::s_wheelOuterRadius = 18;

ScoreEditor::ScoreEditor(QWidget *parent)
    : TimeLineWidget(parent)
    , m_gridStep(5)
    , m_newSymbol(0)
    , m_colorSelCircle(0)
{
    initNewSymbol();
    setRenderHints(QPainter::Antialiasing);

    // make color wheel
    m_colorWheel = new QGraphicsItemGroup(0,scene());

    float arcRun = 360.0 / s_wheelColorCount;

    QRectF outerRect( - s_wheelOuterRadius, - s_wheelOuterRadius, 2.0*s_wheelOuterRadius, 2.0*s_wheelOuterRadius);
    QRectF innerRect( - s_wheelInnerRadius, - s_wheelInnerRadius, 2.0*s_wheelInnerRadius, 2.0*s_wheelInnerRadius);

    for(int i = 0; i<s_wheelColorCount; ++i) {
        float startAngle = arcRun * i;
        float a0 = startAngle / 180.0 * M_PI;
        float a1 = (startAngle + arcRun) / 180.0 * M_PI;

        QPainterPath petalShape;

        // is Qt inconsistent in the orientation of Y and angles?
        petalShape.moveTo( s_wheelInnerRadius * cos(a1), -s_wheelInnerRadius * sin(a1) );
        petalShape.arcTo(  innerRect, startAngle+arcRun, -arcRun );
        petalShape.lineTo( s_wheelOuterRadius * cos(a0), -s_wheelOuterRadius * sin(a0));
        petalShape.arcTo(  outerRect, startAngle, arcRun );
        petalShape.closeSubpath();

        QGraphicsPathItem * petal = new QGraphicsPathItem(petalShape, m_colorWheel);
        petal->setPen(QPen(Rainbow::getColor(i,255,80)));
        petal->setBrush(QBrush(Rainbow::getColor(i,200)));

        petal->setData(PetalIndex, i);

    }
    m_colorSelCircle = new QGraphicsEllipseItem(innerRect,m_colorWheel);
    selectPetal( m_colorWheel->childItems()[0] );
}

void ScoreEditor::drawBackground(QPainter *painter, const QRectF &rect)
{
    TimeLineWidget::drawBackground(painter, rect);
    painter->setPen(QColor(0,64,0,16));

    /* FIXME restrict to rect? */
    for(int i=0; i<width(); i+=m_gridStep) {
        float x = (float)i/width();
        painter->drawLine(QPointF(x,0.0),QPointF(x,1.0));
    }
    for(int j=0; j<height(); j+=m_gridStep) {
        float y = (float)j/height();
        painter->drawLine(QPointF(0.0,y),QPointF(1.0,y));
    }
}

void ScoreEditor::mouseReleaseEvent(QMouseEvent * event)
{
    TimeLineWidget::mouseReleaseEvent(event);
    if (editMode()) {
        if (m_newSymbol->finish()) {
            m_newSymbol->setSelected(true);
            initNewSymbol();
        }
        emit dataChanged();
    }
}

void ScoreEditor::mousePressEvent(QMouseEvent * event)
{
    TimeLineWidget::mousePressEvent(event);
    if (editMode()) {

        if (scene()->selectedItems().size() > 0) {
            // something is selected - don't bother...
            return;
        }

        if (event->buttons() & Qt::LeftButton) {
            QGraphicsItem * hitItem = itemAt( event->pos() );

            if (hitItem && hitItem != m_cursorLine) {
                // FIXME: color wheel should be a custom item handling the mouse
                QVariant vpindex = hitItem->data(PetalIndex);
                if (vpindex.isValid() && !vpindex.isNull()) {
                    // yes, a petal, use its color
                    selectPetal(hitItem);
                }
            } else
                m_newSymbol->start(mapToScene(event->pos()));
        }
    }
}

void ScoreEditor::mouseMoveEvent(QMouseEvent * event)
{
    TimeLineWidget::mouseMoveEvent(event);
    if (editMode()) {
        m_newSymbol->pull(mapToScene(event->pos()));
    }
}

void ScoreEditor::resizeEvent(QResizeEvent *event)
{
    scene()->clearSelection();
    scene()->clearFocus();

    TimeLineWidget::resizeEvent(event);
    m_newSymbol->configure(scene(), width(), height());

    /*
      First copy only symbols then resize them. Two phases are necessary because reconfiguring /
      updating a symbol destroys some items which scene()->items() would return and trying to
      access those causes software to crash
    */
    QList<ScoreSymbol*> symbols;
    foreach(QGraphicsItem * item, scene()->items()) {
        ScoreSymbol * symbol = dynamic_cast<ScoreSymbol *>(item);
        if (symbol) symbols << symbol;
    }

    foreach(ScoreSymbol * symbol, symbols) {
        symbol->configure(scene(), width(), height());
        symbol->updateGraphics();
    }

    m_colorWheel->setTransform( QTransform::fromScale( 1.0/width(), 1.0/height() ) );
    m_colorWheel->setTransform( QTransform::fromTranslate(
                                   s_wheelOuterRadius,
                                   s_wheelOuterRadius ),
                               true);
}

void ScoreEditor::selectPetal(QGraphicsItem * item)
{
    QGraphicsPathItem * petal =
            dynamic_cast<QGraphicsPathItem *>(item);

    if (!petal) return;

    m_colorSelCircle->setPen(petal->pen());
    m_colorSelCircle->setBrush(petal->brush());
    m_newSymbol->setColors(petal->pen(), petal->brush());
}

void ScoreEditor::initNewSymbol()
{
    m_newSymbol = new ScoreSymbol();
    m_newSymbol->configure(scene(), width(), height());
    if (m_colorSelCircle)
        m_newSymbol->setColors( m_colorSelCircle->pen(),
                               m_colorSelCircle->brush() );
    connect(m_newSymbol->inkTimer(), SIGNAL(timeout()), SLOT(passInk()));
}

void ScoreEditor::saveData(QXmlStreamWriter &xml)
{
    foreach(QGraphicsItem * item, scene()->items()) {
        ScoreSymbol * symbol = dynamic_cast<ScoreSymbol *>(item);
        if (!symbol || symbol == m_newSymbol) continue;
        symbol->saveData(xml);
    }
}

void ScoreEditor::loadData(QXmlStreamReader &xml)
{
    while(xml.readNextStartElement()) {
        ScoreSymbol * symbol = new ScoreSymbol();
        symbol->configure(scene(), width(), height());
        symbol->loadData(xml);
        xml.readElementText();
    }
}

<|endoftext|>


<commit_before>#include "exceptions.h"
#include "nrrd.h"

#include <virvo/vvvoldesc.h>
#include <virvo/private/vvlog.h>

#include <teem/nrrd.h>

#include <string>
#include <string.h> // memcpy

#if VV_HAVE_TEEM

using namespace virvo;

struct ScopedNrrd
{

  ScopedNrrd()
    : ptr(nrrdNew())
    , io(nrrdIoStateNew())
  {
  }

  ~ScopedNrrd()
  {
    nrrdNuke(ptr);
    nrrdIoStateNix(io);
  }

  Nrrd* ptr;
  NrrdIoState* io;

};

void nrrd::load(vvVolDesc* vd)
{

  ScopedNrrd nrrd;

  // load decodes data and automatically toggles
  // endianness according to endian tag in file
  if (nrrdLoad(nrrd.ptr, vd->getFilename(), nrrd.io))
  {
    char* err = biffGetDone(NRRD);
    std::string errstr = err;
    free(err);
    throw fileio::exception(errstr);
  }

  if (nrrd.ptr->dim != 3)
  {
    throw fileio::wrong_dimensions();
  }

  vd->frames = 1;
  switch (nrrd.ptr->type)
  {
  case nrrdTypeChar:
  case nrrdTypeUChar:
    vd->bpc  = 1;
    vd->chan = 1;
    break;
  case nrrdTypeShort:
  case nrrdTypeUShort:
    vd->bpc  = 2;
    vd->chan = 1;
    break;
  case nrrdTypeInt:
  case nrrdTypeUInt:
    vd->bpc  = 4;
    vd->chan = 1;
    break;
  default:
    throw fileio::unsupported_datatype();
  }

  size_t size[3];
  nrrdAxisInfoGet_nva(nrrd.ptr, nrrdAxisInfoSize, size);

  vd->vox[0] = size[0];
  vd->vox[1] = size[1];
  vd->vox[2] = size[2];

  uint8_t* raw = new uint8_t[vd->getFrameBytes()];
  memcpy(raw, nrrd.ptr->data, vd->getFrameBytes());
  vd->addFrame(raw, vvVolDesc::ARRAY_DELETE);

}

#endif // VV_HAVE_TEEM

<commit_msg>Compile w/o libteem<commit_after>#include "exceptions.h"
#include "nrrd.h"

#include <virvo/vvvoldesc.h>
#include <virvo/private/vvlog.h>

#if VV_HAVE_TEEM
#include <teem/nrrd.h>
#endif

#include <string>
#include <string.h> // memcpy

#if VV_HAVE_TEEM

using namespace virvo;

struct ScopedNrrd
{

  ScopedNrrd()
    : ptr(nrrdNew())
    , io(nrrdIoStateNew())
  {
  }

  ~ScopedNrrd()
  {
    nrrdNuke(ptr);
    nrrdIoStateNix(io);
  }

  Nrrd* ptr;
  NrrdIoState* io;

};

void nrrd::load(vvVolDesc* vd)
{

  ScopedNrrd nrrd;

  // load decodes data and automatically toggles
  // endianness according to endian tag in file
  if (nrrdLoad(nrrd.ptr, vd->getFilename(), nrrd.io))
  {
    char* err = biffGetDone(NRRD);
    std::string errstr = err;
    free(err);
    throw fileio::exception(errstr);
  }

  if (nrrd.ptr->dim != 3)
  {
    throw fileio::wrong_dimensions();
  }

  vd->frames = 1;
  switch (nrrd.ptr->type)
  {
  case nrrdTypeChar:
  case nrrdTypeUChar:
    vd->bpc  = 1;
    vd->chan = 1;
    break;
  case nrrdTypeShort:
  case nrrdTypeUShort:
    vd->bpc  = 2;
    vd->chan = 1;
    break;
  case nrrdTypeInt:
  case nrrdTypeUInt:
    vd->bpc  = 4;
    vd->chan = 1;
    break;
  default:
    throw fileio::unsupported_datatype();
  }

  size_t size[3];
  nrrdAxisInfoGet_nva(nrrd.ptr, nrrdAxisInfoSize, size);

  vd->vox[0] = size[0];
  vd->vox[1] = size[1];
  vd->vox[2] = size[2];

  uint8_t* raw = new uint8_t[vd->getFrameBytes()];
  memcpy(raw, nrrd.ptr->data, vd->getFrameBytes());
  vd->addFrame(raw, vvVolDesc::ARRAY_DELETE);

}

#endif // VV_HAVE_TEEM

<|endoftext|>