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 )