est il possible de faire un truc pareil?
Code : Tout sélectionner
procedure mafunc()
debug "ok"
endprocedure
a.s = "mafunc"
launchprocedure(a)
Code : Tout sélectionner
procedure mafunc()
debug "ok"
endprocedure
a.s = "mafunc"
launchprocedure(a)
Code : Tout sélectionner
;{
Macro Quote:"
EndMacro
Macro FuncDef(x):Func(UCase(Quote#x#Quote) ) = @x()
EndMacro
Global NewMap Func()
Macro FuncCall(Name, Arg1 =, Arg2 =)
CompilerIf Quote#Arg1#Quote = ""
CallFunctionFast(Func(UCase(Quote#Name#Quote) ) )
CompilerElse
CompilerIf Quote#Arg2#Quote = ""
CallFunctionFast(Func(UCase(Quote#Name#Quote) ), Arg1)
CompilerElse
CallFunctionFast(Func(UCase(Quote#Name#Quote) ), Arg1, Arg2)
CompilerEndIf
CompilerEndIf
EndMacro
;}
Procedure Test()
MessageRequester("", "")
EndProcedure
FuncDef(Test)
FuncCall("Test")
Code : Tout sélectionner
;Tu crées une procédure mafunc() qui debug un simple "ok"
procedure mafunc()
debug "ok"
endprocedure
; Tu crées une variable texte a.s qui se nomme "mafunc" mais elle n'a aucun rapport avec la proce mafunc() plus haute
a.s = "mafunc"
; Tu lances une procedure launchprocedure(a) qui n'existe pas... En supposant que le (a) représente le a.s plus haut, tu n'as pas le bon type.
launchprocedure(a)
Code : Tout sélectionner
;{
Macro Quote:"
EndMacro
Macro FuncDef(x)
Func(UCase(Quote#x#Quote) ) = @x()
EndMacro
Global NewMap Func()
Macro FuncCall(Name, Arg1 =, Arg2 =)
CompilerIf Quote#Arg1#Quote = ""
CallFunctionFast(Func(UCase(Quote#Name#Quote) ) )
CompilerElse
CompilerIf Quote#Arg2#Quote = ""
CallFunctionFast(Func(UCase(Quote#Name#Quote) ),
Arg1)
CompilerElse
CallFunctionFast(Func(UCase(Quote#Name#Quote) ),
Arg1, Arg2)
CompilerEndIf
CompilerEndIf
EndMacro
;}
Procedure Test()
MessageRequester("", "")
EndProcedure
FuncDef(Test)
FuncCall(Test)
Code : Tout sélectionner
;{
Macro Quote:"
EndMacro
Macro FuncDef(x)
Func(UCase(Quote#x#Quote) ) = @x()
EndMacro
Global NewMap Func()
Macro FuncCall(Name, Arg1 =, Arg2 =)
CompilerIf Quote#Arg1#Quote = ""
CallFunctionFast(Func(UCase(Name) ) )
CompilerElse
CompilerIf Quote#Arg2#Quote = ""
CallFunctionFast(Func(UCase(Name) ),
Arg1)
CompilerElse
CallFunctionFast(Func(UCase(Name) ),
Arg1, Arg2)
CompilerEndIf
CompilerEndIf
EndMacro
;}
Procedure Test()
MessageRequester("", "")
EndProcedure
FuncDef(Test)
FuncCall("Test")
Code : Tout sélectionner
Declare mafunc()
Declare lanceur_de_proc(a.s)
calldebugger
; on fourni le nom de la procedure1 qu'on veux lancer au lanceur de procedure
a.s = "mafunc1"
lanceur_de_proc(a.s)
; on fourni le nom de la procedure2 qu'on veux lancer au lanceur de procedure
a.s = "mafunc2"
lanceur_de_proc(a.s)
; Procedure 1 qui sera lancé par le lanceur de procedure
procedure mafunc1()
debug "ok1"
endprocedure
; Procedure 2 qui sera lancé par le lanceur de procedure
procedure mafunc2()
debug "ok2"
endprocedure
Procedure lanceur_de_proc(a.s)
; le lanceur de procedure ..
; il lance une procedure en fonction de la chaine de caractere qui sert ici de commande de lancement
Select a.s
Case "mafunc1"
mafunc1()
Case "mafunc2"
mafunc2()
EndSelect
EndProcedure
Oui, cela s'appelle de la reflection, tu peu utilisé une Map & un pointeur pour cela , exemple tout simple :ChaudEf a écrit :Bonsoir
est il possible de faire un truc pareil?
Merci beaucoupCode : Tout sélectionner
procedure mafunc() debug "ok" endprocedure a.s = "mafunc" launchprocedure(a)
Code : Tout sélectionner
Procedure foo()
Debug "foo"
EndProcedure
NewMap *FuncPtr()
*FuncPtr("foo") = @foo()
CallCFunctionFast(*FuncPtr("foo"))
Code : Tout sélectionner
Prototype rProcedure_Params_0()
Runtime Procedure mafunc()
Debug "ok"
EndProcedure
Procedure launchprocedure(a.s)
Protected procName.rProcedure_Params_0 = GetRuntimeInteger(a + "()")
procName()
EndProcedure
a.s = "mafunc"
launchprocedure(a)
J'avoue que ChaudEf n'exige pas d'avoir, à la volée, une liste des noms, de ses fonctions.Demivec a écrit :Code : Tout sélectionner
Prototype rProcedure_Params_0() Runtime Procedure mafunc() Debug "ok" EndProcedure Procedure launchprocedure(a.s) Protected procName.rProcedure_Params_0 = GetRuntimeInteger(a + "()") procName() EndProcedure a.s = "mafunc" launchprocedure(a)
Code : Tout sélectionner
OpenConsole()
#ITERS = 100000000
x = 12
y = 13
; Declare the signature of a function
Prototype.i bifunc(a.i, b.i)
; Function 1 compatible with the prototype
Procedure.i add(x.i, y.i)
ProcedureReturn x+y
EndProcedure
; Function 2 compatible with the prototype
Procedure.i mul(x.i, y.i)
ProcedureReturn x*y
EndProcedure
; the "trick" to test: function pointer call
; Does it work? YES!
*fun.bifunc = @add()
PrintN(Str(*fun(x,y)))
*fun.bifunc = @mul()
PrintN(Str(*fun(x,y)))
; Why the trick ? Because instead of repeating the same
; test in a loop i want To test beforehand and use the
; right procedure "directly". So instead of doing this:
PrintN("Loop with test:")
t = ElapsedMilliseconds()
For i = 1 To #ITERS
If x=12 : add(x,y) : Else : mul(x,y) : EndIf
Next
PrintN(Str(ElapsedMilliseconds() - t) + "ms")
; I would be doing this:
PrintN("Loop using the trick:")
t = ElapsedMilliseconds()
If x=12 : *fun = @add() : Else : *fun = @mul() : EndIf
For i = 1 To #ITERS
*fun(x,y)
Next
PrintN(Str(ElapsedMilliseconds() - t) + "ms")
; For the sake of comparison, the simple equivalent loop:
PrintN("Simple normal loop:")
t = ElapsedMilliseconds()
For i = 1 To #ITERS
add(x,y)
Next
PrintN(Str(ElapsedMilliseconds() - t) + "ms")
; Typical result (console exe, no debug, #ITERS = 100000000) :
;-------------------------------------------------------------
; Loop With test:
; 568ms
; Loop using the trick:
; 428ms
; Simple normal loop:
; 423ms