git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51187 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			248 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        tests/weakref/evtconnection.cpp
 | 
						|
// Purpose:     wxWeakRef<T> unit test
 | 
						|
// Author:      Arne Steinarson
 | 
						|
// Created:     2008-01-10
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 2007 Arne Steinarson
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// headers
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
#include "testprec.h"
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
    #include "wx/wx.h"
 | 
						|
#endif // WX_PRECOMP
 | 
						|
 | 
						|
#include "wx/event.h"
 | 
						|
#include "wx/weakref.h"
 | 
						|
 | 
						|
static int gs_value = 0; // Increased by 1 by first object and 0x10000 by 2nd object
 | 
						|
 | 
						|
static wxObject *gs_psrc1;
 | 
						|
static wxObject *gs_psrc2;
 | 
						|
 | 
						|
// We need some event types
 | 
						|
const wxEventType wxEVT_TEST = wxNewEventType(),
 | 
						|
                  wxEVT_TEST1 = wxNewEventType(),
 | 
						|
                  wxEVT_TEST2 = wxNewEventType();
 | 
						|
 | 
						|
class wxTestEvent : public wxEvent
 | 
						|
{
 | 
						|
public:
 | 
						|
    wxTestEvent(wxEventType type = wxEVT_TEST) : wxEvent(0, type) { }
 | 
						|
    virtual wxEvent *Clone() const { return new wxTestEvent(GetEventType()); }
 | 
						|
};
 | 
						|
 | 
						|
class wxTestSink : public wxEvtHandler
 | 
						|
{
 | 
						|
public:
 | 
						|
    void OnTestEvent(wxEvent& evt)
 | 
						|
    {
 | 
						|
        if ( evt.GetEventObject() == gs_psrc1 )
 | 
						|
            gs_value += 1;
 | 
						|
        else if ( evt.GetEventObject() == gs_psrc2 )
 | 
						|
            gs_value += 0x10000;
 | 
						|
    }
 | 
						|
 | 
						|
    void OnTestEvent1(wxEvent& )
 | 
						|
    {
 | 
						|
        gs_value += 0x00100;
 | 
						|
    }
 | 
						|
 | 
						|
    void OnTestEvent2(wxEvent&)
 | 
						|
    {
 | 
						|
        gs_value += 0x01000000;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
// test class
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
 | 
						|
class EvtConnectionTestCase : public CppUnit::TestCase
 | 
						|
{
 | 
						|
public:
 | 
						|
    EvtConnectionTestCase() {}
 | 
						|
 | 
						|
private:
 | 
						|
    CPPUNIT_TEST_SUITE( EvtConnectionTestCase );
 | 
						|
        CPPUNIT_TEST( SinkTest );
 | 
						|
        CPPUNIT_TEST( SourceDestroyTest );
 | 
						|
        CPPUNIT_TEST( MultiConnectionTest );
 | 
						|
    CPPUNIT_TEST_SUITE_END();
 | 
						|
 | 
						|
    void SinkTest();
 | 
						|
    void SourceDestroyTest();
 | 
						|
    void MultiConnectionTest();
 | 
						|
 | 
						|
    DECLARE_NO_COPY_CLASS(EvtConnectionTestCase)
 | 
						|
};
 | 
						|
 | 
						|
// register in the unnamed registry so that these tests are run by default
 | 
						|
CPPUNIT_TEST_SUITE_REGISTRATION( EvtConnectionTestCase );
 | 
						|
 | 
						|
// also include in it's own registry so that these tests can be run alone
 | 
						|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtConnectionTestCase, "EvtConnectionTestCase" );
 | 
						|
 | 
						|
 | 
						|
// Helpers
 | 
						|
void DoConnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
 | 
						|
    eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
 | 
						|
                NULL, &ts);
 | 
						|
    eh2.Connect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
 | 
						|
                NULL, &ts);
 | 
						|
}
 | 
						|
 | 
						|
void DoDisconnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
 | 
						|
    eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
 | 
						|
                NULL, &ts);
 | 
						|
    eh2.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
 | 
						|
                NULL, &ts);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void EvtConnectionTestCase::SinkTest()
 | 
						|
{
 | 
						|
    // Let the sink be destroyed before the sources
 | 
						|
 | 
						|
    // An event used below
 | 
						|
    wxTestEvent evt;
 | 
						|
 | 
						|
    // Connect two event handlers to one sink
 | 
						|
    wxEvtHandler eh1, eh2;
 | 
						|
    gs_psrc1 = &eh1;
 | 
						|
    gs_psrc2 = &eh2;
 | 
						|
 | 
						|
    {
 | 
						|
        wxTestSink ts;
 | 
						|
        CPPUNIT_ASSERT( !ts.GetFirst() );
 | 
						|
        DoConnect(eh1, eh2, ts);
 | 
						|
 | 
						|
        DoDisconnect(eh1, eh2, ts);
 | 
						|
 | 
						|
        DoConnect(eh1, eh2, ts);
 | 
						|
 | 
						|
        // Fire events
 | 
						|
        evt.SetEventObject(&eh1);
 | 
						|
        eh1.ProcessEvent(evt);
 | 
						|
        evt.SetEventObject(&eh2);
 | 
						|
        eh2.ProcessEvent(evt);
 | 
						|
 | 
						|
        // Make sure they were processed correctly
 | 
						|
        CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
 | 
						|
    }
 | 
						|
 | 
						|
    // Fire events again, should be no sink connected now
 | 
						|
    gs_value = 0;
 | 
						|
    evt.SetEventObject(&eh1);
 | 
						|
    eh1.ProcessEvent( evt );
 | 
						|
    evt.SetEventObject(&eh2);
 | 
						|
    eh2.ProcessEvent( evt );
 | 
						|
 | 
						|
    // Make sure no processing happened
 | 
						|
    CPPUNIT_ASSERT_EQUAL( 0, gs_value );
 | 
						|
}
 | 
						|
 | 
						|
