-
Content Count
2268 -
Joined
-
Last visited
-
Days Won
46
Everything posted by Fr0sT.Brutal
-
The Delphi Parser - FIBPlus, BDE, legacy Migration
Fr0sT.Brutal replied to Jasonjac2's topic in Delphi Third-Party
I've no idea what Delphi Parser is but AFAIK FIBPlus are available in more or less recent version. IBX is included in Delphi RTL so almost no need to change. BDE is of course dead. Anyway as you're migrating from D7 the most serious problem you'll likely have is Ansi=>Unicode transfer. After that all other changes will look like piece a cake. -
Enums and generics
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
// *************************************************************************** // Static class to convert enum value <=> enum name // *************************************************************************** TEnum<T> = class strict private class var FPTypInf: PTypeInfo; FMin, FMax: Integer; {$IFDEF CAPS_CLASSCONSTROK} class constructor Create; {$ELSE} class procedure Init; {$ENDIF} class procedure CheckRange(Item: Integer); inline; public // T => Int class function Int(Item: T): Integer; overload; inline; // Str => Int class function Int(const Name: string): Integer; overload; inline; // Int => T class function Val(Item: Integer; CheckRange: Boolean = True): T; overload; inline; // Str => T class function Val(const Name: string): T; overload; inline; // T => Str class function Str(Item: T): string; overload; inline; // Int => Str class function Str(Item: Integer): string; overload; // Search for Item in Values array and return its index as T class function Find(const Item: string; const Values: array of string): T; overload; class function Find(const Item: Char; const Values: array of Char): T; overload; class property Min: Integer read FMin; class property Max: Integer read FMax; end; {$REGION 'TEnum<T>'} {$IFDEF TYPES_GENERICS} {$IFDEF CAPS_CLASSCONSTROK} // Perform some checks and save type properties. // Executed on unit init if the class is used, raises exception if type is invalid. class constructor TEnum<T>.Create; {$ELSE} class procedure TEnum<T>.Init; {$ENDIF} begin FPTypInf := PTypeInfo(TypeInfo(T)); // type info check if FPTypInf = nil then raise Err(S_E_NoTypeInfo); // run-time type check if FPTypInf.Kind <> tkEnumeration then raise Err(S_EEnum_NotAnEnum, [FPTypInf.Name]); // get range FMin := GetTypeData(FPTypInf).MinValue; FMax := GetTypeData(FPTypInf).MaxValue; end; // Check if Item in enum range class procedure TEnum<T>.CheckRange(Item: Integer); begin if (Item < FMin) or (Item > FMax) then raise Err(S_EEnum_NotInRange, [Item, FMin, FMax, FPTypInf.Name]); end; // Integer => Enum member, the same as Integer(T) // CheckRange: controls whether checking if Item belongs Low(T)..High(T) will // be performed. Useful to return T(-1) as invalid value. class function TEnum<T>.Val(Item: Integer; CheckRange: Boolean): T; var p: Pointer; begin {$IFNDEF CAPS_CLASSCONSTROK} if FPTypInf = nil then Init; {$ENDIF} if CheckRange then Self.CheckRange(Item); p := @Result; case SizeOf(T) of 1: PUInt8(p)^ := UInt8(Item); 2: PUInt16(p)^ := UInt16(Item); else raise Err(S_EEnum_WrongSize, [SizeOf(T)]); end; end; // Enum member => Integer, the same as T(Int) class function TEnum<T>.Int(Item: T): Integer; var p: Pointer; begin p := @Item; case SizeOf(T) of 1: Result := PUInt8(p)^ ; 2: Result := PUInt16(p)^; else raise Err(S_EEnum_WrongSize, [SizeOf(T)]); end; end; // Integer => String class function TEnum<T>.Str(Item: Integer): string; begin {$IFNDEF CAPS_CLASSCONSTROK} if FPTypInf = nil then Init; {$ENDIF} CheckRange(Item); Result := GetEnumName(FPTypInf, Item); end; // T => String class function TEnum<T>.Str(Item: T): string; begin Result := Str(Int(Item)); end; // String => Integer class function TEnum<T>.Int(const Name: string): Integer; begin {$IFNDEF CAPS_CLASSCONSTROK} if FPTypInf = nil then Init; {$ENDIF} Result := GetEnumValue(FPTypInf, Name); if Result = -1 then raise Err(S_EEnum_NoValueForName, [Name, FPTypInf.Name]); end; // String => T class function TEnum<T>.Val(const Name: string): T; begin Result := Val(Int(Name)); end; // Find string representation in array of strings and return T // Similar to Val(Str) but Text and Values could be arbitrary. // Returns T(-1) if Text not found class function TEnum<T>.Find(const Item: string; const Values: array of string): T; begin Result := Val(FindStr(Item, Values), False); // Turn off range check to return -1 end; // The same but for Chars class function TEnum<T>.Find(const Item: Char; const Values: array of Char): T; begin Result := Val(FindChar(Item, Values), False); // Turn off range check to return -1 end; {$ENDIF} {$ENDREGION} // usage TEnum<TSomeEnum>.Str(seFirst) => 'seFirst' TEnum<TSomeEnum>.Val('seFirst') => seFirst TEnum<TSomeEnum>.Find('First', ['Fisrt', 'Second']) => seFirst Just note that only "naturally numbered" enums have type info (if any of elements has explicit index assignment, no type info is generated) -
The Delphi Parser - FIBPlus, BDE, legacy Migration
Fr0sT.Brutal replied to Jasonjac2's topic in Delphi Third-Party
I didn't understood a thing -
I use "Resource editor 2.2.0.6c KetilO © 2010" just for dialog resources because this app has very convenient feature of generating an include file for all cnotrol IDs in the dialog so I just $I it in my code
-
Can I use dynamically linked MPL 2.0 dll library for commercial purposes?
Fr0sT.Brutal replied to at3s's topic in General Help
AFAIK even the strictest GPL allows dynamic linking without the burden of opening your code No, GPL is more severe than I thought -
Generic circular buffer library released
Fr0sT.Brutal replied to TurboMagic's topic in Algorithms, Data Structures and Class Design
You can try PasDoc -
Because of its async nature, reading from TWSocket is somewhat more complex than "while Read > 0 do". Just check provided demos for the sample
-
Invalid Compiler Directive: 'MESSAGES'
Fr0sT.Brutal replied to Incus J's topic in ICS - Internet Component Suite
Things got much easier since then, I recently successfully compiled my DLL on Linux with Rio. Almost no command line, just copy PAServer and launch it. Emba even has Docker image with PAServer for those who are familiar with it -
Boolean short-circuit with function calls
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
The whole point of this thread is to get all functions executed. -
Boolean short-circuit with function calls
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Hmm, I would rather consider it as bug -
Boolean short-circuit with function calls
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Okay you're right Sure. Just a little redundant code to make all blocks similar. -
Invalid Compiler Directive: 'MESSAGES'
Fr0sT.Brutal replied to Incus J's topic in ICS - Internet Component Suite
Btw, most of non-Windows code could be checked for buildability with Linux target (unless it's Mac-specific of course). This will require only a running instance of any Linux. -
How to extend/add helpers to for record function?
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Side note: in general, empty string <> 0 number. Using this helper for all attributes you can ignore invalid input which could be sometimes undesirable -
Boolean short-circuit with function calls
Fr0sT.Brutal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
With boolean short circuit you probably won't get B and C executed if A returns True. I doubt that order of execution in a condition is specified, optimizer could swap them. Moreover, do you really intend to return true if just some of the functions return true? My option: res := A; Result := Result or res; ... -
PyScripter reached 1 million downloads from Sourceforge
Fr0sT.Brutal replied to pyscripter's topic in I made this
Btw, GitHub offers binary downloads as well. -
August 2020 GM Blog post
Fr0sT.Brutal replied to Darian Miller's topic in Tips / Blogs / Tutorials / Videos
Am I the one wondering WTH Bold is? -
Is interposer class really best to customize TPanel.Paint?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
Ow. Sir, with all the respect, that was too pathetic. I wasn't trying to convince you to change your workflow. There's a conversation on the thread's subject, right? So, just like you, I was just telling my experience. -
While Not _thread.Finished Do Application.ProcessMessages;
Fr0sT.Brutal replied to aehimself's topic in VCL
Surely I understand; but you have to guarantee that data used by bg task won't be modified by actions from UI, regardless of the architecture you use (threads with events or threads with ProcessMsgs). -
If $I has a path (including relative), it is used based from the file containing $I directive. If $I has no path, default Search paths are used.
-
Why not? It's just a wrapper, no magic AFAIU
-
Is interposer class really best to customize TPanel.Paint?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
You need to add paths to sources for all installed packages, otherwise many useful things won't work. -
Is interposer class really best to customize TPanel.Paint?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
Right but you forget source paths. I guess you generate it again every time a new IDE version is out with corresponding packages? Still some piece of work. Anyway project groups are nice and helpful. -
While Not _thread.Finished Do Application.ProcessMessages;
Fr0sT.Brutal replied to aehimself's topic in VCL
Two controversial sentences, as for me. If UI is responsible, user can do some actions. If logic depends on receiving the control back, user is not supposed to do things that could change app's state while bg operation is running. So I guess the easiest workaround would be to block any actions from UI that could interfere with bg task (you should do it anyway even if bg task won't use App.ProcMsgs). Like with shared variables, app's state must be isolated from simultaneous change. -
Why should I use good source control versioning system?
Fr0sT.Brutal replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Well, that cases were my mistakes. Unmarked heads disappear from history when checking out another branch. Will other VCS allow to recover from this situation? Of course Git is too brutal sometimes, just like any serious *nix tool. But it does its best to warn you when you're about to shoot yourself in the leg 😄 -
Is interposer class really best to customize TPanel.Paint?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
I meant source code, of course. Reinstalling all the custom components for a fresh IDE is still a pain. It's a matter of taste; I, for example, dislike excess components on a form so I create and use them in run-time where possible. With interposer you have separate single unit with clean code which is reused easier than easily 😉