[ mehanizamm @ 03.06.2019. 10:53 ] @
Kako da pozovem i izvršim funkciju kojoj je naziv snimljen u stringu?

U četiri unita imam oko 200 funkcija.
Nazive tih funkcija sam izvuko i snimio u MySQL tabeli. Zatim ih prikažem u tabeli i pored svake postoji CheckBox.
Izaberem desetak i na ButtonClick bi trebalo jednu po jednu od tih izabranih funkcija da poziva i izvrsava.

[ Branimir Maksimovic @ 03.06.2019. 12:38 ] @
Kod kompajliranih jezika napravis mapu gde je kljuc ime f-je a vrednost pokazivac na f-ju.
Ne znam koja je struktura to u delfiju, nesto kao asocijativni niz.
[ Rapaic Rajko @ 05.06.2019. 11:17 ] @
Postoji vrlo lepo resenje koriscenjem tekovina OOP-a, zametno ga je objasniti bez primera u kodu.
Za gotov primer, daj malo vise informacija:

1) Da li su sve funkcije istog tipa?
2) Imaju li parametre, ako da, koje i koliko?
3) Ako imaju parametre, gde ih drzis, u bazi? // ovo je i nebitno za primer, to da razmislis kako ces ih proslediti kad ti napravim primer

Pozz (cekamo...)
[ Branimir Maksimovic @ 05.06.2019. 11:25 ] @
Ako f-je imaju parametre onda se napravi serijalizacija u strukture koje delegiraju parametre.
[ Almedin @ 05.06.2019. 12:51 ] @
Procedure staviti u clasu TMyClass i onda nešto ovako
Code:

procedure execMethod(AMethod: string);
var
  t: TRttiType;
  m : TRttiMethod;
  MyClass : TMyClass;
begin
  MyClass := TMyClass.Create;
  t := RttiContext.GetType(MyClass);
  m := t.GetMethod(AMethod);
  m.Invoke(MyClass, []);
  MyClass.Free;
end; 
[ mehanizamm @ 06.06.2019. 20:42 ] @
Citat:
Rapaic Rajko:
Postoji vrlo lepo resenje koriscenjem tekovina OOP-a, zametno ga je objasniti bez primera u kodu.
Za gotov primer, daj malo vise informacija:

1) Da li su sve funkcije istog tipa?
2) Imaju li parametre, ako da, koje i koliko?
3) Ako imaju parametre, gde ih drzis, u bazi? // ovo je i nebitno za primer, to da razmislis kako ces ih proslediti kad ti napravim primer :)

Pozz (cekamo...)


Funkcije su istog tipastring.
Nemaju parametre.
[ mehanizamm @ 06.06.2019. 21:14 ] @
Citat:
Almedin:
Procedure staviti u clasu TMyClass i onda nešto ovako
Code:

procedure execMethod(AMethod: string);
var
  t: TRttiType;
  m : TRttiMethod;
  MyClass : TMyClass;
begin
  MyClass := TMyClass.Create;
  t := RttiContext.GetType(MyClass);
  m := t.GetMethod(AMethod);
  m.Invoke(MyClass, []);
  MyClass.Free;
end; 


Korstim Lazarus 2.0.0, koje pakete da instaliram da bi imao rtti?
[ savkic @ 06.06.2019. 22:19 ] @
> Korstim Lazarus 2.0.0, koje pakete da instaliram da bi imao rtti?

FPC ima limitiranu RTTI podrsku u odnosu na Delphi, ne znam da li je to moguce sa njim. Mislim da ti je najlakse da rucno napravis record array sa nazivom funkcije i pointerom na nju i jednu invoku metodu kojoj prosledis naziv funkcije, ona pretrazi taj array i pozove pointer na funkciju.
[ Rapaic Rajko @ 07.06.2019. 11:37 ] @
Citat:
mehanizamm:
Citat:
Rapaic Rajko:
Postoji vrlo lepo resenje koriscenjem tekovina OOP-a, zametno ga je objasniti bez primera u kodu.
Za gotov primer, daj malo vise informacija:

1) Da li su sve funkcije istog tipa?
2) Imaju li parametre, ako da, koje i koliko?
3) Ako imaju parametre, gde ih drzis, u bazi? // ovo je i nebitno za primer, to da razmislis kako ces ih proslediti kad ti napravim primer :)

Pozz (cekamo...)


Funkcije su istog tipastring.
Nemaju parametre.


A Lazarus je u pitanju, znaci?
Bez obzira, mislim da ce raditi.
Evo celog unit-a, prodiskutovacu ispod:

Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TClassMethodStringType = function: string of object;

  TForm1 = class(TForm)
    btnClassMethod: TButton;
    btnInvokeClassMethod: TButton;
    procedure btnClassMethodClick(Sender: TObject);
    procedure btnInvokeClassMethodClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  published
    class function ClassFuncString: string;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

class function TForm1.ClassFuncString: string;
begin
  ShowMessage('ClassFuncString called');
end;

procedure TForm1.btnClassMethodClick(Sender: TObject);
begin
  TForm1.ClassFuncString;
end;

procedure TForm1.btnInvokeClassMethodClick(Sender: TObject);
var
  aMethod: TMethod;
begin
  aMethod.Data := nil; // jer je class metoda, nema self
  aMethod.Code := TForm1.MethodAddress('ClassFuncString');
  TClassMethodStringType(aMethod);
end;

end.



Za gornji primer ti treba mala formica sa 2 button-a (kao sto vidis u kodu), svaki ima svoj event.
Prvi button poziva class metodu direktno, drugi button prvo pronalazi/locira class metodu, pa je zatim poziva.

Dakle, sta treba da uradis?
1) u svakom od pomenuta 4 unit-a deklarisati klasu, i u nju prebaciti pomenute funkcije kao PUBLISHED (obavezno!) metode.
To zato sto metoda MethodAdress (takodje class metoda, pogledaj kako sam je pozvao - TForm1.MethodAdress, a NE Form1.MethodAdress) locira SAMO published metode.
2) kao sto se vidi, izabrao sam da metode budu class metode (nevezane za instancu/objekat, sto znaci da se ne mora kreirati objekat da bi se iste pozvale)
3) posto smo uradili kao pod 2), aMethod.Data se u kodu postavlja na nil (nema instance i ne treba za class metodu).
4) obrati paznju na typecast

Code:

  TClassMethodStringType(aMethod);


zato sam te pitao za tip funkcije. Bez te linije, ne mozemo nista s TMethod record-om, jednostavno ne bi znali kako da ga izvrsimo/pozovemo.
To je sve. Slozices se da bi bez ovog primera bas bilo tesko objasniti (samo recima) kako sve funkcionise.
Fantasticna tekovina OOP-a, zar ne ;)

Pozz :)