58
57
{ TStrings and TStringList implementations }
62
60
{ TThread implementation }
64
{ system dependend code }
67
62
{ system independend threading code }
69
64
{ event that happens when gui thread is done executing the method}
79
74
{ caught exception in gui thread, to be raised in calling thread }
80
75
SynchronizeException: Exception;
82
procedure TThread.Synchronize(Method: TThreadMethod);
78
function ThreadProc(ThreadObjPtr: Pointer): PtrInt;
81
Thread: TThread absolute ThreadObjPtr;
86
Thread.FFatalException := TObject(AcquireExceptionObject);
88
FreeThread := Thread.FFreeOnTerminate;
89
Result := Thread.FReturnValue;
90
Thread.FFinished := True;
97
{ system dependend code }
100
class procedure TThread.Synchronize(AThread: TThread; AMethod: TThreadMethod);
84
102
LocalSyncException: Exception;
86
104
{ do we really need a synchronized call? }
87
105
if GetCurrentThreadID=MainThreadID then
91
EnterCriticalSection(SynchronizeCritSect);
109
System.EnterCriticalSection(SynchronizeCritSect);
92
110
RtlEventStartWait(ExecuteEvent);
93
111
SynchronizeException:=nil;
94
SynchronizeMethod:=Method;
112
SynchronizeMethod:=AMethod;
96
114
{ be careful, after this assignment Method could be already executed }
97
115
DoSynchronizeMethod:=true;
99
117
RtlEventSetEvent(SynchronizeTimeoutEvent);
101
119
if assigned(WakeMainThread) then
102
WakeMainThread(self);
120
WakeMainThread(AThread);
104
122
{ wait infinitely }
105
123
RtlEventWaitFor(ExecuteEvent);
106
124
LocalSyncException:=SynchronizeException;
107
LeaveCriticalSection(SynchronizeCritSect);
125
System.LeaveCriticalSection(SynchronizeCritSect);
108
126
if assigned(LocalSyncException) then
109
127
raise LocalSyncException;
132
procedure TThread.Synchronize(AMethod: TThreadMethod);
134
TThread.Synchronize(self,AMethod);
114
138
procedure CheckSynchronize(timeout : longint=0);
115
139
{ assumes being called from GUI thread }
118
if GetCurrentThreadID<>MainThreadID then
141
{ first sanity check }
142
if Not IsMultiThread then
144
{ second sanity check }
145
else if GetCurrentThreadID<>MainThreadID then
119
146
raise EThread.CreateFmt(SCheckSynchronizeError,[GetCurrentThreadID])
162
187
{ Interface related stuff }
167
190
{**********************************************************************
168
191
* Miscellaneous procedures and functions *
169
192
**********************************************************************}
194
function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer;
204
if Not (Assigned(Content) and (Content^<>#0)) then
209
WhiteSpace:=WhiteSpace+[#10,#13];
210
Separators:=Separators+[#0,#10,#13,'''','"'];
211
if Assigned(Strings) then
215
while P^ in WhiteSpace do
216
Inc(P); // Not MBCS safe
220
while (InQuote and not (P^ in [QC, #0])) or
221
not (P^ in Separators) do
222
Inc(P); // Not MBCS safe
223
if P^ in ['''', '"'] then
237
if Assigned(Strings) then
239
SetString(S,Start,P-Start);
248
if Assigned(Strings) then
171
255
{ Point and rectangle constructors }
173
257
function Point(AX, AY: Integer): TPoint;
305
function PointsEqual(const P1, P2: TPoint): Boolean; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE}
307
{ lazy, but should work }
308
result:=QWord(P1)=QWord(P2);
312
function PointsEqual(const P1, P2: TSmallPoint): Boolean; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE}
314
{ lazy, but should work }
315
result:=DWord(P1)=DWord(P2);
318
function InvalidPoint(X, Y: Integer): Boolean;
320
result:=(X=-1) and (Y=-1);
324
function InvalidPoint(const At: TPoint): Boolean;
326
result:=(At.x=-1) and (At.y=-1);
330
function InvalidPoint(const At: TSmallPoint): Boolean;
332
result:=(At.x=-1) and (At.y=-1);
224
336
{ Object filing routines }
376
487
procedure RegisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent);
378
if not(assigned(FindGlobalComponentList)) then
379
FindGlobalComponentList:=TList.Create;
380
if FindGlobalComponentList.IndexOf(Pointer(AFindGlobalComponent))<0 then
381
FindGlobalComponentList.Add(Pointer(AFindGlobalComponent));
489
if not(assigned(FindGlobalComponentList)) then
490
FindGlobalComponentList:=TList.Create;
491
if FindGlobalComponentList.IndexOf(Pointer(AFindGlobalComponent))<0 then
492
FindGlobalComponentList.Add(Pointer(AFindGlobalComponent));
385
496
procedure UnregisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent);
387
if assigned(FindGlobalComponentList) then
388
FindGlobalComponentList.Remove(Pointer(AFindGlobalComponent));
498
if assigned(FindGlobalComponentList) then
499
FindGlobalComponentList.Remove(Pointer(AFindGlobalComponent));
396
FindGlobalComponent:=nil;
397
if assigned(FindGlobalComponentList) then
507
FindGlobalComponent:=nil;
508
if assigned(FindGlobalComponentList) then
399
510
for i:=FindGlobalComponentList.Count-1 downto 0 do
409
520
procedure RegisterInitComponentHandler(ComponentClass: TComponentClass; Handler: TInitComponentHandler);
416
525
If (InitHandlerList=Nil) then
417
526
InitHandlerList:=TList.Create;
418
527
H:=TInitHandler.Create;
419
528
H.Aclass:=ComponentClass;
420
529
H.AHandler:=Handler;
421
With InitHandlerList do
531
With InitHandlerList do
534
While (I<Count) and not H.AClass.InheritsFrom(TInitHandler(Items[I]).AClass) do
537
if (I<Count) and (TInitHandler(Items[I]).AClass=H.AClass) then
539
TInitHandler(Items[I]).AHandler:=Handler;
543
InitHandlerList.Insert(I,H);
552
{ all targets should at least include the sysres.inc dummy in the system unit to compile this }
553
function CreateComponentfromRes(const res : string;Inst : THandle;var Component : TComponent) : Boolean;
555
ResStream : TResourceStream;
563
ResStream:=TResourceStream.Create(Inst,res,RT_RCDATA);
565
Component:=ResStream.ReadComponent(Component);
576
function DefaultInitHandler(Instance: TComponent; RootAncestor: TClass): Boolean;
578
function doinit(_class : TClass) : boolean;
424
While (I<Count) and not H.AClass.InheritsFrom(TInitHandler(Items[i]).AClass) do
426
InitHandlerList.Insert(I,H);
581
if (_class.ClassType=TComponent) or (_class.ClassType=RootAncestor) then
583
result:=doinit(_class.ClassParent);
584
result:=CreateComponentfromRes(_class.ClassName,0,Instance) or result;
588
GlobalNameSpace.BeginWrite;
590
result:=doinit(Instance.ClassType);
592
GlobalNameSpace.EndWrite;
430
597
function InitInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;
437
602
if not Assigned(InitHandlerList) then begin
531
696
if Assigned(Root) then
533
698
Reference := FindNestedComponent(Root, FName);
534
SetOrdProp(FInstance, FPropInfo, Longint(Reference));
699
SetOrdProp(FInstance, FPropInfo, PtrInt(Reference));
536
701
// Move component to list of done components, if necessary
537
702
if (DoneList.IndexOf(FInstance) < 0) and
778
941
CollectionsEqual:=false;
944
function CollectionsEqual(C1, C2: TCollection; Owner1, Owner2: TComponent): Boolean;
946
procedure stream_collection(s : tstream;c : tcollection;o : tcomponent);
950
w:=twriter.create(s,4096);
954
w.writecollection(c);
961
s1,s2 : tmemorystream;
964
if (c1.classtype<>c2.classtype) or
965
(c1.count<>c2.count) then
968
s1:=tmemorystream.create;
970
s2:=tmemorystream.create;
972
stream_collection(s1,c1,owner1);
973
stream_collection(s2,c2,owner2);
974
result:=(s1.size=s2.size) and (CompareChar(s1.memory,s2.memory,s1.size)=0);
783
984
{ Object conversion routines }
1128
1328
Output.Write(s[1], Length(s));
1131
{$ifdef HASWIDESTRING}
1132
1331
procedure WriteWString(Const s: WideString);
1134
1333
Output.WriteDWord(Length(s));
1135
1334
if Length(s) > 0 then
1136
1335
Output.Write(s[1], Length(s)*sizeof(widechar));
1138
{$endif HASWIDESTRING}
1140
1338
procedure WriteInteger(value: LongInt);
1201
1394
WriteWString(ws);
1204
{$else HASWIDESTRING}
1205
ws := parser.TokenString;
1206
while parser.NextToken = '+' do
1208
parser.NextToken; // Get next string fragment
1209
parser.CheckToken(toString);
1210
ws := ws + parser.TokenString;
1212
{$endif HASWIDESTRING}
1214
1398
setlength(s,length(ws));
1215
1399
for i:= 1 to length(s) do begin
1460
1644
procedure CommonInit;
1463
1646
InitCriticalSection(SynchronizeCritSect);
1464
1647
ExecuteEvent:=RtlEventCreate;
1465
1648
SynchronizeTimeoutEvent:=RtlEventCreate;
1466
1649
DoSynchronizeMethod:=false;
1467
1650
MainThreadID:=GetCurrentThreadID;
1469
1651
InitHandlerList:=Nil;
1470
1652
FindGlobalComponentList:=nil;
1471
1653
IntConstList := TThreadList.Create;
1472
1654
GlobalFixupList := TThreadList.Create;
1473
1655
ClassList := TThreadList.Create;
1474
1656
ClassAliasList := TStringList.Create;
1657
{ on unix this maps to a simple rw synchornizer }
1658
GlobalNameSpace := TMultiReadExclusiveWriteSynchronizer.Create;
1659
RegisterInitComponentHandler(TComponent,@DefaultInitHandler);
1477
1662
procedure CommonCleanup;
1481
// !!!: GlobalNameSpace.BeginWrite;
1666
GlobalNameSpace.BeginWrite;
1482
1667
with IntConstList.LockList do
1484
1669
for i := 0 to Count - 1 do
1494
1679
GlobalFixupList := nil;
1495
1680
GlobalLists.Free;
1496
1681
ComponentPages.Free;
1497
{!!!: GlobalNameSpace.Free;
1498
GlobalNameSpace := nil;}
1683
{ GlobalNameSpace is an interface so this is enough }
1684
GlobalNameSpace:=nil;
1499
1686
if (InitHandlerList<>Nil) then
1500
1687
for i := 0 to InitHandlerList.Count - 1 do
1501
1688
TInitHandler(InitHandlerList.Items[I]).Free;
1503
1690
InitHandlerList:=Nil;
1504
1691
FindGlobalComponentList.Free;
1505
1692
FindGlobalComponentList:=nil;
1507
1693
DoneCriticalSection(SynchronizeCritSect);
1508
1694
RtlEventDestroy(ExecuteEvent);
1509
1695
RtlEventDestroy(SynchronizeTimeoutEvent);
1513
1698
{ TFiler implementation }
1521
1706
{$i twriter.inc}
1525
$Log: classes.inc,v $
1526
Revision 1.27 2005/04/28 09:15:44 florian
1527
+ variants: string -> float/int casts
1529
Revision 1.26 2005/04/13 16:16:43 peter
1530
use createfmt instead of createresfmt
1532
Revision 1.25 2005/04/09 17:26:08 florian
1533
+ classes.mainthreadid is set now
1534
+ rtleventresetevent
1535
+ rtleventwairfor with timeout
1536
+ checksynchronize with timeout
1537
* race condition in synchronize fixed
1539
Revision 1.24 2005/03/25 22:53:39 jonas
1540
* fixed several warnings and notes about unused variables (mainly) or
1541
uninitialised use of variables/function results (a few)
1543
Revision 1.23 2005/03/13 10:07:01 florian
1544
* another utf-8 patch by C. Western
1546
Revision 1.22 2005/03/09 20:50:11 florian
1547
* C. Western: utf-8 reading from resource files
1549
Revision 1.21 2005/03/07 19:55:13 florian
1550
* C Western: component searching in FindGlobalComponent is now done backwards
1552
Revision 1.20 2005/03/07 17:57:25 peter
1553
* renamed rtlconst to rtlconsts
1555
Revision 1.19 2005/03/07 16:35:19 peter
1556
* Object text format of widestrings patch from Martin Schreiber
1558
Revision 1.18 2005/02/25 23:02:05 florian
1559
+ implemented D7 compliant FindGlobalComponents
1561
Revision 1.17 2005/02/25 22:10:27 florian
1562
* final fix for linux (hopefully)
1564
Revision 1.16 2005/02/25 22:02:48 florian
1565
* another "transfer to linux"-commit
1567
Revision 1.15 2005/02/25 21:52:07 florian
1568
* "transfer to linux"-commit
1570
Revision 1.14 2005/02/25 21:41:09 florian
1571
* generic tthread.synchronize
1572
* delphi compatible wakemainthread
1574
Revision 1.13 2005/02/14 17:13:31 peter
1577
Revision 1.12 2005/02/14 16:47:37 peter
1580
Revision 1.11 2005/02/06 11:20:52 peter
1581
* threading in system unit
1582
* removed systhrds unit
1584
Revision 1.10 2005/01/22 20:53:02 michael
1585
+ Patch from Colin Western to fix reading inherited forms