1
0
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:
Wizzup? 2009-12-04 20:57:00 +00:00
parent 2bb26ee30f
commit b4d56fa979
9 changed files with 244 additions and 49 deletions

View File

@ -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}

View File

@ -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}

View File

@ -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
View 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.

View File

@ -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:

View File

@ -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

View File

@ -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;
}

View File

@ -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 }

View File

@ -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;