SDL2-FFI
view release on metacpan or search on metacpan
lib/SDL2/Utils.pm view on Meta::CPAN
package SDL2::Utils {
# FFI utilities
use strict;
use warnings;
use experimental 'signatures';
use base 'Exporter::Tiny';
our @EXPORT = qw[attach define deprecate has enum ffi is threads_wrapped load_lib];
use FFI::CheckLib;
use FFI::Platypus 1.46;
use FFI::Platypus::Memory qw[malloc strcpy free];
use FFI::C;
use FFI::C::Def;
use FFI::C::ArrayDef;
use FFI::C::StructDef;
use FFI::C::UnionDef;
use FFI::Platypus::Closure;
use File::Spec::Functions qw[catdir canonpath rel2abs];
use Path::Tiny qw[path];
use File::Share qw[dist_dir];
use Config;
use SDL2::Utils::Type::Enum;
use Ref::Util qw( is_ref is_plain_arrayref is_plain_hashref );
sub deprecate ($str) {
warnings::warn( 'deprecated', $str ) if warnings::enabled('deprecated');
}
#sub ver() { # TODO: Remove in favor of SDL2::version
# CORE::state $ver;
# $ver // ffi()->function( SDL_GetVersion => ['SDL_Version'] )
# ->call( $ver = SDL2::Version->new() );
# $ver;
#}
sub threads_wrapped () { # Fake thread safe
#loaded_libs('api_wrapper');
1;
}
my $loaded_libs;
sub loaded_libs ($name) {
defined $loaded_libs->{$name} ? 1 : 0;
}
my %libs;
my %prereq = (
# Windows... this matters in Windows...
SDL2_image => [qw[SDL2 jpeg png16 tiff webp zlib1]],
SDL2_ttf => [qw[SDL2 freetype]],
api_wrapper => [qw[SDL2 SDL2_mixer]],
SDL2_mixer => [qw[]], # TODO
freetype => [qw[zlib1]]
);
sub load_lib ($name) {
$libs{all}{$name} // return; # This should be a fatal error
load_lib($_) for @{ $prereq{$name} // [] }; # Recurse!
my $_cdd = "\0" x 1024; # for Windows and SDL2_ttf
CORE::state $SetDllDirectoryA; # https://github.com/BindBC/bindbc-sdl/issues/10
CORE::state $GetDllDirectoryA;
if ( $^O eq 'MSWin32' ) {
if ( !defined $SetDllDirectoryA ) {
ffi()->lib( 'Kernel32.dll', undef );
$SetDllDirectoryA = ffi()->function( SetDllDirectoryA => ['string'] => 'bool' );
}
if ( !defined $GetDllDirectoryA ) {
ffi()->lib( 'Kernel32.dll', undef );
$GetDllDirectoryA
= ffi()->function( GetDllDirectoryA => [ 'int', 'string' ] => 'int' );
}
$_cdd = undef if !$GetDllDirectoryA->call( length $_cdd, $_cdd );
$SetDllDirectoryA->call(
Path::Tiny->new( $libs{all}{$name} )->parent->absolute->stringify );
}
#warn sprintf 'Loading %s => %s', $name, $libs{all}{$name} // '[missing]';
ffi()->lib( $libs{all}{$name} );
$SetDllDirectoryA->call($_cdd) if $^O eq 'MSWin32' && defined $_cdd;
$loaded_libs = {
map {
path($_)->basename(qw[.so .dylib .dll]) =~ m[^(?:lib)?(.+)(\-.+)?$];
$1 => $_
( run in 1.647 second using v1.01-cache-2.11-cpan-39bf76dae61 )