diff --git a/Source/Simba.lpi b/Source/Simba.lpi
index a6ce69da9..cf61ae250 100644
--- a/Source/Simba.lpi
+++ b/Source/Simba.lpi
@@ -340,7 +340,7 @@
-
+
@@ -1006,6 +1006,10 @@
+
+
+
+
diff --git a/Source/matchtemplate/simba.matchtemplate_helpers.pas b/Source/matchtemplate/simba.matchtemplate_helpers.pas
index 3744906be..604168ec5 100644
--- a/Source/matchtemplate/simba.matchtemplate_helpers.pas
+++ b/Source/matchtemplate/simba.matchtemplate_helpers.pas
@@ -41,7 +41,7 @@ function DoFFT2(const Matrix: TSingleMatrix; const outW, outH: Integer): TComple
H := Matrix.Height - 1;
for Y := 0 to H do
for X := 0 to W do
- Spec[Y, X].Re := Matrix[Y, X]; // WTF!!
+ Spec[Y, X].Re := Matrix[Y, X];
Result := FFTPACK.FFT2(Spec);
end;
diff --git a/Source/matchtemplate/simba.matchtemplate_matrix.pas b/Source/matchtemplate/simba.matchtemplate_matrix.pas
index 30d4789ed..42dfa5133 100644
--- a/Source/matchtemplate/simba.matchtemplate_matrix.pas
+++ b/Source/matchtemplate/simba.matchtemplate_matrix.pas
@@ -26,6 +26,18 @@ interface
simba.mufasatypes;
type
+ TComplex = record
+ Re, Im: Single;
+ end;
+ TComplexArray = array of TComplex;
+ TComplexMatrix = array of TComplexArray;
+
+ TComplexMatrixHelper = type helper for TComplexMatrix
+ function Width: Integer;
+ function Height: Integer;
+ procedure SetSize(AWidth, AHeight: Integer);
+ end;
+
TRGBComplexMatrix = record
Width: Integer;
Height: Integer;
@@ -417,6 +429,24 @@ function Norm(const Matrix: TRGBMatrix): Double;
Result[Y, X] := Left[Y, X] / Right[Y, X];
end;
+function TComplexMatrixHelper.Width: Integer;
+begin
+ if (Length(Self) > 0) then
+ Result := Length(Self[0])
+ else
+ Result := 0;
+end;
+
+function TComplexMatrixHelper.Height: Integer;
+begin
+ Result := Length(Self);
+end;
+
+procedure TComplexMatrixHelper.SetSize(AWidth, AHeight: Integer);
+begin
+ SetLength(Self, AHeight, AWidth);
+end;
+
procedure TRGBMatrix.SetSize(AWidth, AHeight: Integer);
begin
SetLength(Self.R, AHeight, AWidth);
diff --git a/Source/package/simba.package_autoupdater.pas b/Source/package/simba.package_autoupdater.pas
index 3081342a2..020cd13c0 100644
--- a/Source/package/simba.package_autoupdater.pas
+++ b/Source/package/simba.package_autoupdater.pas
@@ -18,7 +18,7 @@ implementation
uses
simba.mufasatypes, simba.package, simba.package_installer,
- simba.main, simba.outputform, simba.package_menubuilder;
+ simba.main, simba.outputform, simba.package_menubuilder, simba.threading;
type
TPackageUpdater = class(TThread)
@@ -35,7 +35,7 @@ TPackageUpdater = class(TThread)
procedure TPackageUpdater.DoTerminateOnMainThread(Sender: TObject);
begin
- AssertMainThread('TPackageUpdater');
+ CheckMainThread('TPackageUpdater');
// Update main menu
BuildPackageMenus(FPackages, SimbaForm.MenuBar);
diff --git a/Source/script/imports/simba/simba.import_quad.pas b/Source/script/imports/simba/simba.import_quad.pas
index fbbc6cba5..be9c8f89b 100644
--- a/Source/script/imports/simba/simba.import_quad.pas
+++ b/Source/script/imports/simba/simba.import_quad.pas
@@ -18,7 +18,8 @@ procedure ImportQuad(Compiler: TSimbaScript_Compiler);
implementation
uses
- lptypes;
+ lptypes,
+ simba.quad;
(*
TQuad
diff --git a/Source/simba.atpa.pas b/Source/simba.atpa.pas
index 767863a20..e58b33705 100644
--- a/Source/simba.atpa.pas
+++ b/Source/simba.atpa.pas
@@ -5,16 +5,13 @@
}
unit simba.atpa;
+{$DEFINE SIMBA_MAX_OPTIMIZATION}
{$i simba.inc}
-{$IFOPT D-}
- {$OPTIMIZATION LEVEL4}
-{$ENDIF}
-
interface
uses
- Classes, SysUtils,
+ Classes, SysUtils, Math,
simba.mufasatypes;
type
@@ -66,8 +63,7 @@ interface
implementation
uses
- math,
- simba.tpa, simba.algo_sort, simba.overallocatearray, simba.integermatrix;
+ simba.tpa, simba.algo_sort, simba.overallocatearray, simba.integermatrix, simba.quad;
function T2DPointArrayHelper.Sort(Weights: TIntegerArray; LowToHigh: Boolean): T2DPointArray;
var
diff --git a/Source/simba.circle.pas b/Source/simba.circle.pas
index fa471f37e..16efa7320 100644
--- a/Source/simba.circle.pas
+++ b/Source/simba.circle.pas
@@ -14,15 +14,6 @@ interface
simba.mufasatypes;
type
- PCircle = ^TCircle;
- TCircle = record
- X: Integer;
- Y: Integer;
- Radius: Integer;
- end;
- PCircleArray = ^TCircleArray;
- TCircleArray = array of TCircle;
-
TCircleHelper = type helper for TCircle
public const
ZERO: TCircle = (X: 0; Y: 0; Radius: 0);
diff --git a/Source/simba.image.pas b/Source/simba.image.pas
index b6d63a56a..d4cd7bfea 100644
--- a/Source/simba.image.pas
+++ b/Source/simba.image.pas
@@ -14,7 +14,7 @@ interface
Classes, SysUtils, Graphics,
simba.baseclass, simba.mufasatypes, simba.image_textdrawer,
simba.colormath, simba.colormath_distance, simba.matchtemplate,
- simba.circle;
+ simba.circle, simba.quad;
type
{$PUSH}
diff --git a/Source/simba.mufasatypes.pas b/Source/simba.mufasatypes.pas
index 6e733b830..1f260a708 100644
--- a/Source/simba.mufasatypes.pas
+++ b/Source/simba.mufasatypes.pas
@@ -10,7 +10,8 @@
interface
uses
- Classes, SysUtils, Graphics, fpjson;
+ Classes, SysUtils, Graphics,
+ fpjson;
{$PUSH}
{$SCOPEDENUMS ON}
@@ -316,24 +317,32 @@ TBox = record
PBoxArray = ^TBoxArray;
TBoxArray = array of TBox;
- TComplex = record
- Re, Im: Single;
+ PQuad = ^TQuad;
+ TQuad = record
+ Top: TPoint;
+ Right: TPoint;
+ Bottom: TPoint;
+ Left: TPoint;
end;
- TComplexArray = array of TComplex;
- TComplexMatrix = array of TComplexArray;
+ TQuadArray = array of TQuad;
+ PQuadArray = ^TQuadArray;
+
+ PCircle = ^TCircle;
+ TCircle = record
+ X: Integer;
+ Y: Integer;
+ Radius: Integer;
+ end;
+ PCircleArray = ^TCircleArray;
+ TCircleArray = array of TCircle;
{$DEFINE HEADER}
{$i generics.inc}
- {$i quad.inc}
{$i box.inc}
{$i boxarray.inc}
{$i point.inc}
{$i string.inc}
- {$DEFINE MACRO_HELPER_NAME := TComplexMatrixBaseHelper}
- {$DEFINE MACRO_MATRIX_NAME := TComplexMatrix}
- {$i matrix.inc}
-
{$DEFINE MACRO_HELPER_NAME := TByteMatrixBaseHelper}
{$DEFINE MACRO_MATRIX_NAME := TByteMatrix}
{$i matrix.inc}
@@ -408,8 +417,6 @@ ESimbaException = class(Exception);
procedure SimbaException(Message: String; Args: array of const); overload;
procedure SimbaException(Message: String); overload;
-procedure AssertMainThread(const Method: String);
-
// Writable const
const
SimbaProcessType: ESimbaProcessType = ESimbaProcessType.UNKNOWN;
@@ -419,20 +426,15 @@ implementation
uses
math, forms, uregexpr, strutils, jsonparser, jsonscanner,
simba.math, simba.overallocatearray, simba.geometry,
- simba.algo_sort, simba.tpa, simba.random;
+ simba.algo_sort, simba.random;
{$DEFINE BODY}
{$i generics.inc}
- {$i quad.inc}
{$i box.inc}
{$i boxarray.inc}
{$i point.inc}
{$i string.inc}
- {$DEFINE MACRO_HELPER_NAME := TComplexMatrixBaseHelper}
- {$DEFINE MACRO_MATRIX_NAME := TComplexMatrix}
- {$i matrix.inc}
-
{$DEFINE MACRO_HELPER_NAME := TByteMatrixBaseHelper}
{$DEFINE MACRO_MATRIX_NAME := TByteMatrix}
{$i matrix.inc}
@@ -495,12 +497,6 @@ procedure SimbaException(Message: String);
raise ESimbaException.Create(Message);
end;
-procedure AssertMainThread(const Method: String);
-begin
- if (GetCurrentThreadID() <> MainThreadID) then
- SimbaException('Not called on main thread: ' + Method);
-end;
-
procedure SimbaDebugLn(const Msg: String);
begin
DebugLn(Msg);
diff --git a/Source/quad.inc b/Source/simba.quad.pas
similarity index 78%
rename from Source/quad.inc
rename to Source/simba.quad.pas
index bd8ca6252..c128da766 100644
--- a/Source/quad.inc
+++ b/Source/simba.quad.pas
@@ -1,23 +1,26 @@
{
- TQuad is TRectangle from SRL.
- Author: Jarl Holta - https://github.com/slackydev
+ Author: Raymond van Venetiƫ and Merlijn Wajer
+ Project: Simba (https://github.com/MerlijnWajer/Simba)
+ License: GNU General Public License (https://www.gnu.org/licenses/gpl-3.0)
}
+unit simba.quad;
-{%MAINUNIT simba.mufasatypes}
+{$i simba.inc}
-{$IFDEF HEADER}
- type
- PQuad = ^TQuad;
- TQuad = record
- Top: TPoint;
- Right: TPoint;
- Bottom: TPoint;
- Left: TPoint;
+interface
+uses
+ Classes, SysUtils,
+ simba.mufasatypes;
+
+type
+ TQuadHelper = type helper for TQuad
+ const
+ EMPTY: TQuad = (Top: (X:0; Y:0); Right: (X:0; Y:0); Bottom: (X:0; Y:0); Left: (X:0; Y:0));
+ public
class function Create(ATop, ARight, ABottom, ALeft: TPoint): TQuad; static; overload;
class function CreateFromBox(Box: TBox): TQuad; static; overload;
class function CreateFromPoints(Points: TPointArray): TQuad; static; overload;
- class operator in(const P: TPoint; const Quad: TQuad): Boolean;
function RandomPoint: TPoint;
function RandomPointCenter: TPoint;
@@ -39,12 +42,16 @@ TQuad = record
function Area: Integer;
function Normalize: TQuad;
end;
- PQuadArray = ^TQuadArray;
- TQuadArray = array of TQuad;
-{$ENDIF}
-{$IFDEF BODY}
-class function TQuad.Create(ATop, ARight, ABottom, ALeft: TPoint): TQuad;
+ operator in(const P: TPoint; const Quad: TQuad): Boolean;
+
+implementation
+
+uses
+ Math,
+ simba.math, simba.tpa, simba.random, simba.geometry, simba.overallocatearray;
+
+class function TQuadHelper.Create(ATop, ARight, ABottom, ALeft: TPoint): TQuad;
begin
Result.Top := ATop;
Result.Right := ARight;
@@ -52,7 +59,7 @@ class function TQuad.Create(ATop, ARight, ABottom, ALeft: TPoint): TQuad;
Result.Left := ALeft;
end;
-class function TQuad.CreateFromBox(Box: TBox): TQuad;
+class function TQuadHelper.CreateFromBox(Box: TBox): TQuad;
begin
Result.Top := TPoint.Create(Box.X1, Box.Y1);
Result.Right := TPoint.Create(Box.X2, Box.Y1);
@@ -60,17 +67,12 @@ class function TQuad.CreateFromBox(Box: TBox): TQuad;
Result.Left := TPoint.Create(Box.X1, Box.Y2);
end;
-class function TQuad.CreateFromPoints(Points: TPointArray): TQuad;
+class function TQuadHelper.CreateFromPoints(Points: TPointArray): TQuad;
begin
Result := Points.MinAreaRect();
end;
-class operator TQuad.in(const P: TPoint; const Quad: TQuad): Boolean;
-begin
- Result := Quad.Contains(P);
-end;
-
-function TQuad.RandomPoint: TPoint;
+function TQuadHelper.RandomPoint: TPoint;
var
a,x,y,x1,y1,x2,y2: Double;
begin
@@ -90,7 +92,7 @@ function TQuad.RandomPoint: TPoint;
Result := Result.Rotate(a, TPoint.Create(Round(X), Round(Y)));
end;
-function TQuad.RandomPointCenter: TPoint;
+function TQuadHelper.RandomPointCenter: TPoint;
var
a,x,y,x1,y1,x2,y2: Double;
begin
@@ -110,17 +112,17 @@ function TQuad.RandomPointCenter: TPoint;
Result := Result.Rotate(a, TPoint.Create(Round(X), Round(Y)));
end;
-function TQuad.ToTPA: TPointArray;
+function TQuadHelper.ToTPA: TPointArray;
begin
Result := [Top, Right, Bottom, Left];
end;
-function TQuad.Bounds: TBox;
+function TQuadHelper.Bounds: TBox;
begin
Result := ToTPA().Bounds();
end;
-function TQuad.ShortSideLen: Integer;
+function TQuadHelper.ShortSideLen: Integer;
begin
if (Hypot(Left.Y-Top.Y, Left.X-Top.X) < Hypot(Left.Y-Bottom.Y, Left.X-Bottom.X)) then
Result := Round(Hypot(Left.Y-Top.Y, Left.X-Top.X) / 2)
@@ -128,7 +130,7 @@ function TQuad.ShortSideLen: Integer;
Result := Round(Hypot(Left.Y-Bottom.Y, Left.X-Bottom.X) / 2);
end;
-function TQuad.LongSideLen: Integer;
+function TQuadHelper.LongSideLen: Integer;
begin
if (Hypot(Left.Y-Top.Y, Left.X-Top.X) > Hypot(Left.Y-Bottom.Y, Left.X-Bottom.X)) then
Result := Round(Hypot(Left.Y-Top.Y, Left.X-Top.X) / 2)
@@ -136,13 +138,13 @@ function TQuad.LongSideLen: Integer;
Result := Round(Hypot(Left.Y-Bottom.Y, Left.X-Bottom.X) / 2);
end;
-function TQuad.Mean: TPoint;
+function TQuadHelper.Mean: TPoint;
begin
Result.X := (Self.Top.X + Self.Right.X + Self.Bottom.X + Self.Left.X) div 4;
Result.Y := (Self.Top.Y + Self.Right.Y + Self.Bottom.Y + Self.Left.Y) div 4;
end;
-function TQuad.Rotate(Radians: Double): TQuad;
+function TQuadHelper.Rotate(Radians: Double): TQuad;
begin
with Self.Mean() do
begin
@@ -155,27 +157,27 @@ function TQuad.Rotate(Radians: Double): TQuad;
Result := Result.Normalize();
end;
-function TQuad.Contains(P: TPoint): Boolean;
+function TQuadHelper.Contains(P: TPoint): Boolean;
begin
Result := TSimbaGeometry.PointInQuad(P, Self.Top, Self.Right, Self.Bottom, Self.Left);
end;
-function TQuad.Contains(X, Y: Integer): Boolean;
+function TQuadHelper.Contains(X, Y: Integer): Boolean;
begin
Result := TSimbaGeometry.PointInQuad(TPoint.Create(X, Y), Self.Top, Self.Right, Self.Bottom, Self.Left);
end;
-function TQuad.Offset(P: TPoint): TQuad;
+function TQuadHelper.Offset(P: TPoint): TQuad;
begin
Result := TQuad.Create(Top.Offset(P), Right.Offset(P), Bottom.Offset(P), Left.Offset(P));
end;
-function TQuad.Offset(X, Y: Integer): TQuad;
+function TQuadHelper.Offset(X, Y: Integer): TQuad;
begin
Result := TQuad.Create(Top.Offset(X, Y), Right.Offset(X, Y), Bottom.Offset(X, Y), Left.Offset(X, Y));
end;
-function TQuad.Extract(Points: TPointArray): TPointArray;
+function TQuadHelper.Extract(Points: TPointArray): TPointArray;
var
I: Integer;
Buffer: TSimbaPointBuffer;
@@ -188,7 +190,7 @@ function TQuad.Extract(Points: TPointArray): TPointArray;
Result := Buffer.Trim();
end;
-function TQuad.Exclude(Points: TPointArray): TPointArray;
+function TQuadHelper.Exclude(Points: TPointArray): TPointArray;
var
I: Integer;
Buffer: TSimbaPointBuffer;
@@ -201,7 +203,7 @@ function TQuad.Exclude(Points: TPointArray): TPointArray;
Result := Buffer.Trim();
end;
-function TQuad.Expand(Amount: Double): TQuad;
+function TQuadHelper.Expand(Amount: Double): TQuad;
var
InTPA, OutTPA: array[0..3] of TPoint;
Theta: Double;
@@ -224,7 +226,7 @@ function TQuad.Expand(Amount: Double): TQuad;
Result := TQuad.Create(OutTPA[0], OutTPA[1], OutTPA[2], OutTPA[3]);
end;
-function TQuad.NearestEdge(P: TPoint): TPoint;
+function TQuadHelper.NearestEdge(P: TPoint): TPoint;
var
Dists: array[0..3] of Double;
Points: array[0..3] of TPoint;
@@ -247,12 +249,12 @@ function TQuad.NearestEdge(P: TPoint): TPoint;
end;
end;
-function TQuad.Area: Integer;
+function TQuadHelper.Area: Integer;
begin
Result := Round(Distance(Self.Bottom, Self.Right)) * Round(Distance(Self.Bottom, Self.Left));
end;
-function TQuad.Normalize: TQuad;
+function TQuadHelper.Normalize: TQuad;
var
I, T: Integer;
Points: TPointArray;
@@ -268,6 +270,11 @@ function TQuad.Normalize: TQuad;
Result.Bottom := Points[(T + 2) mod 4];
Result.Left := Points[(T + 3) mod 4];
end;
-{$ENDIF}
+operator in(const P: TPoint; const Quad: TQuad): Boolean;
+begin
+ Result := Quad.Contains(P);
+end;
+
+end.
diff --git a/Source/simba.scriptbackup.pas b/Source/simba.scriptbackup.pas
index 096f7eb76..554895110 100644
--- a/Source/simba.scriptbackup.pas
+++ b/Source/simba.scriptbackup.pas
@@ -38,7 +38,7 @@ implementation
uses
crc,
- simba.files, simba.env, simba.ide_initialization, simba.scripttabsform;
+ simba.files, simba.env, simba.ide_initialization, simba.scripttabsform, simba.threading;
function Crc32String(const Str: String): UInt32;
begin
@@ -51,7 +51,7 @@ procedure TSimbaScriptBackup.DoFileCollecting(Sender: TObject);
var
I: Integer;
begin
- AssertMainThread('TSimbaScriptBackup');
+ CheckMainThread('TSimbaScriptBackup');
SetLength(FFiles, SimbaScriptTabsForm.TabCount);
for I := 0 to SimbaScriptTabsForm.TabCount - 1 do
@@ -107,7 +107,7 @@ constructor TSimbaScriptBackup.Create(AOwner: TComponent);
procedure SetupScriptBackup;
begin
- AssertMainThread('SetupScriptBackup');
+ CheckMainThread('SetupScriptBackup');
TSimbaScriptBackup.Create(SimbaScriptTabsForm);
end;
diff --git a/Source/simba.scriptinstance.pas b/Source/simba.scriptinstance.pas
index ae3173caa..5034d54fb 100644
--- a/Source/simba.scriptinstance.pas
+++ b/Source/simba.scriptinstance.pas
@@ -124,7 +124,7 @@ procedure TSimbaScriptInstance.DoOutputThreadTerminated(Sender: TObject);
var
ScriptTab: TSimbaScriptTab;
begin
- AssertMainThread('TSimbaScriptInstance.DoOutputThreadTerminated');
+ CheckMainThread('TSimbaScriptInstance.DoOutputThreadTerminated');
if FProcess.Running then
FProcess.Terminate(EXIT_CODE_FORCE_STOP);
diff --git a/Source/simba.threading.pas b/Source/simba.threading.pas
index 77cae96f0..770372643 100644
--- a/Source/simba.threading.pas
+++ b/Source/simba.threading.pas
@@ -19,6 +19,7 @@ interface
// TThreadMethod = procedure of object;
function IsMainThread: Boolean;
+procedure CheckMainThread(const Method: String);
procedure QueueOnMainThread(Proc: TThreadProc); overload;
procedure QueueOnMainThread(Method: TThreadMethod); overload;
@@ -32,6 +33,17 @@ function RunInThread(NestedMethod: TThreadNestedProc; FreeOnTerminate: Boolean =
implementation
+function IsMainThread: Boolean;
+begin
+ Result := GetCurrentThreadID() = MainThreadID;
+end;
+
+procedure CheckMainThread(const Method: String);
+begin
+ if (not IsMainThread()) then
+ SimbaException('Not called on main thread: ' + Method);
+end;
+
type
TSyncObject = object
Proc: TThreadProc;
@@ -53,11 +65,6 @@ procedure TSyncObject.Execute;
end;
end;
-function IsMainThread: Boolean;
-begin
- Result := GetCurrentThreadID() = MainThreadID;
-end;
-
type
TThreaded = class(TThread)
protected
diff --git a/Source/simba.tpa.pas b/Source/simba.tpa.pas
index 915fdde3e..5ac873c51 100644
--- a/Source/simba.tpa.pas
+++ b/Source/simba.tpa.pas
@@ -37,7 +37,7 @@ interface
uses
Classes, SysUtils,
- simba.mufasatypes, simba.circle;
+ simba.mufasatypes, simba.quad, simba.circle;
type
TPointArrayHelper = type helper for TPointArray
diff --git a/Third-Party/lape b/Third-Party/lape
index 738505266..e521c2886 160000
--- a/Third-Party/lape
+++ b/Third-Party/lape
@@ -1 +1 @@
-Subproject commit 738505266982d3e661d6ec6177d26c5a73facbe1
+Subproject commit e521c28866a1307e02ac1155daeebd2acacdc456