1. Wrapping Functions Inside of Struct?

Hi all,

I'm just wondering if there's a way to wrap functions that are in a struct or is there some other work-a-round?

 
//header file "file.h" from Allegro 
 
typedef struct ALLEGRO_FILE_INTERFACE 
{ 
   AL_METHOD(void *,  fi_fopen, (const char *path, const char *mode)); 
   AL_METHOD(bool,    fi_fclose, (ALLEGRO_FILE *handle)); 
   AL_METHOD(size_t,  fi_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); 
   AL_METHOD(size_t,  fi_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); 
   AL_METHOD(bool,    fi_fflush, (ALLEGRO_FILE *f)); 
   AL_METHOD(int64_t, fi_ftell, (ALLEGRO_FILE *f)); 
   AL_METHOD(bool,    fi_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); 
   AL_METHOD(bool,    fi_feof, (ALLEGRO_FILE *f)); 
   AL_METHOD(int,     fi_ferror, (ALLEGRO_FILE *f)); 
   AL_METHOD(const char *, fi_ferrmsg, (ALLEGRO_FILE *f)); 
   AL_METHOD(void,    fi_fclearerr, (ALLEGRO_FILE *f)); 
   AL_METHOD(int,     fi_fungetc, (ALLEGRO_FILE *f, int c)); 
   AL_METHOD(off_t,   fi_fsize, (ALLEGRO_FILE *f)); 
} ALLEGRO_FILE_INTERFACE; 

My vague idea would be

include std/ffi.e 
 
public constant ALLEGRO_FILE_INTERFACE = define_c_type({ 
         C_STRING, --path 
         C_STRING --mode 
}) 
 
OR 
 
--I feel like this wouldn't work, but its an idea I had.  
 
public constant ALLEGRO_FILE_INTERFACE = define_c_type({ 
     atom x = define_c_proc(all,"+fi_open",{C_STRING,C_STRING}) 
 
    public procedure fi_open(sequence path,sequence mode) 
      c_proc(x,{path,mode}) 
    end procedure 
}) 
new topic     » topic index » view message » categorize

2. Re: Wrapping Functions Inside of Struct?

I could be wrong, but from what I can see, if you're not using al_fopen() then you don't need ALLEGRO_FILE_INTERFACE.
If you have a working example using al_fopen() that does not use al_set_new_file_interface() then you don't need "".
Should you actually need it, then al_set_new_file_interface() just needs a (carefully ordered) bank of 13 call_backs().
There would be very little benefit, and perhaps possibility for misuse, for your app itself to know about any function
names/args/return types, that is, after they've been put into, or in getting back out of, such a simple flat array.

HTH, Pete

new topic     » goto parent     » topic index » view message » categorize

3. Re: Wrapping Functions Inside of Struct?

Icy_Viking said...

I'm just wondering if there's a way to wrap functions that are in a struct or is there some other work-a-round?

petelomax said...

I could be wrong, but from what I can see, if you're not using al_fopen() then you don't need ALLEGRO_FILE_INTERFACE.
If you have a working example using al_fopen() that does not use al_set_new_file_interface() then you don't need "".
Should you actually need it, then al_set_new_file_interface() just needs a (carefully ordered) bank of 13 call_backs().
There would be very little benefit, and perhaps possibility for misuse, for your app itself to know about any function
names/args/return types, that is, after they've been put into, or in getting back out of, such a simple flat array.

Pete's right; these are just callbacks for creating a custom file interface. It's possible you might want to do this if, for example, you wanted to store your resources in a single archive and access each entry using the Allegro file functions.

The AL_METHOD macro is defined in internal/alconfig.h

#define AL_METHOD(type, name, args) type (*name) args 

So an entry like this:

AL_METHOD(void *, fi_fopen, (const char *path, const char *mode)); 

Just gets translated to this:

void *(*fi_fopen)(const char *path, const char *mode); 

Which is just a function pointer.

So your structure definition would look like this:

