SRL Archive - Development

Forms..


mastaraymond

2009-10-17 14:25:21

Forms are quit a problem in FPC/Lazarus. Lazarus kind-of prohibits forms being run in threads other than the mainthread..
We can take away this 'safety' piece of code, but it will result in forms not being 100% okay.

So, drop forms compatibility?

nielsie95

2009-10-17 14:28:23

Doesn't SCAR run forms in the main thread too through ThreadSafeCall?

mastaraymond

2009-10-17 14:32:44

From: nielsie95
Doesn't SCAR run forms in the main thread too through ThreadSafeCall?

Hmm; Doubt it since Delphi allows you to run Forms in different threads, and I'm pretty sure ThreadSafeCall actually creates a different thread.

nielsie95

2009-10-17 17:10:32

I think it executes the function in the main thread. Here's what the manual says on ThreadSafeCall:


function ThreadSafeCall(ProcName: string; var V: TVariantArray): TVariant;
Calls function or procedure in thread-safe way. SCAR scripts operate in separate thread to prevent main form freezing and as a rule threads are not allowed to create, modify or even access forms or controls directly. That means scripts can't create or use forms or controls directly, operate with debug image directly etc. Most of SCAR functions that access forms (Writeln, Status, Readln, LoadDebugImg, ect) are thread-safe already. However if you're operating with debug window canvas directly for an example, you're risking to make SCAR unstable or crash it.


EDIT:

From: Freddy1990
Using ThreadSafeCall to do this is a really bad idea because it synchronizes the script thread with the main thread… And the functions in SCAR are written to run in a separated thread, so synchronizing some of them would not be wise, however, I can probably add a CallProc function to SCAR instead which doesn't synchronize threads, of course it can't be used for forms then simply because it wouldn't be thread-safe then. For forms you'd still need ThreadSafeCall.


And are you sure Delphi forms are threadsafe too?

Wizzup?

2009-10-17 17:18:08

The question is: do you really want to run user forms on the main thread?
I do wonder if it works, though. ;)

nielsie95

2009-10-17 17:26:33

I'm afraid you don't have much choice when you're working with Delphi or Lazarus VCL.

mastaraymond

2009-10-17 17:41:35

From: nielsie95
I think it executes the function in the main thread. Here's what the manual says on ThreadSafeCall:



EDIT:



And are you sure Delphi forms are threadsafe too?

Delphi forms aren't fully thread safe, but yeah they can be run from a different thread (like your webbrowser)..

If that is true ^, I have no clue how freddy manages to do it. Because when you run a pascalscript method it kinda freezes the thread, meaning the mainform would freeze.
So, sleep(50000) in ThreadSafeCall would block the mainthread,
Wouch, it DOES block the mainthread!

Okay, there has to be a way to execute PSScript commands line by line then..

nielsie95

2009-10-17 17:52:30

TPSScript.ExecuteFunction?

mastaraymond

2009-10-17 18:20:06

From: nielsie95
TPSScript.ExecuteFunction?

Result := CurrThread.PSScript.Exec.RunProcPVar(v,CurrThread.PSScript.Exec.GetProc(Procname));

is what I use right now, but that will block the mainthread -> So then we can't stop the script. There has to be a way to run line by line or something, will see later :-).

Markus

2009-10-18 05:51:21

Wasn't there an OnLine event in PS? Just add processmessages to it?

nielsie95

2009-10-18 06:15:25

If you run line by line it could still block the mainform using Sleep?

Markus

2009-10-18 07:13:47

Most likely, yes, same thing Freddy is having now?

mastaraymond

2009-10-18 12:06:29

From: Markus
Wasn't there an OnLine event in PS? Just add processmessages to it?

Perfect solution, thank you sir.

Wizzup?

2009-10-18 12:26:02

So, we really want forms in this alpha? :<
TBH, calling ProcessMessages every line is just a waste of resources…

mastaraymond

2009-10-18 12:59:59

