mirror of
https://github.com/moparisthebest/Simba
synced 2024-12-22 23:38: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
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\chapter{Core}
|
||||
|
||||
\section{TClient}
|
||||
|
||||
The TClient class bundles all the other Core classes.
|
||||
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
|
||||
cooperate.
|
||||
the core Mufasa classes into one class, and providing the methods to make those
|
||||
classes cooperate.
|
||||
|
||||
\section{TMWindow}
|
||||
|
||||
@ -48,6 +47,20 @@ Retreiving information from the target Application/Window.
|
||||
|
||||
\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}
|
||||
|
||||
\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
|
||||
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}
|
||||
|
||||
\section{Mouse}
|
||||
|
@ -10,7 +10,7 @@ uses
|
||||
Forms,Interfaces,
|
||||
LCLIntf,
|
||||
Client,
|
||||
bitmaps,x ,mufasatypes,dtm,dtmutil
|
||||
bitmaps,x ,mufasatypes,dtm,dtmutil, ocrutil
|
||||
|
||||
|
||||
{ you can add units after this };
|
||||
@ -30,6 +30,28 @@ type
|
||||
|
||||
{ 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;
|
||||
|
||||
var
|
||||
@ -61,38 +83,47 @@ begin
|
||||
C := TClient.Create;
|
||||
|
||||
bmp := TMufasaBitmap.Create;
|
||||
bmp.SetSize(800,600);
|
||||
FillChar(bmp.FData[0],sizeof(trgb32)*800*600, 0);
|
||||
bmp.SetSize(CW,CH);
|
||||
Writeln(Format('Client W/H: %d, %d', [CW, CH]));
|
||||
FillChar(bmp.FData[0],sizeof(trgb32)*CW*CH, 0);
|
||||
Randomize;
|
||||
for i := 0 to 200 do
|
||||
bmp.fastsetpixel(random(800), random(600), 255);
|
||||
{bmp.FastSetPixel(8,8,255);
|
||||
for i := 0 to 500 do
|
||||
bmp.fastsetpixel(random(CW), random(CH), 255);
|
||||
{ bmp.FastSetPixel(8,8,255);
|
||||
bmp.FastSetPixel(9,9,255);
|
||||
bmp.FastSetPixel(7,7,255);
|
||||
bmp.FastSetPixel(9,8,255);
|
||||
bmp.FastSetPixel(8,9,255); }
|
||||
bmp.FastSetPixel(8,9,255); }
|
||||
C.MWindow.SetTarget(bmp);
|
||||
|
||||
|
||||
initdtm(dtm, 3);
|
||||
{ initdtm(dtm, 5);
|
||||
dtm.p[0] := Point(2, 2);
|
||||
dtm.p[1] := Point(-3, -3);
|
||||
dtm.p[2] := Point(0, 0);
|
||||
dtm.p[3] := Point(1, 1);
|
||||
dtm.p[4] := Point(3, 3);
|
||||
dtm.c[0] := 255;
|
||||
dtm.t[0] := 255;
|
||||
dtm.t[0] := 0;
|
||||
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;
|
||||
C.MFinder.FindDTMs(dtm, p, 0, 0,799, 599, 0);
|
||||
//C.MFinder.FindDTM(dtm, p[0].x, p[0].y, 0, 0,799, 599);
|
||||
writeln(inttostr(gettickcount - time));
|
||||
writeln(inttostr(length(p)));
|
||||
C.MFinder.FindDTMs(dtm, p, 0, 0,CW-1, CH-1, 0);
|
||||
//C.MFinder.FindDTM(dtm, p[0].x, p[0].y, 0, 0,CW-1, CH-1);
|
||||
writeln(inttostr(gettickcount - time) + 'ms');
|
||||
writeln(inttostr(length(p))+ ' points found');
|
||||
|
||||
{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;
|
||||
|
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 GetDTM(index: Integer; out dtm: pDTM): Boolean;
|
||||
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,
|
||||
y2: Integer): Boolean;
|
||||
@ -272,6 +274,18 @@ begin
|
||||
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.
|
||||
Notes:
|
||||
|
@ -57,6 +57,7 @@ var
|
||||
i: integer;
|
||||
begin
|
||||
d.l := len;
|
||||
d.n := '';
|
||||
setlength(d.p, len);
|
||||
setlength(d.c, len);
|
||||
setlength(d.t, len);
|
||||
@ -78,10 +79,13 @@ var
|
||||
i : integer;
|
||||
begin;
|
||||
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]));
|
||||
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]));
|
||||
end;
|
||||
|
||||
Function pDTMToTDTM(Const DTM: pDTM): TDTM;
|
||||
|
||||
Var
|
||||
|
@ -1654,16 +1654,9 @@ begin
|
||||
// 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.
|
||||
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);
|
||||
//writeln(format('w,h: %d, %d', [w,h]));
|
||||
|
||||
@ -1728,24 +1721,3 @@ begin
|
||||
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;
|
||||
p: TPointArray;
|
||||
c, t, asz, ash: TIntegerArray;
|
||||
n: String; // DOEN
|
||||
end;
|
||||
|
||||
{ Other DTM Types }
|
||||
|
@ -83,9 +83,10 @@ begin
|
||||
result := true;
|
||||
OCRPath := path + DS;
|
||||
if DirectoryExists(path + DS + 'UpChars' + DS) then
|
||||
OCRData[0] := InitOCR(path + DS + 'UpChars' + DS)
|
||||
OCRData[0] := ocrutil.InitOCR(path + DS + 'UpChars' + DS)
|
||||
else
|
||||
result := false;
|
||||
|
||||
end;
|
||||
|
||||
function TMOCR.GetUpTextAt(atX, atY: integer): string;
|
||||
|
Loading…
Reference in New Issue
Block a user