Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour
La question bête du jour:
Version pb: 12.5.2
Dans mon application j'ai un objet n_global instancié en variable globale gnv_global
cet objet contient mes quelques "variables" globales de l'application par exemple gnv_global.repertoire_temp
Il contient aussi mes "objets globaux pour l'application" par exemple gnv_global.utilisateur gnv_global.parametres etc... (ces objets ont évidemment leurs propres attributs et méthodes)
Il contient aussi des fonctions de base par exemple gnv_global.of_chaine_dans_tableau(...) gnv_global.of_is_safe(...)
Je ne saurai dire si c'est bien conçu ou non mais là n'est pas la question.
Ca marche nickel dans le code courant mais pas dans les datawindow (dans les computes)
PB n'accepte pas que je référence mon gnv_global dedans.
Pour palier à la chose je me suis fait deux fonctions globales une pour récupérer les attributs de mes objets et l'autre pour appeler les méthodes
Merci Seki pour le PBNICW qui m'est très utile pour ça
Ca c'est la fonction pour récupérer les attributs ça marche impec (le seultruc qui "m'embête" c'est que je ne peux pas retourner un any... mais bon pas grave
any lany_ret PowerObject lpo_obj long ll_pos string ls_obj ll_pos = pos(as_obj,'.') if ll_pos > 0 then ls_obj = mid(as_obj,ll_pos + 1) lpo_obj = CWGetField(gnv_global,ls_obj) else lpo_obj = gnv_global end if lany_ret = CWGetField(lpo_obj,as_var) return(string(lany_ret))
Pour les appels de méthodes j'ai utilisé le même principe mais avec un call_dynamic à la place du dernier CWGetField
global function string f_unit_call_global (string as_obj, string as_method);any lany_ret PowerObject lpo_obj long ll_pos string ls_obj ll_pos = pos(as_obj,'.') if ll_pos > 0 then ls_obj = mid(as_obj,ll_pos + 1) lpo_obj = CWGetField(gnv_global,ls_obj) else lpo_obj = gnv_global end if lany_ret = call_dynamic(lpo_obj,as_method) return(string(lany_ret)) end function
Mon problème est ici: les arguments des méthodes
Je ne peux/veux pas m'amuser à surcharger ma fonction globale avec toutes les combinaisons possibles de types et nombres d'arguments
Pour le moment je l'ai fait pour un paramètre long et un paramètre string mais bon... et puis je déteste dupliquer mon code de partout...
Je ne peux pas faire directement un call_dynamic sur gnv_global dans le compute (c'est dommage)
Si vous pensez à une solution miracle je suis preneur.
Même si cette solution demande de modifier légèrement les fastfuncs (bon là c'est pas gagné).
L'idéal serait d'avoir un autre call_dynamic et de pouvoir passer le nom de l'objet en string
il faudrait donc remplacer si possible dans le code des fastfuncs
value * arguments = GET_EVALEDARGLIST( vm ); pb_object * objInst = (pb_object*) arguments[0].value;
par du code qui récupérerait l'objet instancié à partir de son nom comme ce qui est fait dans le CWGetField
Votre avis sur la question ?
Hors ligne
Il serait possible d'écrire un call_dynamic_vargs( powerobject obj, string method, any arguments[] ) dans les fastfuncs ou pbnicw.
Hors ligne
oui mais ça n'arrange pas mon affaire
c'est pour utiliser dans les compute de datawindow
donc (sauf erreur de ma part) pas possible de construire le tableau
et pas possible de mettre mon gnv_global en premier argument
après le besoin n'est pas immense et on s'en sortira sûrement très bien avec un appel avec un long, un string et deux string mais c'est mon côté générique/universel qui a envie d'avoir un truc qui couvre le plus de cas possible ;)
Hors ligne
ha, dans ce cas il te faudrait quelque chose comme :
eval("$gnv_global->i_objet1->f_toto('une chaine', true, -42)")
C'est envisageable avec embeddingperl (full), mais pas sure que çà soit très performant vu que c'est dans une dwexpression / sur un compute il risque d'y avoir des appels très frequents.
Hors ligne
j'ose espérer que l'on m'a demandé ça juste pour remplir des entêtes d'édition et pas mettre dans le detail de grosse datawindow ce qui rendrai le manque de performance acceptable.
Mais vu le passif de certains dev chez nous j'ai des doutes
Hors ligne
Et pourquoi ne pas inverser le problème ?
C'est-à-dire ne pas faire appel à une fonction globale au sein d'un computed field (CF), mais utiliser un computed column (CC) bidon qui le remplace, puis au moment opportun (retrieveend, itemchanged) faire appel à une méthode dédiée qui elle fera appels aux fonctionnalités déjà existantes afin de mettre à jours les CC bidons concernés en fonction du contexte (tous en cas de retrievend et dans le cas d'un itemchanged, uniquement ceux concernés).
Cette méthode pourra éventuellement utiliser la dot notation afin d'optimiser les performances lors de la mises à jours des CC.
D'après mon expérience, ce genre d'approche améliore les performances globales qui sont fortement dégradées lors d'appels de fonctions globales en générale, et particulièrement à partir d'un CF au sein d'un datawindow car répété continuellement à la fréquence définie par sa propriété refresh.
Hors ligne