Skip to content

Instantly share code, notes, and snippets.

@trentpolack
Last active December 27, 2017 22:58
Show Gist options
  • Save trentpolack/ee6df817817a78d8ea996104fbd596ea to your computer and use it in GitHub Desktop.
Save trentpolack/ee6df817817a78d8ea996104fbd596ea to your computer and use it in GitHub Desktop.
Getting around a series of annoying issues (C++'s existence and UE4's syntactical quirks) through a lambda-as-function-pointer-with-arguments.
// Structure to define a lambda object, return type, and any arguments to pass into the lambda expression upon execution.
template< typename O, typename R, typename ... A >
struct LambdaExpression
{
O _object;
R( O::*_function )( A... ) const;
LambdaExpression( const O & object )
: _object( object ), _function( &decltype( _object )::operator() )
{ }
R operator( )( A ... args ) const
{
return ( _object.*_function )( args... );
}
};
// Function to execute the lambda expression.
auto SpawnProjectileLambda( )
{
auto lambda = [=]( AMechPartWeapon* Weapon ) {
return( Weapon->SpawnPooledProjectile( ) );
};
return( LambdaExpression< decltype( lambda ), AMechPartWeapon*, IPooledObject* >( lambda ) );
}
// Sample class method to take the lambda expression as a function pointer.
template< typename T >
IPooledObject* GetPooledObject( T& LambdaSpawnExpression );
template< typename T >
IPooledObject* UObjectPool::GetPooledObject( T& LambdaSpawnExpression )
{
T* pInstance = GetPooledObject< T >( );
if( pInstance == nullptr )
{
// Instantiate a new object and add it to the pool.
pInstance = LambdaSpawnExpression( );
ensure( pInstance != nullptr );
Add( pInstance, true );
}
return pInstance;
}
// And its final actual use case:
AProjectile* pProjectile = Cast< AProjectile >( ProjectilePool->GetPooledObject( SpawnProjectileLambda ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment