//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: A header describing use of the delegate system. It's hiding // the highly complex implementation details of the delegate system // // $NoKeywords: $ // //===========================================================================// #ifndef UTLDELEGATE_H #define UTLDELEGATE_H #ifdef _WIN32 #pragma once #endif //----------------------------------------------------------------------------- // The delegate system: A method of invoking methods, whether they are // member methods of classes, static methods of classes, or free functions, // dealing with all the nastiness in differences between how the calls have // to happen yet works in a highly optimal fashion. For details, see // // http://www.codeproject.com/cpp/FastDelegate.asp // // The delegate design pattern is described here // // http://en.wikipedia.org/wiki/Delegation_(programming) //----------------------------------------------------------------------------- #ifdef UTLDELEGATE_USAGE_DEMONSTRATION //----------------------------------------------------------------------------- // Here, we show how to use this system (the ifdef UTLDELEGATE_USAGE_DEMONSTRATION is used to get syntax coloring). //----------------------------------------------------------------------------- // First, define the functions you wish to call. int Test1( char *pString, float x ); class CTestClass { public: void Test2(); static float Test3( int x ); }; void Test() { CTestClass testClass; // CUtlDelegate is a class that can be used to invoke methods of classes // or static functions in a highly efficient manner. // There are a couple ways to hook up a delegate. One is in a constructor // Note that the template parameter of CUtlFastDelegate looks like the // function type: first, you have the return type, then ( parameter list ) CUtlDelegate< int ( char *, float ) > delegate1( &Test1 ); // Another way is to use the UtlMakeDelegate method, allowing you to // define the delegate later. Note that UtlMakeDelegate does *not* do a heap allocation CUtlDelegate< void () > delegate2; delegate2 = UtlMakeDelegate( &testClass, &CTestClass::Test2 ); // A third method is to use the Bind() method of CUtlFastDelegate // Note that you do not pass in the class pointer for static functions CUtlDelegate< float ( int ) > delegate3; delegate3.Bind( &CTestClass::Test3 ); // Use the () operator to invoke the function calls. int x = delegate1( "hello", 1.0f ); delegate2(); float y = delegate3( 5 ); // Use the Clear() method to unbind a delegate. delegate1.Clear(); // You can use operator! or IsEmpty() to see if a delegate is bound if ( !delegate1.IsEmpty() ) { delegate1( "hello2" ); } // Delegates maintain an internal non-templatized representation of the // functions they are bound to called CUtlAbstractDelegate. These are // useful when keeping a list of untyped delegates or when passing // delegates across interface boundaries. const CUtlAbstractDelegate &abstractDelegate3 = delegate3.GetAbstractDelegate(); CUtlDelegate< float ( int ) > delegate4; delegate4.SetAbstractDelegate( abstractDelegate3 ); delegate4( 10 ); } #endif // UTLDELEGATE_USAGE_DEMONSTRATION // Looking in this file may cause blindness. #include "tier1/utldelegateimpl.h" #endif // UTLDELEGATE_H