Page 2 of 2
Re: Update a plot in LibPlotters
Posted: Mon Oct 05, 2015 4:57 pm
by Robert
manumart1 wrote:The module LibPlotters (subsystem Lib from
http://www.zinnamturm.eu/downloadsIN.htm#Lib) does not have Plotter.
UpdateNow.
I modified module LibPlotters as you showed, but got an error:
So
RestoreGraphic is missing. I changed it to
Restore and compiled ok.
It now works ok, i.e. each line is drawn separately and immediately, instead of all at the same time when the program finished.
Yes, what I posted was
suggestions, not finished code. If it works ok the way to clean it up is to observe that msg.graphicOnly is always FALSE, so you can remove the "IF msg.graphicOnly THEN" clauses, and even remove the graphicOnly fields entirely.
But... if the delay is too long, after 6 seconds the cursor becomes busy and the screen freezes
I often observe this problem. I think it is a general BlackBox problem with any long running Command, and not related to LibPlotters. I don't find it a time issue (6 seconds), but is caused when you do anything on the computer; move the mouse, hit the keyboard, top another programme ....
When the Command finishes the screen is then redrawn with the correct final result; it is only the intermediate results that can't be seen.
I also find that Chris's magic ProcessMessages can be very helpful - it can also be
dangerous.
Regards
Re: Update a plot in LibPlotters
Posted: Mon Oct 05, 2015 9:03 pm
by Ivan Denisov
I recommend you never to use:
Better use
Services.Action!
Re: Update a plot in LibPlotters
Posted: Mon Oct 05, 2015 9:39 pm
by Ivan Denisov
Please look at this example. It updates plotters 5 times without WinApi (and without UpdateNow).
Code: Select all
MODULE Test;
IMPORT Log, Plotters := LibPlotters, Vec := LibVectors, Ports, Services, Models;
TYPE
Animation = POINTER TO RECORD (Services.Action)
j: INTEGER;
p: Plotters.Plotter;
END;
PROCEDURE (a: Animation) Do ();
VAR data: Vec.Vector; i: INTEGER; msg: Models.UpdateMsg;
BEGIN
Log.String("Iteration : "); Log.Int(a.j); Log.Ln();
data := Vec.New(512);
FOR i := 0 TO LEN(data) - 1 DO data[i] := a.j END;
a.p.DrawVector(data, 0, 1, 0, 1, 0, Ports.blue);
Models.Broadcast(a.p, msg);
INC(a.j);
IF a.j <= 5 THEN
Services.DoLater(a, Services.Ticks() + Services.resolution);
ELSE
Services.RemoveAction(a)
END
END Do;
PROCEDURE Run3* ();
VAR
p: Plotters.Plotter;
a: Animation;
BEGIN
p := Plotters.dir.NewPlotter ('Line plots');
p.SetMargin (10, 5, 3, 3);
p.Scale (0, 50, 0, 10);
Plotters.OpenAux(p, 0, 0, TRUE, 'Test plot update');
NEW(a);
a.j := 1;
a.p := p;
Services.DoLater(a, Services.now);
END Run3;
END Test.
Re: Update a plot in LibPlotters
Posted: Tue Oct 06, 2015 8:04 am
by Robert
Ivan Denisov wrote:Better use Services.Action!
It updates plotters 5 times without WinApi (and without UpdateNow).
And it solves the freezing display problem!
But restructuring the code to use Actions is not always very convenient (maybe you want the update inside 2 nested loops, or inside some recursive structure). So sometimes it can be tempting not to use Actions.
Re: Update a plot in LibPlotters
Posted: Tue Oct 06, 2015 6:24 pm
by manumart1
The program from
Ivan works really well. The window can even be moved with the mouse while the program is running.
But the call to
Services.RemoveAction(a) intrigues me. Is it necessary? I thought that the Action
a was being consumed during the execution of
Do.
Code: Select all
PROCEDURE (a: Animation) Do ();
...
IF a.j <= 5 THEN
Services.DoLater(a, Services.Ticks() + Services.resolution);
ELSE
Services.RemoveAction(a)
END
END Do;
Re: Update a plot in LibPlotters
Posted: Wed Oct 07, 2015 2:14 am
by Ivan Denisov
Services.RemoveAction(a) is not necessary in this case. I think, that it can speed up garbage collection, removing pointer to this action from the Services module. However maybe it does not. Nothing bad will happen if you will call Services.RemoveAction(a), when you do not need the action.