(mod_pointerfunc) invocar funciones de bennu con string y lista de parámetros

Started by Prg, November 27, 2011, 07:21:31 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Prg

Esta librería presenta una alternativa a los punteros a funciones.
Yo la uso para enviar una cadena y graficar de acuerdo a la función que se indica en la cadena.

Comparto la librería y algunos ejemplos

Quoteimport "mod_pointerfunc";
import "mod_say";
import "mod_string";
private
float f=2.5;
begin
     /*
       Las funciones se llaman ejecutaX donde X es la letra del tipo de dato que retornan. X puede ser F-Flotante,
       I-Entero, S-Cadena, P-Puntero. Reciben el nombre de la función como primer parámetro, seguido del número de parámetros (Max 3) y la lista de parámetros,
       todos del mismo tipo y pueden ser int, float, string o pointer.

       Existe otra función llamada ejecutaMX donde X es la letra del tipo de dato que retornan. X puede ser F-Flotante,
       I-Entero, S-Cadena, P-Puntero.
              Esta función recibe como primer parámetro la cadena con el nombre de la función a invocar.
              Como segundo parámetro reciben una cadena con los tipos de datos de los parámetros (no hay límite en la cantidad de parámetros y los tipos se pueden mezclar), se usa  F-Flotante,
                 I-Entero, S-Cadena, P-Puntero. Todos los caracteres deben ir seguidos sin ningún espacio o algún otro caracter entre ellos, ejemplo:
                 "III" --tres enteros como parámetros
                 "SPF" --cadena, puntero y flotante como parámetros
              Como tercer parámetro tenemos una lista con los parámetros, separados todos con 1 espacio. Las cadenas van entre comilla simple (caracter 39 en ascii), y deben cerrarse. Ejemplos:
                 "12 13 12.2" --entero, entero y flotante
                 "'hola'"     --cadena
                 ""+(&variable)+" 'doce'" --puntero y cadena

     */

     //Ejecuta una función que retorna un flotante y recibe un puntero
     say("ejemploFp");
     say(Ejecutaf("ejemploFp",1,&f));   //nombre de función, cantidad de parámetros de tipo puntero (hasta 3, todos tienen que ser punteros) y la lista de parámetros
     say("");
     //Ejecuta una función que retorna un flotante y recibe un flotante
     say("ejemploF");
     say(Ejecutaf("ejemploF",1,12.3));   //nombre de función, cantidad de parámetros de tipo flotante (hasta 3, todos tienen que ser flotantes) y la lista de parámetros
     say("");
     //Ejecuta una función que retorna un entero y recibe 2 enteros
     say("ejemploI");
     say(EjecutaI("ejemploI",2,23,232)); //nombre de función, cantidad de parámetros de tipo entero (hasta 3, todos tienen que ser enteros) y la lista de parámetros
     say("");
     //Ejecuta una función que retorna una cadena y recibe una cadena
     say("ejemploS");
     say(EjecutaS("ejemplos",1,"hola")); //nombre de función, cantidad de parámetros de tipo cadena (hasta 3, todos tienen que ser cadenas) y la lista de parámetros
     say("");
     //Ejecuta una función que recibe un entero, flotante, cadena y puntero y retorna un entero
     say("ejemploIFSP");
     say(EjecutaMI("ejemploIFSP","IFSP","23 22.3 'hola como estas en este día' "+(&f))); //nombre de la función, cadena con la lista de tipos de parámetros (I-Entero, P-Puntero, F-Flotante, S-Cadena. No existe límite en la cantidad de parámetros y no puede haber otro caracter distinto a los anteriores), cadena con los parámetros separados por espacios. El número de la cadena de tipos y de la cadena con los parámetros debe coincidir, de lo contario la invocación fallará.
     say("");
     //Ejecuta una función que recibe una cadena y un flotante y retorn aun flotante
     say("ejemploSF");
     say(EjecutaMF("ejemploSF","SF","     '     hola'       2.3     ")); //nombre de la función, cadena con la lista de tipos de parámetros (I-Entero, P-Puntero, F-Flotante, S-Cadena. No existe límite en la cantidad de parámetros y no puede haber otro caracter distinto a los anteriores), cadena con los parámetros separados por espacios. El número de la cadena de tipos y de la cadena con los parámetros debe coincidir, de lo contario la invocación fallará.
end


function float ejemploFp(float *r)
begin
say(*r);
return 3.3;
end

function float ejemploF(float r)
begin
say(r);
return 3.3;
end

function int ejemploI(int r,int d)
begin
say(r);
say(d);
return 3;
end

function int ejemploIFSP(int r,float f, string s, float* p)
begin
say(r);
say(f);
say(s);
say(p);
say(*p);
return 3;
end

function float ejemploSF( string s,float f)
begin
say(s);
say(f);
return 3.3;
end

function string ejemplos(string r)
begin
say(r);
return "Yo retorno esta cadena más mi parámetro: "+r;
end