From: Wizzup?
So, we really want forms in this alpha? :<
TBH, calling ProcessMessages every line is just a waste of resources…

Will only happen in a SafeThread, :)

mastaraymond

2009-10-18 16:08:05

Scar doesn't use an OnLine event at all :-(.
But yeah, got it working (for windows a tleast, untested @ linux)

program new;
var
TempVar : Boolean;
procedure OnClick(Sender : TObject);
begin;
TempVar := True;
Writeln('YOU HAS CLICKED THE BUTTON');
end;
function x : Boolean;
var
MyForm : TForm;
AButton : TButton;
begin;
TempVar := False;
Result := false;
MyForm := CreateForm;
MyForm.Width := 250;
MyForm.Height := 250;
AButton := CreateButton(MyForm);
AButton.Parent := MyForm;
Abutton.SetBounds(100,100,100,50);
AButton.OnClick := @OnClick;
AButton.Caption := 'Test';
MyForm.ShowModal;
MyForm.Free;
Result := TempVar;
end;
var
v : TVariantArray;
begin
if ThreadSafeCall('x',v) then
Writeln('You clicked the button! WinnOr')
else
Writeln('You did not click the button, fail all the way');
end.

There still is some bug in PS left that doesn't allow me to create form objects in PS itself, but this can be fixed (if I feel like it ^_^).

Wizzup?

2009-10-18 16:51:29

Works on Linux.

R0b0t1

2009-10-18 20:09:09

How about ditch the main form and create an auxiliary form (the "main" form) which can be run in a separate thread.

mastaraymond

2009-10-20 08:15:04

From: R0b0t1
How about ditch the main form and create an auxiliary form (the "main" form) which can be run in a separate thread.
Won't work since it actually has to run in the so-called "MainThread".

I'm still confused why it crashes on object creation /me looks futher!

Wizzup?

2009-10-20 08:39:05

Instead of threads, we could also fork()…

R0b0t1

2009-10-20 22:48:30

No… I mean you make the main form invisible and create another thread for the actions of the new "main form" (EG, draw())

mastaraymond

2009-10-21 10:01:33

From: R0b0t1
No… I mean you make the main form invisible and create another thread for the actions of the new "main form" (EG, draw())

Yeah, but that is really not possible since there is an exception build in FPC that errors when you "open" forms in non-mainthreads.. Mainthread being the "first" thread created in your application.

R0b0t1

2009-10-21 23:39:07

Then it would certainly be possible to run pascal script in another thread?

nielsie95

2009-10-22 02:34:34

Yes, but forms need to run in the main thread, hence ThreadSafeCall.

NxTitle

2009-10-22 12:42:33

This suggestion may require rebuilding quite a bit of Mufasa, but why not split the interpreter and the forms into two separate programs?

That way when you run Mufasa, you load up the forms in the main thread. After loading a script and you press play, it creates a second process in the background that does all the hard work. If you need to get input or output then you can redirect the stdin/out/err, or even use sockets to do more advanced things (even the possibility of advanced debugging within Mufasa)

However it would require that lots of the code is split in order to create these two programs, which doesn't make this the easiest fix possible.

Wizzup?

2009-10-22 12:53:37

From: NxTitle
This suggestion may require rebuilding quite a bit of Mufasa, but why not split the interpreter and the forms into two separate programs?

That way when you run Mufasa, you load up the forms in the main thread. After loading a script and you press play, it creates a second process in the background that does all the hard work. If you need to get input or output then you can redirect the stdin/out/err, or even use sockets to do more advanced things (even the possibility of advanced debugging within Mufasa)

However it would require that lots of the code is split in order to create these two programs, which doesn't make this the easiest fix possible.


There are plans to make it communicate over sockets, but it would work a bit different than you suggested.

One "Main" process -> It will execute all the scripts, and one could connect to it, and send commands, like {stop, start, pause, restart}-script.
This way you wouldn't even have to run a GUI. You only connect to it with a GUI to manage the stuff.

But that's a idea that won't be finished in very near future… :)