export constant AL_ALLEGRO_FILE_INTERFACE = define_c_type({ 
    C_POINTER, -- void *(*fi_fopen)(const char *path, const char *mode); 
    C_POINTER, -- bool (*fi_fclose)(ALLEGRO_FILE *handle); 
    C_POINTER, -- size_t (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size); 
    C_POINTER, -- size_t (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size); 
    C_POINTER, -- bool (*fi_fflush)(ALLEGRO_FILE *f); 
    C_POINTER, -- int64_t (*fi_ftell)(ALLEGRO_FILE *f); 
    C_POINTER, -- bool (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence); 
    C_POINTER, -- bool (*fi_feof)(ALLEGRO_FILE *f); 
    C_POINTER, -- int (*fi_ferror)(ALLEGRO_FILE *f); 
    C_POINTER, -- const char *(*fi_ferrmsg)(ALLEGRO_FILE *f); 
    C_POINTER, -- void (*fi_fclearerr)(ALLEGRO_FILE *f); 
    C_POINTER, -- int (*fi_fungetc)(ALLEGRO_FILE *f, int c); 
    C_POINTER  -- off_t (*fi_fsize)(ALLEGRO_FILE *f); 
}) 

And your custom interface implementation might look something like this:

function fi_fopen( sequence path, sequence mode ) 
    return 0 
end function 
 
function fi_fclose( atom handle ) 
    return 0 
end function 
 
function fi_fread( atom f, atom ptr, atom size ) 
    return 0 
end function 
 
function fi_fwrite( atom f, atom ptr, atom size ) 
    return 0 
end function 
 
function fi_fflush( atom f ) 
    return 0 
end function 
 
function fi_ftell( atom f ) 
    return 0 
end function 
 
function fi_fseek( atom f, atom offset, atom whence ) 
    return 0 
end function 
 
function fi_feof( atom f ) 
    return 0 
end function 
 
function fi_ferror( atom f ) 
    return 0 
end function 
 
function fi_ferrmsg( atom f ) 
    return 0 
end function 
 
function fi_fclearerr( atom f ) 
    return 0 
end function 
 
function fi_fungetc( atom f, integer c ) 
    return 0 
end function 
 
function fi_fsize( atom f ) 
    return 0 
end function 
 
constant C_OFF_T = C_LONG_PTR -- used by fi_fsize() 
 
