1 #ifndef AWFUL_LUA_GENERICPOINTER_H
2 #define AWFUL_LUA_GENERICPOINTER_H
4 namespace awful
{ namespace LuaImpl
6 template<> struct TypeConverter
< NormalType
, GenericPointer
>
8 class PointerConverter_i
: public RefCounted
11 virtual ~PointerConverter_i() {}
12 virtual void ConvertFromLua_nocheck( lua_State
* pLS
, int Index_
, GenericPointer
& Dest_
) = 0;
13 virtual void ConvertToLua( lua_State
* pLS
, const GenericPointer
& Dest_
) = 0;
16 template< class C
> class PointerConverter
: public PointerConverter_i
19 virtual void ConvertFromLua_nocheck( lua_State
* pLS
, int Index_
, GenericPointer
& Dest_
)
21 TypeConverter
< NormalType
, Pointer
< C
> > tc( pLS
);
23 tc
.ConvertFromLua_nocheck( Index_
, pObj
);
27 virtual void ConvertToLua( lua_State
* pLS
, const GenericPointer
& pObj_
)
29 TypeConverter
< NormalType
, Pointer
< C
> > tc( pLS
);
30 Pointer
< C
> pObj
= static_cast< C
* >( pObj_
);
31 tc
.ConvertToLua( pObj
);
35 typedef std::map
< TypeInfoKey
, Pointer
< PointerConverter_i
> > converter_map
;
36 static converter_map PointerConverters
;
38 template< class C
> static void RegisterClass()
40 PointerConverters
.insert( std::make_pair(
41 TypeInfoKey( typeid( C
) ),
42 new PointerConverter
< C
> ) );
45 TypeConverter( lua_State
* pLS_
) :
50 bool CheckType_nothrow( int Index_
)
52 // TODO: this is not very robust because it assume that any user data we get thrown
53 // at are our own wrapped pointers, whereas it could be some completely alien stuff.
54 if( lua_isnil( m_pLS
, Index_
) )
57 if( lua_type( m_pLS
, Index_
) != LUA_TUSERDATA
)
60 PointerWrapper
< RefCounted
>* pWrapper
=
61 static_cast< PointerWrapper
< RefCounted
>* >( lua_touserdata( m_pLS
, Index_
) );
63 converter_map::const_iterator it
= PointerConverters
.find( *pWrapper
->pTypeInfo
);
64 return it
!= PointerConverters
.end();
67 void ConvertFromLua( int Index_
, GenericPointer
& Dest_
)
69 if( !CheckType_nothrow( Index_
) )
70 throw Error::TypeMismatch( lua_type( m_pLS
, Index_
), LUA_TUSERDATA
);
72 ConvertFromLua_nocheck( Index_
, Dest_
);
75 void ConvertFromLua_nocheck( int Index_
, GenericPointer
& Dest_
)
77 if( lua_isnil( m_pLS
, Index_
) )
83 PointerWrapper
< RefCounted
>* pWrapper
=
84 static_cast< PointerWrapper
< RefCounted
>* >( lua_touserdata( m_pLS
, Index_
) );
86 // TODO: This could be cached from the possible prior call to CheckType_nothrow
87 // so as to avoid to look this up twice.
88 converter_map::const_iterator it
= PointerConverters
.find( *pWrapper
->pTypeInfo
);
89 it
->second
->ConvertFromLua_nocheck( m_pLS
, Index_
, Dest_
);
92 void ConvertToLua( const GenericPointer
& Ptr_
)
98 converter_map::const_iterator it
= PointerConverters
.find( *Ptr_
.getDynamicType() );
100 // TODO: what if the GenericPointer somehow points to a type that is not registered
101 // in converter_map? We should throw a specific diagnostic message.
102 it
->second
->ConvertToLua( m_pLS
, Ptr_
);