mirror of
https://github.com/moparisthebest/Simba
synced 2024-12-23 07:48:50 -05:00
Changes in doc and code.
git-svn-id: http://www.villavu.com/repositories/merlijn/mufasa@267 3f818213-9676-44b0-a9b4-5e4c4e03d09d
This commit is contained in:
parent
2bb26ee30f
commit
b4d56fa979
@ -21,15 +21,14 @@ Developer notes include:
|
|||||||
\item Bugs
|
\item Bugs
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
\chapter{Core}
|
\chapter{Core}
|
||||||
|
|
||||||
\section{TClient}
|
\section{TClient}
|
||||||
|
|
||||||
The TClient class bundles all the other Core classes.
|
The TClient class bundles all the other Core classes.
|
||||||
It's main use is to make using the Mufasa Macro Library trivial, by bundling
|
It's main use is to make using the Mufasa Macro Library trivial, by bundling
|
||||||
the for Mufasa classes into one class, and provides the methods to make them
|
the core Mufasa classes into one class, and providing the methods to make those
|
||||||
cooperate.
|
classes cooperate.
|
||||||
|
|
||||||
\section{TMWindow}
|
\section{TMWindow}
|
||||||
|
|
||||||
@ -48,6 +47,20 @@ Retreiving information from the target Application/Window.
|
|||||||
|
|
||||||
\section{TMDTM}
|
\section{TMDTM}
|
||||||
|
|
||||||
|
The TMDTM class is a DTM manager. It provides methods to add, store, load
|
||||||
|
and free DTM's. It has a few few other features. One of it's other features
|
||||||
|
is keeping track of what DTMs are unfreed. It can, for example, help you find
|
||||||
|
a bug in your code, by printing out information of the DTM that you forgot to
|
||||||
|
free. You can also give names to DTMs, which eases debugging further.
|
||||||
|
|
||||||
|
If you try to access an invalid DTM, the MML will throw an exception.
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{AddDTM}
|
||||||
|
\subsection{GetDTM}
|
||||||
|
\subsection{DTMFromString}
|
||||||
|
\subsection{FreeDTM}
|
||||||
|
|
||||||
\section{TMOCR}
|
\section{TMOCR}
|
||||||
|
|
||||||
\chapter{Add on}
|
\chapter{Add on}
|
||||||
|
@ -19,6 +19,75 @@ the Mufasa macro library exports to it's Interpreter, PS\footnote{Pascal
|
|||||||
Script}. For a real in depth explanation, the Mufasa Handbook would be a better
|
Script}. For a real in depth explanation, the Mufasa Handbook would be a better
|
||||||
place to look.
|
place to look.
|
||||||
|
|
||||||
|
\chapter{Exceptions}
|
||||||
|
|
||||||
|
\section{Motivation}
|
||||||
|
Mufasa takes debugging to a new level by using exceptions for error handling,
|
||||||
|
this allows you to even catch possible errors in your script, thus allowing
|
||||||
|
the script to continue it's exection. We strongly believe Exceptions are the
|
||||||
|
way to go. They were implemented for a reason.
|
||||||
|
|
||||||
|
\section{When do we throw Exceptions}
|
||||||
|
|
||||||
|
There are a lot of occasions where Mufasa may throw exceptions.
|
||||||
|
|
||||||
|
Consider the following program:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
program new;
|
||||||
|
var
|
||||||
|
bmp:integer;
|
||||||
|
x, y:integer;
|
||||||
|
begin
|
||||||
|
bmp:=bitmapfromstring(200, 200, '');
|
||||||
|
x := -1;
|
||||||
|
y := -1;
|
||||||
|
fastsetpixel(bmp, x, y, clwhite);
|
||||||
|
end.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
This code is, always invalid. If you try this in SCAR, it will execute and do
|
||||||
|
nothing. \\
|
||||||
|
|
||||||
|
Very useful, right? \\
|
||||||
|
|
||||||
|
Now, when we execute the same code with MML, we get this:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
Error: Exception: You are accessing an invalid point, (-1,-1) at bitmap[0] at line 8
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Further expanding the example:
|
||||||
|
\begin{verbatim}
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Results in:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
Compiled succesfully in 8 ms.
|
||||||
|
We failed to do a setpixel with x = .-1, y = -1
|
||||||
|
Succesfully executed
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\subsection{Going beyond script debugging}
|
||||||
|
Exceptions are even in the very core of Mufasa. This greatly improves
|
||||||
|
debugging in general, as we will also be able to easily spot errors in Mufasa.
|
||||||
|
When they occured, what the values of the variables were, et cetera.
|
||||||
|
|
||||||
|
Let's look at a function known as ReturnData(), which returns the client data.
|
||||||
|
It for example checks if the points that are passed are consistent.
|
||||||
|
If they are not, an Exception is thrown. If Mufasa does not catch that
|
||||||
|
particular Exception\footnote{Which it doesn't, as a feature.}, then it will
|
||||||
|
be thrown in your script. This will indicate that somehow ReturnData got
|
||||||
|
invalid coordinates. Usually this Exception is not throw, as other functions
|
||||||
|
also check their input for sanity, and then it is possible to throw a more
|
||||||
|
detailed exception.
|
||||||
|
|
||||||
|
\subsection{How to Handle Exceptions}
|
||||||
|
|
||||||
|
An exception is handled with a $try$ ... $except$ ... $finally$ statement.
|
||||||
|
See the example in the previous section for more details.
|
||||||
|
|
||||||
\chapter{Input}
|
\chapter{Input}
|
||||||
|
|
||||||
\section{Mouse}
|
\section{Mouse}
|
||||||
|
@ -10,7 +10,7 @@ uses
|
|||||||
Forms,Interfaces,
|
Forms,Interfaces,
|
||||||
LCLIntf,
|
LCLIntf,
|
||||||
Client,
|
Client,
|
||||||
bitmaps,x ,mufasatypes,dtm,dtmutil
|
bitmaps,x ,mufasatypes,dtm,dtmutil, ocrutil
|
||||||
|
|
||||||
|
|
||||||
{ you can add units after this };
|
{ you can add units after this };
|
||||||
@ -30,6 +30,28 @@ type
|
|||||||
|
|
||||||
{ MufasaTests }
|
{ MufasaTests }
|
||||||
|
|
||||||
|
const
|
||||||
|
CW = 800;
|
||||||
|
CH = 600;
|
||||||
|
|
||||||
|
function randomdtm(a: integer): pdtm;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
initdtm(result, a);
|
||||||
|
for i := 1 to result.l - 1 do
|
||||||
|
begin
|
||||||
|
result.p[i] := point(random(30) - 15, random(30) - 15);
|
||||||
|
result.c[i] := 0;
|
||||||
|
result.t[i] := random(255);
|
||||||
|
result.asz [i] := random(5);
|
||||||
|
result.ash[i] := 0;
|
||||||
|
writeln(format('dtm: (%d, %d) c: %d, t: %d, asz: %d', [result.p[i].x,
|
||||||
|
result.p[i].y, result.c[i], result.t[i], result.asz[i]]));
|
||||||
|
end;
|
||||||
|
result.c[0] := 255;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure MufasaTests.DoRun;
|
procedure MufasaTests.DoRun;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -61,38 +83,47 @@ begin
|
|||||||
C := TClient.Create;
|
C := TClient.Create;
|
||||||
|
|
||||||
bmp := TMufasaBitmap.Create;
|
bmp := TMufasaBitmap.Create;
|
||||||
bmp.SetSize(800,600);
|
bmp.SetSize(CW,CH);
|
||||||
FillChar(bmp.FData[0],sizeof(trgb32)*800*600, 0);
|
Writeln(Format('Client W/H: %d, %d', [CW, CH]));
|
||||||
|
FillChar(bmp.FData[0],sizeof(trgb32)*CW*CH, 0);
|
||||||
Randomize;
|
Randomize;
|
||||||
for i := 0 to 200 do
|
for i := 0 to 500 do
|
||||||
bmp.fastsetpixel(random(800), random(600), 255);
|
bmp.fastsetpixel(random(CW), random(CH), 255);
|
||||||
{bmp.FastSetPixel(8,8,255);
|
{ bmp.FastSetPixel(8,8,255);
|
||||||
bmp.FastSetPixel(9,9,255);
|
bmp.FastSetPixel(9,9,255);
|
||||||
bmp.FastSetPixel(7,7,255);
|
bmp.FastSetPixel(7,7,255);
|
||||||
bmp.FastSetPixel(9,8,255);
|
bmp.FastSetPixel(9,8,255);
|
||||||
bmp.FastSetPixel(8,9,255); }
|
bmp.FastSetPixel(8,9,255); }
|
||||||
C.MWindow.SetTarget(bmp);
|
C.MWindow.SetTarget(bmp);
|
||||||
|
|
||||||
|
|
||||||
initdtm(dtm, 3);
|
{ initdtm(dtm, 5);
|
||||||
dtm.p[0] := Point(2, 2);
|
dtm.p[0] := Point(2, 2);
|
||||||
dtm.p[1] := Point(-3, -3);
|
dtm.p[1] := Point(-3, -3);
|
||||||
dtm.p[2] := Point(0, 0);
|
dtm.p[2] := Point(0, 0);
|
||||||
|
dtm.p[3] := Point(1, 1);
|
||||||
|
dtm.p[4] := Point(3, 3);
|
||||||
dtm.c[0] := 255;
|
dtm.c[0] := 255;
|
||||||
dtm.t[0] := 255;
|
dtm.t[0] := 0;
|
||||||
dtm.asz[1] := 1;
|
dtm.asz[1] := 1;
|
||||||
dtm.ash[1] := dtm_Rectangle;
|
dtm.ash[1] := dtm_Rectangle; }
|
||||||
|
|
||||||
setlength(p, 1);
|
dtm := randomdtm(20);
|
||||||
|
|
||||||
|
// setlength(p, 1);
|
||||||
|
time := GetTickCount;
|
||||||
|
C.MFinder.FindDTMs(dtm, p, 0, 0,CW-1, CH-1, 0);
|
||||||
|
writeln(inttostr(gettickcount - time) + 'ms');
|
||||||
|
setlength(p,0);
|
||||||
|
|
||||||
time := GetTickCount;
|
time := GetTickCount;
|
||||||
C.MFinder.FindDTMs(dtm, p, 0, 0,799, 599, 0);
|
C.MFinder.FindDTMs(dtm, p, 0, 0,CW-1, CH-1, 0);
|
||||||
//C.MFinder.FindDTM(dtm, p[0].x, p[0].y, 0, 0,799, 599);
|
//C.MFinder.FindDTM(dtm, p[0].x, p[0].y, 0, 0,CW-1, CH-1);
|
||||||
writeln(inttostr(gettickcount - time));
|
writeln(inttostr(gettickcount - time) + 'ms');
|
||||||
writeln(inttostr(length(p)));
|
writeln(inttostr(length(p))+ ' points found');
|
||||||
|
|
||||||
{for i := 0 to high(p) do
|
{for i := 0 to high(p) do
|
||||||
writeln(format('%d: (%d, %d)', [i, p[i].x, p[i].y])); }
|
writeln(format('%d: (%d, %d)', [i, p[i].x, p[i].y])); }
|
||||||
|
|
||||||
|
|
||||||
//bmp.OnDestroy:=nil;
|
//bmp.OnDestroy:=nil;
|
||||||
|
90
Tests/PS/FileTests.mufa
Normal file
90
Tests/PS/FileTests.mufa
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
program Hoi;
|
||||||
|
|
||||||
|
{
|
||||||
|
Description: Test file to test the consistency of
|
||||||
|
the following Functions:
|
||||||
|
|
||||||
|
AppPath, DirectoryExists, FileExists, ExeExt,
|
||||||
|
DirectorySeperator, OpenFile, CreateFile, RewriteFile,
|
||||||
|
WriteFileString, ReadFileString, SetFileCharPointer,
|
||||||
|
FileSize, EndOfFile, FileContents.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Needs: GetFiles.
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
Using ./test as TestPath crashes on Linux.
|
||||||
|
Usage:
|
||||||
|
Run it. Set the TestPath to a different directory if you are on Windows. :)
|
||||||
|
}
|
||||||
|
|
||||||
|
Const
|
||||||
|
TestPath = './test';
|
||||||
|
|
||||||
|
fsFromBeginning = 0; // offset must be pos or 0
|
||||||
|
fsFromCurrent = 1; // offset pos or neg
|
||||||
|
fsFromEnd = 2; // offset only neg or 0
|
||||||
|
|
||||||
|
var
|
||||||
|
s, s2: string;
|
||||||
|
myFile, myFile2: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
s := apppath;
|
||||||
|
Writeln('Our current path is: ' + s);
|
||||||
|
{ If DirectoryExists(s) Then
|
||||||
|
writeln('Directory ' + s + ' exists.'); }
|
||||||
|
|
||||||
|
{ If FileExists(s + DirectorySeperator + 'Cogat' + ExeExt) Then
|
||||||
|
writeln('We exist!'); }
|
||||||
|
|
||||||
|
myFile := CreateFile(TestPath);
|
||||||
|
WriteFileString(myFile, 'wat');
|
||||||
|
WriteFileString(myFile, 'watnumber2');
|
||||||
|
CloseFile(myFile);
|
||||||
|
|
||||||
|
myFile := OpenFile(TestPath, False);
|
||||||
|
ReadFileString(myFile, s2, 2);
|
||||||
|
writeln('s2: ' + s2);
|
||||||
|
CloseFile(myFile);
|
||||||
|
|
||||||
|
myFile := CreateFile(TestPath + '2');
|
||||||
|
WriteFileString(myFile, 'wat222');
|
||||||
|
|
||||||
|
CloseFile(myFile);
|
||||||
|
|
||||||
|
// TestPath now contains; 'watwatnumber2'. We will make it write 'number',
|
||||||
|
// and then 2.
|
||||||
|
myFile := OpenFile(TestPath, False);
|
||||||
|
SetFileCharPointer(myFile, 6, fsFromBeginning);
|
||||||
|
ReadFileString(myFile, s2, 6);
|
||||||
|
writeln('s2: ' + s2);
|
||||||
|
s2 := '';
|
||||||
|
|
||||||
|
SetFileCharPointer(myFile, -1, fsFromEnd);
|
||||||
|
ReadFileString(myFile, s2, 1);
|
||||||
|
writeln('s2: ' + s2);
|
||||||
|
CloseFile(myFile);
|
||||||
|
|
||||||
|
// myFile2 should be -1.
|
||||||
|
myFile := RewriteFile(TestPath, False);
|
||||||
|
myFile2 := RewriteFile(TestPath, False);
|
||||||
|
writeln(inttostr(myFile) + ' : ' + inttostr(myFile2));
|
||||||
|
|
||||||
|
// myFile2 should be -1.
|
||||||
|
myFile2 := OpenFile(TestPath, False);
|
||||||
|
writeln(inttostr(myFile) + ' : ' + inttostr(myFile2));
|
||||||
|
|
||||||
|
// Now, we will test EndOfFile, and FileSize.
|
||||||
|
|
||||||
|
While Not EndOfFile(myFile) Do
|
||||||
|
Begin
|
||||||
|
ReadFileString(myFile, s2, 1);
|
||||||
|
Writeln(s2);
|
||||||
|
End;
|
||||||
|
|
||||||
|
CloseFile(myFile);
|
||||||
|
|
||||||
|
//Writeln(FileContents(TestPath));
|
||||||
|
writeln('wat');
|
||||||
|
end.
|
@ -41,7 +41,9 @@ type
|
|||||||
function AddpDTM(d: pDTM): Integer;
|
function AddpDTM(d: pDTM): Integer;
|
||||||
function GetDTM(index: Integer; out dtm: pDTM): Boolean;
|
function GetDTM(index: Integer; out dtm: pDTM): Boolean;
|
||||||
procedure FreeDTM(DTM: Integer);
|
procedure FreeDTM(DTM: Integer);
|
||||||
Function StringToDTM(S: String): pDTM;
|
function StringToDTM(S: String): pDTM;
|
||||||
|
function SetDTMName(DTM: Integer; S: String): boolean;
|
||||||
|
|
||||||
|
|
||||||
{ function FindDTM(DTM: Integer; out x, y: Integer; x1, y1, x2,
|
{ function FindDTM(DTM: Integer; out x, y: Integer; x1, y1, x2,
|
||||||
y2: Integer): Boolean;
|
y2: Integer): Boolean;
|
||||||
@ -272,6 +274,18 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TMDTM.SetDTMName(DTM: Integer; s: string): boolean;
|
||||||
|
var
|
||||||
|
dtm_: pDTM;
|
||||||
|
begin
|
||||||
|
if(GetDTM(dtm, dtm_)) then
|
||||||
|
begin
|
||||||
|
dtm_.n := s;
|
||||||
|
Exit(True);
|
||||||
|
end;
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
{/\
|
{/\
|
||||||
Unloads the DTM at the given index from the DTM Array.
|
Unloads the DTM at the given index from the DTM Array.
|
||||||
Notes:
|
Notes:
|
||||||
|
@ -57,6 +57,7 @@ var
|
|||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
d.l := len;
|
d.l := len;
|
||||||
|
d.n := '';
|
||||||
setlength(d.p, len);
|
setlength(d.p, len);
|
||||||
setlength(d.c, len);
|
setlength(d.c, len);
|
||||||
setlength(d.t, len);
|
setlength(d.t, len);
|
||||||
@ -78,10 +79,13 @@ var
|
|||||||
i : integer;
|
i : integer;
|
||||||
begin;
|
begin;
|
||||||
i := 0;
|
i := 0;
|
||||||
|
if tdtm.n <> '' then
|
||||||
|
writeln('Name: ' + tdtm.n);
|
||||||
WriteLn('MainPoint ' + inttostr(tDTM.p[i].x) + ', ' + inttostr(tDTM.p[i].y) + ' col: ' + inttostr(tDTM.c[i]) + ', tol: ' + inttostr(tDTM.t[i]) + '; ashape ' + inttostr(tdtm.ash[i]) + ' asize ' + inttostr(tdtm.asz[i]));
|
WriteLn('MainPoint ' + inttostr(tDTM.p[i].x) + ', ' + inttostr(tDTM.p[i].y) + ' col: ' + inttostr(tDTM.c[i]) + ', tol: ' + inttostr(tDTM.t[i]) + '; ashape ' + inttostr(tdtm.ash[i]) + ' asize ' + inttostr(tdtm.asz[i]));
|
||||||
for I := 1 to High(tDTM.p) do
|
for I := 1 to High(tDTM.p) do
|
||||||
WriteLn('SubPoint['+IntToStr(I) + '] ' + inttostr(tDTM.p[i].x) + ', ' + inttostr(tDTM.p[i].y) + ' col: ' + inttostr(tDTM.c[i]) + ', tol: ' + inttostr(tDTM.t[i]) + '; ashape ' + inttostr(tdtm.ash[i]) + ' asize ' + inttostr(tdtm.asz[i]));
|
WriteLn('SubPoint['+IntToStr(I) + '] ' + inttostr(tDTM.p[i].x) + ', ' + inttostr(tDTM.p[i].y) + ' col: ' + inttostr(tDTM.c[i]) + ', tol: ' + inttostr(tDTM.t[i]) + '; ashape ' + inttostr(tdtm.ash[i]) + ' asize ' + inttostr(tdtm.asz[i]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function pDTMToTDTM(Const DTM: pDTM): TDTM;
|
Function pDTMToTDTM(Const DTM: pDTM): TDTM;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
|
@ -1654,16 +1654,9 @@ begin
|
|||||||
// C = DTM.C
|
// C = DTM.C
|
||||||
C := DTM.c;
|
C := DTM.c;
|
||||||
|
|
||||||
// Now, we must find the occurances of all colours.
|
|
||||||
// This part should be turned into a more general function (for DTM Finding).
|
|
||||||
// Something like FindColorsMultiBooleanArray (?)
|
|
||||||
|
|
||||||
// Retreive Client Data.
|
// Retreive Client Data.
|
||||||
PtrData := TClient(Client).MWindow.ReturnData(x1, y1, W + 1, H + 1);
|
PtrData := TClient(Client).MWindow.ReturnData(x1, y1, W + 1, H + 1);
|
||||||
|
|
||||||
// Do we want to "cache" these vars?
|
|
||||||
// We will, for now. Easier to type.
|
|
||||||
|
|
||||||
cd := CalculateRowPtrs(PtrData, h + 1);
|
cd := CalculateRowPtrs(PtrData, h + 1);
|
||||||
//writeln(format('w,h: %d, %d', [w,h]));
|
//writeln(format('w,h: %d, %d', [w,h]));
|
||||||
|
|
||||||
@ -1728,24 +1721,3 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
{ crap code }
|
|
||||||
|
|
||||||
// this is the probably the slowest part of the algorithm.
|
|
||||||
{ for yy := y1 to y2 do
|
|
||||||
begin
|
|
||||||
for xx := x1 to x2 do
|
|
||||||
begin
|
|
||||||
{for i := 0 to dtm.l - 1 do
|
|
||||||
begin
|
|
||||||
// optimise this later...
|
|
||||||
if TClient(Client).MFinder.SimilarColors(dtm.c[i], RGBToColor(Ptr^.R,Ptr^.G,Ptr^.B) , dtm.t[i]) then
|
|
||||||
B[xx][yy] := B[xx][yy] or (1 shl i);
|
|
||||||
end; }
|
|
||||||
inc(Ptr);
|
|
||||||
end;
|
|
||||||
inc(Ptr, PtrInc);
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ type
|
|||||||
l: Integer;
|
l: Integer;
|
||||||
p: TPointArray;
|
p: TPointArray;
|
||||||
c, t, asz, ash: TIntegerArray;
|
c, t, asz, ash: TIntegerArray;
|
||||||
|
n: String; // DOEN
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Other DTM Types }
|
{ Other DTM Types }
|
||||||
|
@ -83,9 +83,10 @@ begin
|
|||||||
result := true;
|
result := true;
|
||||||
OCRPath := path + DS;
|
OCRPath := path + DS;
|
||||||
if DirectoryExists(path + DS + 'UpChars' + DS) then
|
if DirectoryExists(path + DS + 'UpChars' + DS) then
|
||||||
OCRData[0] := InitOCR(path + DS + 'UpChars' + DS)
|
OCRData[0] := ocrutil.InitOCR(path + DS + 'UpChars' + DS)
|
||||||
else
|
else
|
||||||
result := false;
|
result := false;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMOCR.GetUpTextAt(atX, atY: integer): string;
|
function TMOCR.GetUpTextAt(atX, atY: integer): string;
|
||||||
|
Loading…
Reference in New Issue
Block a user