signaltest.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2004-2007 University of Southern California
00006 // Rob Peters <rjpeters at usc dot edu>
00007 //
00008 // created: Wed Oct 13 08:31:39 2004
00009 // commit: $Id: signaltest.cc 10065 2007-04-12 05:54:56Z rjpeters $
00010 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/pkgs/whitebox/signaltest.cc $
00011 //
00012 // --------------------------------------------------------------------
00013 //
00014 // This file is part of GroovX.
00015 //   [http://ilab.usc.edu/rjpeters/groovx/]
00016 //
00017 // GroovX is free software; you can redistribute it and/or modify it
00018 // under the terms of the GNU General Public License as published by
00019 // the Free Software Foundation; either version 2 of the License, or
00020 // (at your option) any later version.
00021 //
00022 // GroovX is distributed in the hope that it will be useful, but
00023 // WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025 // General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with GroovX; if not, write to the Free Software Foundation,
00029 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00030 //
00032 
00033 #ifndef GROOVX_PKGS_WHITEBOX_SIGNALTEST_CC_UTC20050626084022_DEFINED
00034 #define GROOVX_PKGS_WHITEBOX_SIGNALTEST_CC_UTC20050626084022_DEFINED
00035 
00036 #include "pkgs/whitebox/signaltest.h"
00037 
00038 #include "nub/signal.h"
00039 
00040 #include "tcl/pkg.h"
00041 
00042 #include "rutz/unittest.h"
00043 
00044 #include "rutz/trace.h"
00045 
00046 namespace
00047 {
00048   int v0 = 0;
00049   int v1 = 0;
00050 
00051   void v0_callback0() { ++v0; }
00052   void v1_callback0() { --v1; }
00053 
00054   void v0_callback1(int i) { v0 += i; }
00055   void v1_callback1(int i) { v1 -= i; }
00056 
00057   void testSlotAdapterFreeFunc0()
00058   {
00059     nub::signal0 sig0;
00060 
00061     v0 = 0;
00062     v1 = 0;
00063     TEST_REQUIRE_EQ(v0, 0);
00064     TEST_REQUIRE_EQ(v1, 0);
00065 
00066     sig0.emit();
00067     TEST_REQUIRE_EQ(v0, 0);
00068     TEST_REQUIRE_EQ(v1, 0);
00069 
00070     nub::soft_ref<nub::slot0> s0 = sig0.connect(&v0_callback0);
00071     sig0.emit();
00072     TEST_REQUIRE_EQ(v0, 1);
00073     TEST_REQUIRE_EQ(v1, 0);
00074 
00075     nub::soft_ref<nub::slot0> s1 = sig0.connect(&v1_callback0);
00076     sig0.emit();
00077     TEST_REQUIRE_EQ(v0, 2);
00078     TEST_REQUIRE_EQ(v1, -1);
00079 
00080     sig0.disconnect(s0);
00081     sig0.emit();
00082     TEST_REQUIRE_EQ(v0, 2);
00083     TEST_REQUIRE_EQ(v1, -2);
00084 
00085     sig0.disconnect(s1);
00086     sig0.emit();
00087     TEST_REQUIRE_EQ(v0, 2);
00088     TEST_REQUIRE_EQ(v1, -2);
00089   }
00090 
00091   void testSignalSlotChain()
00092   {
00093     nub::signal0 sig1;
00094     nub::signal0 sig2;
00095     nub::signal0 sig3;
00096 
00097     sig3.connect(&v0_callback0); // sig3 --> v0_callback0
00098 
00099     v0 = 0;
00100     TEST_REQUIRE_EQ(v0, 0);
00101 
00102     sig1.emit(); TEST_REQUIRE_EQ(v0, 0);
00103     sig2.emit(); TEST_REQUIRE_EQ(v0, 0);
00104     sig3.emit(); TEST_REQUIRE_EQ(v0, 1);
00105 
00106     sig2.connect(sig3.slot()); // sig2 --> sig3 --> v0_callback0
00107 
00108     sig1.emit(); TEST_REQUIRE_EQ(v0, 1);
00109     sig2.emit(); TEST_REQUIRE_EQ(v0, 2);
00110     sig3.emit(); TEST_REQUIRE_EQ(v0, 3);
00111 
00112     sig1.connect(sig2.slot()); // sig1 --> sig2 --> sig3 --> v0_callback0
00113 
00114     sig1.emit(); TEST_REQUIRE_EQ(v0, 4);
00115     sig2.emit(); TEST_REQUIRE_EQ(v0, 5);
00116     sig3.emit(); TEST_REQUIRE_EQ(v0, 6);
00117 
00118     sig2.disconnect(sig3.slot()); // sig1 --> sig2 XX sig3 --> v0_callback0
00119 
00120     sig1.emit(); TEST_REQUIRE_EQ(v0, 6);
00121     sig2.emit(); TEST_REQUIRE_EQ(v0, 6);
00122     sig3.emit(); TEST_REQUIRE_EQ(v0, 7);
00123   }
00124 
00125   void testCyclicSignalSlotChain()
00126   {
00127     // This test is to make sure that we don't let ourselves get into
00128     // infinite loops even if there are cyclic patterns of connections
00129     // between signals and slots. This is implemented with
00130     // nub::signal_base::Impl::isItEmitting, which is locked by
00131     // nub::signal_base::Impl::Lock on entry to
00132     // nub::signal_base::do_emit().
00133 
00134     nub::signal0 sig1;
00135     nub::signal0 sig2;
00136     nub::signal0 sig3;
00137 
00138     sig3.connect(&v0_callback0); // sig3 --> v0_callback0
00139     sig2.connect(sig3.slot()); // sig2 --> sig3 --> v0_callback0
00140     sig1.connect(sig2.slot()); // sig1 --> sig2 --> sig3 --> v0_callback0
00141 
00142     sig3.connect(sig1.slot()); // sig1 --> sig2 --> sig3 --> v0_callback0
00143                                //  ^                 |
00144                                //  |                 |
00145                                //  +-----------------+
00146 
00147     v0 = 0;
00148     TEST_REQUIRE_EQ(v0, 0);
00149 
00150     sig1.emit(); TEST_REQUIRE_EQ(v0, 1);
00151     sig2.emit(); TEST_REQUIRE_EQ(v0, 2);
00152     sig3.emit(); TEST_REQUIRE_EQ(v0, 3);
00153   }
00154 
00155   void testSlotAdapterFreeFunc1()
00156   {
00157     nub::Signal1<int> sig1;
00158 
00159     v0 = 0;
00160     v1 = 0;
00161     TEST_REQUIRE_EQ(v0, 0);
00162     TEST_REQUIRE_EQ(v1, 0);
00163 
00164     sig1.emit(1);
00165     TEST_REQUIRE_EQ(v0, 0);
00166     TEST_REQUIRE_EQ(v1, 0);
00167 
00168     nub::soft_ref<nub::slot1<int> > s0 = sig1.connect(&v0_callback1);
00169     sig1.emit(2);
00170     TEST_REQUIRE_EQ(v0, 2);
00171     TEST_REQUIRE_EQ(v1, 0);
00172 
00173     nub::soft_ref<nub::slot1<int> > s1 = sig1.connect(&v1_callback1);
00174     sig1.emit(3);
00175     TEST_REQUIRE_EQ(v0, 5);
00176     TEST_REQUIRE_EQ(v1, -3);
00177 
00178     sig1.disconnect(s0);
00179     sig1.emit(4);
00180     TEST_REQUIRE_EQ(v0, 5);
00181     TEST_REQUIRE_EQ(v1, -7);
00182 
00183     sig1.disconnect(s1);
00184     sig1.emit(5);
00185     TEST_REQUIRE_EQ(v0, 5);
00186     TEST_REQUIRE_EQ(v1, -7);
00187   }
00188 }
00189 
00190 extern "C"
00191 int Signaltest_Init(Tcl_Interp* interp)
00192 {
00193 GVX_TRACE("Signaltest_Init");
00194 
00195   GVX_PKG_CREATE(pkg, interp, "Signaltest", "4.$Revision: 10065 $");
00196 
00197   DEF_TEST(pkg, testSlotAdapterFreeFunc0);
00198   DEF_TEST(pkg, testSignalSlotChain);
00199   DEF_TEST(pkg, testCyclicSignalSlotChain);
00200   DEF_TEST(pkg, testSlotAdapterFreeFunc1);
00201 
00202   GVX_PKG_RETURN(pkg);
00203 }
00204 
00205 // Need these to avoid dyld errors on Mac OS X
00206 extern "C" int Signaltest_SafeInit(Tcl_Interp*)
00207 { return 1; }
00208 
00209 extern "C" int Signaltest_Unload(Tcl_Interp* interp, int /*flags*/)
00210 {
00211 GVX_TRACE("Signaltest_Unload");
00212   return tcl::pkg::destroy_on_unload(interp, "Signaltest");
00213 }
00214 
00215 extern "C" int Signaltest_SafeUnload(Tcl_Interp*, int /*flags*/)
00216 { return 1; }
00217 
00218 static const char __attribute__((used)) vcid_groovx_pkgs_whitebox_signaltest_cc_utc20050626084022[] = "$Id: signaltest.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00219 #endif // !GROOVX_PKGS_WHITEBOX_SIGNALTEST_CC_UTC20050626084022_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.