otro ejemplo
Quotegraph=new_map(500,300,32);
             set_text_color( 0ff00ff00h );
             grafica(0,graph,15,0ffff0000h,30,0.5,"cosf");

Quote
function float sinf(float f)
begin
return sin(f);
end

function float cosf(float f)
begin
return cos(f);
end

function float tanf(float f)
begin
return tan(f);
end

//Proceso modificado a partir de ejemplo de la wiki
Process grafica(file,grafico,screen_border,color,vel,float avance,string func)
private
gAux,screen_width,screen_height,cantText;
float value,fangle;
Begin
screen_width=graphic_info(file,grafico,g_width);
screen_height=graphic_info(file,grafico,g_height);
drawing_map(file,grafico);
cantText=(screen_width-screen_border)/text_width ( 0 , "300300" ) ;
    for(x=1;x<=cantText;x++)
        gAux=write_in_map( 0, itoa(x*360/cantText )+"^", 8);
         map_xputnp(file,grafico,0,gAux,screen_border+x*(screen_width-screen_border)/cantText+3,screen_height-1,0,100,100,0);
         unload_map(0,gAux);
    end
    draw_line(1,screen_height-screen_border,screen_width,screen_height-screen_border);


    draw_line(screen_border,1,screen_border,screen_height-1);


    for(fangle=0;fangle<360;fangle+=avance)
        value=Ejecutaf(func,1,fangle*1000)*(screen_height/2-20);
        map_put_pixel(file,grafico, screen_border+fangle*(screen_width-screen_border)/360,
                   screen_height/2-value,
                   color );
        frame(vel);
    end

    Repeat
        frame;
    Until(key(_ESC))

End
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Prg

en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

SplinterGU

voy a ir pensando de que forma implementar un mecanismo de punteros a funcion nativos... y al estilo C... tengo que ver si me quedan opcodes (o mascaras mejor dicho de opcodes) disponibles para hacerlo.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Quote from: SplinterGU on November 28, 2011, 04:23:33 AM
voy a ir pensando de que forma implementar un mecanismo de punteros a funcion nativos... y al estilo C... tengo que ver si me quedan opcodes (o mascaras mejor dicho de opcodes) disponibles para hacerlo.
¡Eso sería estupendo!
Y karma, Prg, por la lib.

gecko

Torres Baldi Studio
http://torresbaldi.com

SplinterGU

Quote from: gecko on November 28, 2011, 04:29:12 AM
perdon por la ignorancia, pero... todo esto para que sirve?

(punteros a funcion) es un poco complejo explicarlo, o mas bien, no se me ocurre como explicarlo, pero pensa en un unico codigo donde cierta parte de la logica esta depende de otra funcion y esta otra funcion la pasas por parametro...

por ejemplo...

funcion int calcula( process * tip_funcion, int param1, int param2 )
begin
  return tip_function(param1, param2);
end

luego tenes, funciones

suma(int param1, param2)
resta(int param1, param2)
mul(int param1, param2)
div(int param1, param2)

y luego podes llamarlas de la siguiente forma

calcula(suma, 10, 20)

calcula(div, 20, 2)

lo que haran estas 2 instrucciones es llamar a suma(10,20) y a div(20,2)

esto te permite flexibilidad y poder hacer algo tambien muy configurable y te evitas tener que tener codigos switch o if, para llamar a una cosa u otra.

lo
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Permitiría también cosas como configurar niveles en juegos símplemente guardando las funciones a las que se llama.
Defines un array cuyos elementos serían:

prota, x0, y0, t0
enemigo1, x1, y1, t1
enemigo2, x2, y2, t2
...

Y entonces otra función se encargaría de ir llamando a cada una de las funciones del array en la posición en la que vengan definidos cuando llegue su tiempo de activación. De esa forma, cada nivel se podría definir casi casi con definir un único array, no más código repetitivo.

Cosas así.

l1nk3rn3l

esto es lo que necesitamos para la futura IA , usando maquina de estados
y solo llamando procesos especificos como lo hace un motor como unreal ..


joder esto es muy util..  para muchas cosas..

gecko

Si, de verdad que parece muy util. Gracias por las explicaciones! (Y)

Creo que voy a probar esta libreria :)
Torres Baldi Studio
http://torresbaldi.com

Prg

En la librería Chipmunk, por ejemplo, se puede llamar una función al detectar una colisión, antes de procesarla, mientras se procesa y después de procesarla. A la función se le pasa información  de la colisión (para conocer cuando dos objetos se tocan, la normal de colisión y con cúanta fuerza) y el retorno de la función influye en la forma en que la colisión se procesa.

La función que se llamará desde la otra se define por un puntero a función, de tal forma que puedes tener varias funciones que se llamarán de acuerdo a ciertos datos, de esta forma personalizas muchísimo la forma en que un código de 3ros actúa sin necesidad de modicarlo directamente.

Este es otro ejemplo.
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)