void EvtConnectionTestCase::SourceDestroyTest()
 | 
						|
{
 | 
						|
    // Let the sources be destroyed before the sink
 | 
						|
    wxTestSink ts;
 | 
						|
    wxTestEvent evt;
 | 
						|
    {
 | 
						|
        wxEvtHandler eh1;
 | 
						|
        {
 | 
						|
            CPPUNIT_ASSERT( !ts.GetFirst() );
 | 
						|
 | 
						|
            // Connect two event handlers to one sink
 | 
						|
            wxEvtHandler eh2;
 | 
						|
            gs_psrc1 = &eh1;
 | 
						|
            gs_psrc2 = &eh2;
 | 
						|
            DoConnect( eh1, eh2, ts );
 | 
						|
 | 
						|
            // Fire events
 | 
						|
            gs_value = 0;
 | 
						|
            evt.SetEventObject(&eh1);
 | 
						|
            eh1.ProcessEvent( evt );
 | 
						|
            evt.SetEventObject(&eh2);
 | 
						|
            eh2.ProcessEvent( evt );
 | 
						|
 | 
						|
            // Make sure they were processed correctly
 | 
						|
            CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
 | 
						|
        }
 | 
						|
 | 
						|
        gs_value = 0;
 | 
						|
        evt.SetEventObject(&eh1);
 | 
						|
        eh1.ProcessEvent( evt );
 | 
						|
 | 
						|
        // Make sure still connected
 | 
						|
        CPPUNIT_ASSERT_EQUAL( 0x00000001, gs_value );
 | 
						|
    }
 | 
						|
    CPPUNIT_ASSERT( !ts.GetFirst() );
 | 
						|
}
 | 
						|
 | 
						|
void EvtConnectionTestCase::MultiConnectionTest()
 | 
						|
{
 | 
						|
    // events used below
 | 
						|
    wxTestEvent evt;
 | 
						|
    wxTestEvent evt1(wxEVT_TEST1);
 | 
						|
    wxTestEvent evt2(wxEVT_TEST2);
 | 
						|
 | 
						|
    // One source
 | 
						|
    wxEvtHandler eh1;
 | 
						|
    evt.SetEventObject(&eh1);
 | 
						|
    gs_psrc1 = NULL;
 | 
						|
    gs_psrc2 = &eh1;
 | 
						|
 | 
						|
    {
 | 
						|
        // ...and one sink
 | 
						|
        wxTestSink ts;
 | 
						|
 | 
						|
        eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
 | 
						|
                    NULL, &ts);
 | 
						|
        eh1.Connect(wxEVT_TEST1, (wxObjectEventFunction)&wxTestSink::OnTestEvent1,
 | 
						|
                    NULL, &ts);
 | 
						|
        eh1.Connect(wxEVT_TEST2, (wxObjectEventFunction)&wxTestSink::OnTestEvent2,
 | 
						|
                    NULL, &ts);
 | 
						|
 | 
						|
        // Generate events
 | 
						|
        gs_value = 0;
 | 
						|
        eh1.ProcessEvent(evt);
 | 
						|
        eh1.ProcessEvent(evt1);
 | 
						|
        eh1.ProcessEvent(evt2);
 | 
						|
        CPPUNIT_ASSERT( gs_value==0x01010100 );
 | 
						|
 | 
						|
        {
 | 
						|
            // Declare weak references to the objects (using same list)
 | 
						|
            wxEvtHandlerRef re(&eh1), rs(&ts);
 | 
						|
        }
 | 
						|
        // And now destroyed
 | 
						|
 | 
						|
        eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
 | 
						|
                       NULL, &ts);
 | 
						|
        eh1.ProcessEvent(evt);
 | 
						|
        eh1.ProcessEvent(evt1);
 | 
						|
        eh1.ProcessEvent(evt2);
 | 
						|
        CPPUNIT_ASSERT_EQUAL( 0x02010200, gs_value );
 | 
						|
    }
 | 
						|
 | 
						|
    // No connection should be left now
 | 
						|
    gs_value = 0;
 | 
						|
    eh1.ProcessEvent(evt);
 | 
						|
    eh1.ProcessEvent(evt1);
 | 
						|
    eh1.ProcessEvent(evt2);
 | 
						|
 | 
						|
    // Nothing should have been done
 | 
						|
    CPPUNIT_ASSERT_EQUAL( 0, gs_value );
 | 
						|
}
 | 
						|
 |