constant MY_INTERFACE = allocate_struct( AL_ALLEGRO_FILE_INTERFACE, { 
    call_back( routine_id("fi_fopen"), {C_STRING,C_STRING}, C_POINTER ), 
    call_back( routine_id("fi_fclose"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_fread"), {C_POINTER,C_POINTER,C_SIZE_T}, C_SIZE_T ), 
    call_back( routine_id("fi_fwrite"), {C_POINTER,C_POINTER,C_SIZE_T}, C_SIZE_T ), 
    call_back( routine_id("fi_fflush"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_ftell"), {C_POINTER}, C_INT64 ), 
    call_back( routine_id("fi_fseek"), {C_POINTER,C_INT64,C_INT}, C_BOOL ), 
    call_back( routine_id("fi_feof"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_ferror"), {C_POINTER}, C_INT ), 
    call_back( routine_id("fi_ferrmsg"), {C_POINTER}, C_POINTER ), 
    call_back( routine_id("fi_fclearerr"), {C_POINTER}, C_VOID ), 
    call_back( routine_id("fi_fungetc"), {C_POINTER,C_INT}, C_INT ), 
    call_back( routine_id("fi_fsize"), {C_POINTER}, C_OFF_T ) 
}) 

And then you'd use it like this:

atom f = al_fopen_interface( MY_INTERFACE, "path/to/myfile.ext", "r" ) 
 
-- do file things here 
 
al_fclose( f ) 

-Greg

new topic     » goto parent     » topic index » view message » categorize

4. Re: Wrapping Functions Inside of Struct?

ghaberek said...
Icy_Viking said...

I'm just wondering if there's a way to wrap functions that are in a struct or is there some other work-a-round?

petelomax said...

I could be wrong, but from what I can see, if you're not using al_fopen() then you don't need ALLEGRO_FILE_INTERFACE.
If you have a working example using al_fopen() that does not use al_set_new_file_interface() then you don't need "".
Should you actually need it, then al_set_new_file_interface() just needs a (carefully ordered) bank of 13 call_backs().
There would be very little benefit, and perhaps possibility for misuse, for your app itself to know about any function
names/args/return types, that is, after they've been put into, or in getting back out of, such a simple flat array.

Pete's right; these are just callbacks for creating a custom file interface. It's possible you might want to do this if, for example, you wanted to store your resources in a single archive and access each entry using the Allegro file functions.

The AL_METHOD macro is defined in internal/alconfig.h

#define AL_METHOD(type, name, args) type (*name) args 

So an entry like this:

AL_METHOD(void *, fi_fopen, (const char *path, const char *mode)); 

Just gets translated to this:

void *(*fi_fopen)(const char *path, const char *mode); 

Which is just a function pointer.

So your structure definition would look like this:

export constant AL_ALLEGRO_FILE_INTERFACE = define_c_type({ 
    C_POINTER, -- void *(*fi_fopen)(const char *path, const char *mode); 
    C_POINTER, -- bool (*fi_fclose)(ALLEGRO_FILE *handle); 
    C_POINTER, -- size_t (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size); 
    C_POINTER, -- size_t (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size); 
    C_POINTER, -- bool (*fi_fflush)(ALLEGRO_FILE *f); 
    C_POINTER, -- int64_t (*fi_ftell)(ALLEGRO_FILE *f); 
    C_POINTER, -- bool (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence); 
    C_POINTER, -- bool (*fi_feof)(ALLEGRO_FILE *f); 
    C_POINTER, -- int (*fi_ferror)(ALLEGRO_FILE *f); 
    C_POINTER, -- const char *(*fi_ferrmsg)(ALLEGRO_FILE *f); 
    C_POINTER, -- void (*fi_fclearerr)(ALLEGRO_FILE *f); 
    C_POINTER, -- int (*fi_fungetc)(ALLEGRO_FILE *f, int c); 
    C_POINTER  -- off_t (*fi_fsize)(ALLEGRO_FILE *f); 
}) 

And your custom interface implementation might look something like this:

function fi_fopen( sequence path, sequence mode ) 
    return 0 
end function 
 
function fi_fclose( atom handle ) 
    return 0 
end function 
 
function fi_fread( atom f, atom ptr, atom size ) 
    return 0 
end function 
 
function fi_fwrite( atom f, atom ptr, atom size ) 
    return 0 
end function 
 
function fi_fflush( atom f ) 
    return 0 
end function 
 
function fi_ftell( atom f ) 
    return 0 
end function 
 
function fi_fseek( atom f, atom offset, atom whence ) 
    return 0 
end function 
 
function fi_feof( atom f ) 
    return 0 
end function 
 
function fi_ferror( atom f ) 
    return 0 
end function 
 
function fi_ferrmsg( atom f ) 
    return 0 
end function 
 
function fi_fclearerr( atom f ) 
    return 0 
end function 
 
function fi_fungetc( atom f, integer c ) 
    return 0 
end function 
 
function fi_fsize( atom f ) 
    return 0 
end function 
 
constant C_OFF_T = C_LONG_PTR -- used by fi_fsize() 
 
constant MY_INTERFACE = allocate_struct( AL_ALLEGRO_FILE_INTERFACE, { 
    call_back( routine_id("fi_fopen"), {C_STRING,C_STRING}, C_POINTER ), 
    call_back( routine_id("fi_fclose"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_fread"), {C_POINTER,C_POINTER,C_SIZE_T}, C_SIZE_T ), 
    call_back( routine_id("fi_fwrite"), {C_POINTER,C_POINTER,C_SIZE_T}, C_SIZE_T ), 
    call_back( routine_id("fi_fflush"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_ftell"), {C_POINTER}, C_INT64 ), 
    call_back( routine_id("fi_fseek"), {C_POINTER,C_INT64,C_INT}, C_BOOL ), 
    call_back( routine_id("fi_feof"), {C_POINTER}, C_BOOL ), 
    call_back( routine_id("fi_ferror"), {C_POINTER}, C_INT ), 
    call_back( routine_id("fi_ferrmsg"), {C_POINTER}, C_POINTER ), 
    call_back( routine_id("fi_fclearerr"), {C_POINTER}, C_VOID ), 
    call_back( routine_id("fi_fungetc"), {C_POINTER,C_INT}, C_INT ), 
    call_back( routine_id("fi_fsize"), {C_POINTER}, C_OFF_T ) 
}) 

And then you'd use it like this:

atom f = al_fopen_interface( MY_INTERFACE, "path/to/myfile.ext", "r" ) 
 
-- do file things here 
 
al_fclose( f ) 

-Greg

Thanks Greg, that makes a lot of sense. It was simpler then I had previously thought.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu