Guest
Public paste!

nameczanin

By: a guest | Feb 6th, 2008 | Syntax: C++ | Size: 10.41 KB | Hits: 71 | Expires: Never
Copy text to clipboard
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <cstdarg>
  5.  
  6. using namespace std;
  7.  
  8.  
  9. //taka klasa zupelnie abstrakcyjna, potrzebna tylko do polaczenia typow
  10. class CCallback_Base
  11. {
  12.  
  13. protected:
  14.  
  15.         //mozna powiedziec, ze cala klasa jest dla szpicu
  16.  
  17. public:
  18.  
  19.     //ale sprobujcie ja wyrzucic :P
  20.  
  21. };
  22.  
  23. //maly singleton do tworzenia id dla kolejnych callbackow
  24. class CCallbackIdCreator
  25. {
  26.  
  27. private:
  28.  
  29.     unsigned int m_dLastId;
  30.  
  31.  
  32. public:
  33.  
  34.     CCallbackIdCreator()
  35.     {
  36.         m_dLastId = 0;
  37.     }
  38.  
  39.     static CCallbackIdCreator& inst()
  40.     {
  41.         static CCallbackIdCreator m_inst;
  42.  
  43.         return m_inst;
  44.     }
  45.  
  46.  
  47. private:
  48.  
  49.     unsigned int getId()
  50.     {
  51.         return ++m_dLastId;
  52.     }
  53.  
  54.     template <class> friend class Func;
  55.  
  56. };
  57.  
  58. //funkcja/metoda (wskaznik)
  59. template <typename T> class Func
  60. {
  61.  
  62. private:
  63.  
  64.     //metody w klasie
  65.         void(T::*m_Method)(void*);
  66.     int(T::*m_MethodInt)(void*);
  67.     void(CCallback_Base::*m_pMethod)(void*);
  68.     int(CCallback_Base::*m_pMethodInt)(void*);
  69.         T* m_pClassInst;
  70.  
  71.     //funkcje globalne
  72.     void* m_pThis;
  73.     void(*m_pFunc)(void*);
  74.     int(*m_pFuncInt)(void*);
  75.     void* m_pParameter;
  76.  
  77.     //info o tym czego uzywamy w tej instancji tej klasy
  78.     int m_bIsInstantiated;
  79.     int m_bIsClass;
  80.     int m_bIsInt;
  81.  
  82.     //id
  83.     unsigned int m_id;
  84.  
  85.  
  86.     //typy pomocnicze
  87.     typedef void (CCallback_Base::*MethodType)(void*);
  88.     typedef void (T::*MethodType_T)(void*);
  89.  
  90.     typedef int (CCallback_Base::*MethodType_Int)(void*);
  91.     typedef int (T::*MethodType_T_Int)(void*);
  92.  
  93.  
  94. public:
  95.  
  96.     //ten konstruktor tylko zeruje wszystko
  97.     Func()
  98.     {
  99.         m_pThis = NULL;
  100.         m_pFunc = NULL;
  101.         m_pFuncInt = NULL;
  102.         m_pParameter = NULL;
  103.  
  104.         m_pClassInst = NULL;
  105.         m_Method = NULL;
  106.         m_MethodInt = NULL;
  107.  
  108.         m_bIsInstantiated = false;
  109.         m_bIsClass = false;
  110.         m_bIsInt = false;
  111.  
  112.         m_id = 0;
  113.     }
  114.  
  115.     //konstruktor dla metod
  116.     Func( T* class_inst, int isInt, ... )
  117.         {
  118.         va_list list;
  119.  
  120.  
  121.                 m_pClassInst = class_inst;
  122.  
  123.         va_start( list, isInt );
  124.  
  125.             if( isInt )
  126.                 m_pMethodInt = (MethodType_Int) va_arg( list, MethodType_Int );
  127.             else
  128.                 m_pMethod = va_arg( list, MethodType );
  129.  
  130.             m_pParameter = va_arg( list, void* );
  131.  
  132.         va_end( list );
  133.  
  134.         va_start( list, isInt );
  135.  
  136.             if( isInt )
  137.                 m_MethodInt = va_arg( list, MethodType_T_Int );
  138.             else
  139.                 m_Method = va_arg( list, MethodType_T );
  140.  
  141.         va_end( list );
  142.        
  143.  
  144.         m_bIsInstantiated = true;
  145.         m_bIsClass = true;
  146.         m_bIsInt = isInt;
  147.  
  148.         m_id = CCallbackIdCreator::inst().getId();
  149.         }
  150.  
  151.     //konstruktory dla funkcji
  152.     Func( void* This, void(*func)(void*), void* par )
  153.     {
  154.         m_pThis = This;
  155.         m_pFunc = func;
  156.         m_pParameter = par;
  157.  
  158.         m_bIsInstantiated = true;
  159.         m_bIsClass = false;
  160.         m_bIsInt = false;
  161.  
  162.         m_id = CCallbackIdCreator::inst().getId();
  163.     }
  164.  
  165.     Func( void* This, int(*func)(void*), void* par )
  166.     {
  167.         m_pThis = This;
  168.         m_pFuncInt = func;
  169.         m_pParameter = par;
  170.  
  171.         m_bIsInstantiated = true;
  172.         m_bIsClass = false;
  173.         m_bIsInt = true;
  174.  
  175.         m_id = CCallbackIdCreator::inst().getId();
  176.     }
  177.  
  178.  
  179. private:
  180.  
  181.     void SetId( unsigned int id )
  182.     {
  183.         m_id = id;
  184.     }
  185.  
  186.     void SetClassInst( CCallback_Base* class_inst )
  187.     {
  188.         m_pClassInst = (T*) class_inst;
  189.     }
  190.  
  191.     CCallback_Base* GetClassInst()
  192.     {
  193.         return (CCallback_Base*)m_pClassInst;
  194.     }
  195.  
  196.     void SetMethod( void(CCallback_Base::*Method)(void*) )
  197.     {
  198.         m_pMethod = Method;
  199.         m_bIsInstantiated = true;
  200.         m_bIsClass = true;
  201.         m_bIsInt = false;
  202.     }
  203.  
  204.     MethodType GetMethod()
  205.     {
  206.         return m_pMethod;
  207.     }
  208.  
  209.     void SetFunc( void* This, void(*func)(void*), void* par )
  210.     {
  211.         m_pThis = This;
  212.         m_pFunc = func;
  213.         m_pParameter = par;
  214.  
  215.         m_bIsInstantiated = true;
  216.         m_bIsClass = false;
  217.         m_bIsInt = false;
  218.     }
  219.  
  220.     void SetFunc( void* This, int(*func)(void*), void* par )
  221.     {
  222.         m_pThis = This;
  223.         m_pFuncInt = func;
  224.         m_pParameter = par;
  225.  
  226.         m_bIsInstantiated = true;
  227.         m_bIsClass = false;
  228.         m_bIsInt = true;
  229.     }
  230.  
  231.     void Call( void* par = NULL )
  232.     {
  233.         if( par != NULL )
  234.             m_pParameter = par;
  235.  
  236.  
  237.         if( m_bIsInstantiated )
  238.         if( m_bIsClass )
  239.         {
  240.             (m_pClassInst->*m_pMethod)( m_pParameter );
  241.         }
  242.         else
  243.         {
  244.             //assembler potrzebny, aby uwzglednic 'this' danej funkcji
  245.             void* pFunc = (void*) m_pFunc;
  246.             void* pParameter = (void*) m_pParameter;
  247.  
  248.             //jakby co to zawsze wrzucamy parametr na stos, chocby mial byc = 0
  249.                 __asm
  250.                 {
  251.                         mov ecx,[m_pThis];  //ustawiamy parametr This dla funkcji (zeby wiedziala skad dziala)
  252.                         push pParameter;    //wrzucamy parametr na stos
  253.                         call [pFunc];       //wywolujemy funkcje
  254.                 add sp, 4;          //czyszczenie stosu (parametrow)
  255.                 }
  256.         }
  257.     }
  258.  
  259.     int CallInt( void* par = NULL )
  260.     {
  261.         if( par != NULL )
  262.             m_pParameter = par;
  263.  
  264.         if( m_bIsInstantiated )
  265.         if( m_bIsClass )
  266.         {
  267.             (m_pClassInst->*m_pMethodInt)( m_pParameter );
  268.         }
  269.         else
  270.         {
  271.             //assembler potrzebny, aby uwzglednic 'this' danej funkcji
  272.             void* pFunc = (void*) m_pFuncInt;
  273.             void* pParameter = (void*) m_pParameter;
  274.  
  275.             //jakby co to zawsze wrzucamy parametr na stos, chocby mial byc = 0
  276.            
  277.                 __asm
  278.                 {
  279.                         mov ecx,[m_pThis];  //ustawiamy parametr This dla funkcji (zeby wiedziala skad dziala)
  280.                         push pParameter;    //wrzucamy parametr na stos
  281.                         call [pFunc];       //wywolujemy funkcje
  282.                 add sp, 4;          //czyszczenie stosu (parameter)
  283.                 }
  284.                
  285.         }
  286.  
  287.         //aby kompilator sie nie plul w zasadzie :P
  288.         return true;
  289.     }
  290.  
  291.  
  292. public:
  293.  
  294.     void operator=( const Func<T>& obj )
  295.     {
  296.         m_pThis = obj.m_pThis;
  297.         m_pFunc = obj.m_pFunc;
  298.         m_pFuncInt = obj.m_pFuncInt;
  299.         m_pParameter = obj.m_pParameter;
  300.  
  301.         m_pClassInst = obj.m_pClassInst;
  302.         m_Method = obj.m_Method;
  303.         m_MethodInt = obj.m_MethodInt;
  304.  
  305.         m_bIsInstantiated = obj.m_bIsInstantiated;
  306.         m_bIsClass = obj.m_bIsClass;
  307.         m_bIsInt = obj.m_bIsInt;
  308.  
  309.         m_id = obj.m_id;
  310.     }
  311.  
  312.     bool operator==( const Func<T>& obj ) const
  313.     {
  314.         if( m_id == obj.m_id )
  315.             return true;
  316.         else
  317.             return false;
  318.     }
  319.  
  320.     bool operator!=( const Func<T>& obj ) const
  321.     {
  322.         if( m_id != obj.m_id )
  323.             return true;
  324.         else
  325.             return false;
  326.     }
  327.  
  328.  
  329.     friend class Callback;
  330.  
  331. };
  332.  
  333.  
  334. //container (handler)
  335. class Callback
  336. {
  337.  
  338. private:
  339.        
  340.     Func<CCallback_Base> m_callback;
  341.  
  342.  
  343. public:
  344.  
  345.     //konstruktory ogolne
  346.     Callback()
  347.     {
  348.     }
  349.  
  350.     Callback( const Callback& obj )
  351.     {
  352.         m_callback = obj.m_callback;
  353.     }
  354.  
  355.  
  356.     //destruktor dla niektorych kompilatorow bez wyobrazni
  357.     ~Callback()
  358.     {
  359.     }
  360.  
  361.     //konstruktor dla metod
  362.     template <typename T> Callback( Func<T> method )
  363.     {
  364.         m_callback.SetClassInst( method.GetClassInst() );
  365.         m_callback.SetMethod( method.GetMethod() );
  366.     }
  367.  
  368.     //konstruktory dla funkcji
  369.     Callback( void* This, void(*func)(void*), void* par )
  370.     {
  371.         m_callback.SetFunc( This, func, par );
  372.     }
  373.  
  374.     Callback( void* This, int(*func)(void*), void* par )
  375.     {
  376.         m_callback.SetFunc( This, func, par );
  377.     }
  378.  
  379.     //wywolanie metody/funkcji
  380.     void call( void* par = NULL )
  381.     {
  382.         m_callback.Call( par );
  383.     }
  384.  
  385.     //wywolanie metody/funkcji ze zwrotem parametru
  386.     int callInt( void* par = NULL )
  387.     {
  388.         return m_callback.CallInt( par );
  389.     }
  390.  
  391.     void operator= ( const Callback& obj )
  392.     {
  393.         m_callback = obj.m_callback;
  394.     }
  395.  
  396.     bool operator==( const Callback& obj ) const
  397.     {
  398.         if( m_callback.m_id == obj.m_callback.m_id )
  399.             return true;
  400.         else
  401.             return false;
  402.     }
  403.  
  404.     bool operator!=( const Callback& obj ) const
  405.     {
  406.         if( m_callback.m_id != obj.m_callback.m_id )
  407.             return true;
  408.         else
  409.             return false;
  410.     }
  411.  
  412. };
  413.  
  414.  
  415.  
  416. /* test functions */
  417. void some_func3_1( void* );
  418. void some_func3_2( void* );
  419. int some_func3_3( void* );
  420. void some_func( void* );
  421.  
  422.  
  423. //test A
  424. void some_func( void* par )
  425. {
  426.     cout << "\tcalled some_func" << endl;
  427.     if( par != NULL )
  428.         cout << "\t\tgot param: " << ((int)par) << endl;
  429. }
  430.  
  431. //test B
  432. int some_func3_3( void* myInt )
  433. {
  434.     int dTmp = (int) myInt;
  435.  
  436.     cout << "\tcalled some_func3_3" << endl << "\t\tgot param: " << dTmp << endl << "\t\tret val: ";
  437.     if( dTmp != 4 )
  438.     {
  439.         cout << "false (par != 4)" << endl;
  440.         return false;
  441.     }
  442.    
  443.     cout << "true (par == 4)" << endl;
  444.     return true;
  445. }
  446.  
  447. //test C
  448. //global func inside another func
  449.  
  450. Callback c( &some_func3_1, &some_func3_2, NULL );
  451.  
  452. void some_func3_2( void* myInt )
  453. {
  454.     int dTmp = (int) myInt;
  455.  
  456.     cout << "\tcalled some_func3_2" << endl << "\t\tgot param: " << dTmp << endl;
  457. }
  458.  
  459. void some_func3_1( void* )
  460. {
  461.     int myPrivateInt = 6;
  462.  
  463.     c.call( (void*) myPrivateInt );
  464. }
  465.  
  466. //test D
  467. class SomeClass
  468. {
  469.  
  470. public:
  471.  
  472.     SomeClass(){}
  473.     ~SomeClass(){}
  474.  
  475.     void someMethod( void* par )
  476.     {
  477.         cout << "\tcalled someMethod" << endl;
  478.         if( par != NULL )
  479.             cout << "\t\tgot param: " << ((int)par) << endl;
  480.     }
  481.  
  482. };
  483.  
  484. //test A, B, C, D
  485. int main( int argc, char* argv[] )
  486. {
  487.     //class method
  488.     SomeClass obj;
  489.     Callback d( Func<SomeClass>(&obj, false, &SomeClass::someMethod, 0) );
  490.    
  491.     //global func
  492.     Callback a( 0, &some_func, 0 );
  493.     Callback b( 0, &some_func3_3, (void*)4 );
  494.  
  495.  
  496.     //calling
  497.     cout << "void:" << endl;
  498.         a.call();
  499.         a.call( (void*) 123 );
  500.         d.call();
  501.         d.call( (void*) 5 );
  502.         some_func3_1( 0 );
  503.  
  504.     cout << endl << "int: " << endl;
  505.         b.callInt();
  506.  
  507.  
  508.     getchar();
  509.  
  510.     return 0;
  511. }