PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Rund um die LCL und andere Komponenten
Antworten
Johasch
Beiträge: 10
Registriert: Sa 8. Feb 2020, 10:50

PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von Johasch »

Hallo,
Ich möchte in meinen Programm Pascal Script verwenden um Zeichenaufgaben automatisch zu erledigen.
Dazu habe ich unter anderem einige eigenen Typdefinitionen in einer Unit angelegt:

Code: Alles auswählen

unit ChartRoutines;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Graphics, Math,
  TAChartUtils;

const
  coArrKind = 0;
  coArrRel  = 1;
  coArrLen  = 2;
  coArrAng  = 3;
  coArrMid  = 4;

type
  TmyPenStyle   = (_psSolid, _psDash, _psDot, _psDashDot, _psDashDotDot,
                   _psPattern, _psClear, _psDefault, _psSkip);
type
  TmyBrushStyle = (_bsSolid, _bsHorizontal, _bsVertical, _bsFDiagonal,
                   _bsBDiagonal, _bsCross, _bsDiagCross,
                   _bsClear, _bsDefault, _bsSkip);

type
  TDrawType = (drawVektoren, drawVektorWeg, drawPunktspiegelung,
               drawLinienspiegelung);

type
  TObjectType = (dtPoint, dtLine, dtPolyLine, dtPolygon, dtVector);

type
  TSizeAndAngle = record
    Size  : double;
    Angle : double;
    AngColor : TColor;   
    Corner: TDoublePoint; // In TAChartUtils definiert
  end;
  
  ...
                             
Diese möchte ich nun in Pascal Script registrieren, um sie auch von dort aus verwenden zu können.
Ich weiß, wie man eigene Funktionen registrieren kann, aber zu diesem Thema habe ich im Internet noch nichts gefunden, was mir wirklich weiterhilft.

Kann ich sie auch hier registrieren, oder muss ich einen anderen Ereigniscode verwenden?

Code: Alles auswählen

procedure TForm1.PSScript1Compile(Sender: TPSScript);
begin
  // Eigene Funktionen:
  Sender.AddFunction(@ReadCellString,  'function ReadCellString(table, row, col : integer) : string');
  Sender.AddFunction(@WriteCellString, 'procedure WriteCellString(table, row, col : integer; value : string)');

  ...
end;      
Danke im Voraus.

martin_frb
Beiträge: 572
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von martin_frb »

Brauchst Du die types außerhalb des Scripts? (Oder in Funktion Parametern, von Funktionen die registriert sind)?

Oder geht es darum die (virtuelle) unit einzubinden.

1)
PSCompiler.AddTypeS('TPoint', 'record x,y: Longint; end;');

Beispiel:
components\macroscript\emscriptclasses.pas

2)
Keine Ahnung.
{$IFDEF PS_USESSUPPORT}
?

Johasch
Beiträge: 10
Registriert: Sa 8. Feb 2020, 10:50

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von Johasch »

Hallo martin_frb,
habe ein bischen mit deinem Codeschnippsel herum experimentiert und bin schon ein gutes Stück weitergekommen.
Es geht mir tatsächlich darum, Typen zwischen psScript und dem Hauptprogramm hin- und her zu schicken.

Der Code sieht momentan so aus:

Code: Alles auswählen

procedure DoublePointTest (value : TDoublePoint);
var
x, y : double;
begin
  x := value.X;
  Y := value.Y;
end;
function GetDoublePoint : TDoublePoint;
begin
  result.x := 12;
  result.y := 11;
end;

procedure TForm1.PSScript1Compile(Sender: TPSScript);
begin
  // Zuerst Typen registrieren:
  Sender.Comp.AddTypeS('TDoublePoint','record x,y : double; end;');

  // Eigene Funktionen
  Sender.AddFunction(@DoublePointTest, 'procedure DoublePointTest (value : TDoublePoint)');
  Sender.AddFunction(@GetDoublePoint,  'function GetDoublePoint : TDoublePoint;');
  //... 
end;  
Damit kann ich in Pascal Script diesen Code ohne Probleme ausführen:

Code: Alles auswählen

var
 xy : TDoublePoint;

begin
  xy := GetDoublePOint;
  xy.x := xy.x + 2;
  DoublePointTest(xy);
end.
Dass ich die Typdefinitionen aus der Unit extra anmelden muss, ist zwas schade, aber weiters kein Problem.

Jedoch weiß ich aber noch nicht, wie man z. B "TColor" aus der Graphics-Unit anmelden muss, sowie die vordefinierten Farben. Welche Befehle muss ich verwenden?

Code: Alles auswählen

implementation

uses
      uPSR_std,
      uPSC_std,
      uPSR_stdctrls,
      uPSC_stdctrls,
      uPSR_forms,
      uPSC_forms,
      uPSC_graphics,
      uPSC_controls,
      uPSC_classes,
      uPSR_graphics,
      uPSR_controls,
      uPSR_classes;
                    
 procedure SetPanelColor(color : TColor);
begin
  // Form1.Panel5.Color := color;
end;



procedure TForm1.PSScript1Compile(Sender: TPSScript);
begin
  // Zuerst Typen registrieren:
  Sender.Comp.AddTypeS('TDoublePoint','record x,y : double; end;');

  // Eigene Funktionen
  Sender.AddFunction(@ReadCellString,  'function ReadCellString(table, row, col : integer) : string');

