text: #pragma once
  
  namespace VMG {
  	namespace Util {
  		template<typename S, typename A>
  		class Event {			
  			typedef void(*FUN_CALLBACK_CLS)(void*, S*, A);
  			typedef void(*FUN_CALLBACK_STATIC)(S*, A);
  		
  			public:
  				// Connect function (non tpyed)
  				inline void connect(FUN_CALLBACK_STATIC cb) {
  					m_callbackStatic = cb;
  					m_ptrObject = nullptr;
  				}
  
  				// Connect function (type)
  				template<typename T, typename AT>
  				void connect(AT cb, T* ptrObject) {
  					m_callbackTyped = (FUN_CALLBACK_CLS)*(void**)&cb;
  					m_ptrObject = ptrObject;
  				}
  
  				// Connect operator
  				inline void operator=(FUN_CALLBACK_STATIC cb) {
  					connect(cb);
  				}
  				
  			protected:
  				// S is allowed to call
  				friend S;
  
  				// Call event
  				void call(S* sender, A argument) {
  					// Call if exists
  					if (m_callbackStatic && m_ptrObject == nullptr) {
  						m_callbackStatic(sender, argument);
  					}
  					else if (m_callbackTyped && m_ptrObject) {
  						m_callbackTyped(m_ptrObject, sender, argument);
  					}
  				}
  
  				// Call operator
  				inline void operator()(S* sender, A argument) {
  					call(sender, argument);
  				}
  
  			private:
  				// Null event
  				union {
  					FUN_CALLBACK_STATIC m_callbackStatic = nullptr;
  					FUN_CALLBACK_CLS m_callbackTyped;
  				};
  
  				// Object (event is typed when object not null)
  				void* m_ptrObject = nullptr;
  		};
  	
  	}
  }