Lancer une procedure enregistre en variable

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Lancer une procedure enregistre en variable

Message par ChaudEf »

Bonsoir
est il possible de faire un truc pareil?

Code : Tout sélectionner

procedure mafunc()
 debug "ok"
endprocedure

a.s = "mafunc"
launchprocedure(a)
Merci beaucoup
Windows 10 x64 -- Purebasic 5.70 LTS x86
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ollivier »

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")
Note :
  • c'est insensible à la casse donc pas de confusion possible
  • Ici, c'est limité à 2 arguments facultatifs mais on peut augmenter le nombre d'arguments facultatifs si besoin
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ar-S »

@ChaudEf
Comme tu l'as écrit non, ça ne veut pas dire grand chose ou il manque des éléments.
Ce que tu as écrit signifie

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)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ollivier »

On vire des guillemets en dernière ligne,
on envoie le bug en bug report sur le forum officiel
http://www.purebasic.fr/english/viewtop ... =4&t=68686


Ça te plaît maintenant ?

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)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ollivier »

Zut... Les guillemets c'était pas là qu'il fallait que je les saute... Corrigé.

@ChaudEf

C'est bon comme ç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(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")
Avatar de l’utilisateur
Zorro
Messages : 2186
Inscription : mar. 31/mai/2016 9:06

Re: Lancer une procedure enregistre en variable

Message par Zorro »

ouaip, yen a qui code comme il parle !!!


on comprends rien ! :roll: :lol:


voici ce que tu Peux faire :

il te faut une procedure qui sert de lanceur de procedure en fonction d'une chaine de caractere

ben voila comment faire :

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
c'etait tout con hein ?? :lol:
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Lancer une procedure enregistre en variable

Message par G-Rom »

ChaudEf a écrit :Bonsoir
est il possible de faire un truc pareil?

Code : Tout sélectionner

procedure mafunc()
 debug "ok"
endprocedure

a.s = "mafunc"
launchprocedure(a)
Merci beaucoup
Oui, cela s'appelle de la reflection, tu peu utilisé une Map & un pointeur pour cela , exemple tout simple :

Code : Tout sélectionner

Procedure foo()
  Debug "foo"
EndProcedure


NewMap *FuncPtr()
*FuncPtr("foo") = @foo()


CallCFunctionFast(*FuncPtr("foo"))
Demivec
Messages : 91
Inscription : sam. 18/sept./2010 18:13

Re: Lancer une procedure enregistre en variable

Message par Demivec »

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)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ollivier »

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)
J'avoue que ChaudEf n'exige pas d'avoir, à la volée, une liste des noms, de ses fonctions.

Dans ce cas, ta suggestion est très bien trouvée.

Et, dans le cas général, ça reste aussi un très bon exemple complet d'utilisation de la librairie native RunTime. Merci pour cette info.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Lancer une procedure enregistre en variable

Message par Kwai chang caine »

Alors là bravo DEMIVEC
Tous ces exemples sont super intéressants, mais alors le tiens est carrément époustouflant.
J'ai même cru que c'était pas du PB 8O
Runtime...jamais entendu parler ... :oops:
Merci beaucoup pour ce code 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Lancer une procedure enregistre en variable

Message par JohnJohnsonSHERMAN »

Merci Demivec ! :) J'avais déjà fait ca mais sans les prototypes, donc c'était plus sale... Je ne savais pas qu'on pouvait s'en servir dans ce cas :P

@KCC, c'est pas bien ca... T'as pas lu la Sainte Doc en entier?? :o :lol:
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Lancer une procedure enregistre en variable

Message par Kwai chang caine »

T'as raison, je lis déjà pas les doc d'aspirateur, alors une aussi grosse doc ... :oops:
C'est d'autant plus, "trop pas" (d'jeuns inside :mrgreen: ) cool, car comme on le sait tous, il faut autant de temps pour faire une bonne doc que le programme lui même :|
J'espère que notre seigneur me pardonnera :cry:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Ormente
Messages : 27
Inscription : sam. 19/août/2017 23:41
Localisation : Mâcon, bientôt La Plagne
Contact :

Re: Lancer une procedure enregistre en variable

Message par Ormente »

Bonjour les gens.
Je suis un petit nouveau ici : j'ai une License PB depuis des lustres mais n'avais quasiment jamais programmé avec. Je suis en train d'essayer un peu, et j'avais justement voulu faire le même genre de choses.
Voici ce à quoi j'étais arrivé :
(désolé j'ai l'habitude de commenter en langue des coins, mais si c'est un soucis je peux traduire)

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
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Lancer une procedure enregistre en variable

Message par djes »

Bienvenue Ormente ! :)
C'est bien, tu débutes en PB mais tu sembles maîtriser les pointeurs ; je pense que tu vas facilement faire d'excellents codes !

Celui-ci est un excellent exemple, c'est très peu utilisé en BASIC, et pourtant comme tu l'as bien démontré, ça permet de gagner de la vitesse. C'est le genre de chose qui pourrait être prise en charge et repérée par l'éditeur/compilateur, en surlignant ces sortes de "surcharge d'opérateurs", et en renvoyant vers la définition. Ainsi on améliore le langage, mais on garde la lisibilité du BASIC.
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Lancer une procedure enregistre en variable

Message par JohnJohnsonSHERMAN »

Bienvenue à toi Ormente :)

Exellente astuce ! Je n'y avais pas pensé, c'est trés pratique dans ces cas où plusieurs fonctions avec les mêmes prototypes doivent être choisies (if ou select), merci de l'astuce :)

<HS> Ca n'a rien à voir, mais suis-je le seul à rêver de surcharge d'opérateurs / de procédures en PB? :o </HS>
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Répondre