end;                
 
Wenn ich den folgenden Code aussführe, bekomme ich die Meldung dass die Funktion nicht registriert werden kann, da vermutlich die Typdefinition noch fehlt.

Code: Alles auswählen

begin
  SetPanelColor(clRed)
end;
  

martin_frb
Beiträge: 572
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von martin_frb »

Schau mal in die Datei, die ich erwähnt habe. Ist bei der IDE dabei

Code: Alles auswählen

procedure CompRegisterBasics(AComp: TPSPascalCompiler);
    ACompiler.AddConstantN('mrNone', 'Integer',).Value^.ts32 := mrOk;
Der PS code ist auch verfügbar, für andere Typen.

Johasch
Beiträge: 10
Registriert: Sa 8. Feb 2020, 10:50

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von Johasch »

Hallo martin_frb,
manchmal braucht man nur kleine Anstöße, um weiter zu kommen.
Habe mich durch die verschiedenen Units hindurchgewühlt und schließlich die entscheidenden Hinweise gefunden. Zusätzlich habe ich mir auch noch 'uPSC_graphics' näher angesehen.
Da bei diesen Units jede Konstante und Typ extra deklariert wird, müssen bei eigene Units offensichtlich auch alle einzeln Angemeldet werden. Werde versuchen, auch so eine Importroutine zu schreiben.

Für den Fall, dass jemand diesen Beitrag mit derselben Fragestellung durchsieht, ist hier das komplette, funktionsfähige Codebeispiel:

Code: Alles auswählen

uses
     uPSC_graphics,
     uPSR_graphics;

{$R *.lfm}

{ TForm1 }

procedure DoublePointTest (value : TDoublePoint);
var
x, y : double;
begin
  Form1.Memo2.Lines.Add(FloatToStr(value.X));
  Form1.Memo2.Lines.Add(FloatToStr(value.Y));
end;
function GetDoublePoint : TDoublePoint;
begin
  result.x := 12;
  result.y := 11;
end;

procedure SetPanelColor(color : TColor);
begin
  Form1.Panel5.Color := color;
end;

procedure HandleSizeAndAngle(value : TSizeAndAngle);
var
  xy : TDoublePoint;
  co : TColor;
begin
  xy := value.XY;
  co := value.AndCol;
end;

procedure TForm1.PSScript1Compile(Sender: TPSScript);
begin
  // Zuerst Typen registrieren:
  Sender.Comp.AddTypeS('TDoublePoint','record x,y : double; end;');
  Sender.Comp.AddTypeS('TSizeAndAngle', 'record AndCol : TColor; XY : TDoublePoint;'
                                         + 'Size  : double; Angle : double; end;');
  // Eigene Funktionen
  Sender.AddFunction(@SetPanelColor,     'procedure SetPanelColor(color : TColor)');
  Sender.AddFunction(@DoublePointTest,   'procedure DoublePointTest (value : TDoublePoint)');
  Sender.AddFunction(@GetDoublePoint,    'function GetDoublePoint : TDoublePoint;');
  Sender.AddFunction(@HandleSizeAndAngle,'procedure HandleSizeAndAngle(value : TSizeAndAngle);');
end;

procedure TForm1.PSScript1CompImport(Sender: TObject; x: TPSPascalCompiler);
begin
  // Import-Routine von Unit 'uPSC_graphics' aufrufen:
  // Damit werden TColor und Farbkonstanten importiert:
  SIRegister_Graphics_TypesAndConsts(x);
end;                                                           
Damit lassen sich zwischen Pascal Script und dem Hauptprogramm ohne Probleme auch selbstdefinierte Typen austauschen z. B, entsprechen der anfänglichen Fragestellung:

Code: Alles auswählen

var
  sa : TSizeAndAngle;

begin
  sa.xy.x := 12.3;
  sa.xy.y := 0.33;
  sa.AndCol := clGreen;
  sa.Size := 21;

  HandleSizeandAngle(sa);

end.  
Für mich ist die Fragestellung damit geklärt - Danke

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von thosch »

Hab zu PascalScript mal ne ganz andere Frage:

Benutzt PascalScript Systemaufrufe. Unter Windows WinAPI und unter Linux dortiges API?

Johasch
Beiträge: 10
Registriert: Sa 8. Feb 2020, 10:50

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von Johasch »

Hallo thosch,
eine sichere Antwort kann ich dir auf diese Frage nicht geben, da ich selbst erst Anfänger mit Pascal Script bin.
Ich habe die Unit "upsRuntime" in den Componten -> PascalScript mal kurz überflogen und dort auf die Schnelle keine Systemaufrufe gesehen.
Soviel ich sehe ist Pascal Script "nur" ein Pascal Code, der den Scriptcode ausführt. Daher werden dann alle Systemaufrufe, so wie bei jedem anderen Pascal Programm erst bei der Compilierung vom Hauptprogramm umgesetzt.
Falls deine Frage darauf abzielt, wie du Systemaufrufe in PascalScript selbst einbinden kannst: Dazu müsstest du eine eigene Frage an das Forum stellen.
Ansonsten würde ich mir diesbezüglich keine Gedanken machen.

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: PSScript: Wie kann ich eigene Types in Pascal Script einbinden?

Beitrag von thosch »

Danke für diese Auskunft, da probier ich das ganz einfach mal aus.

Antworten