Jump to content

Fr0sT.Brutal

Members
  • Content Count

    2268
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Fr0sT.Brutal

  1. Fr0sT.Brutal

    The Delphi Parser - FIBPlus, BDE, legacy Migration

    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.
  2. Fr0sT.Brutal

    Enums and generics

    // *************************************************************************** // 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)
  3. Fr0sT.Brutal

    The Delphi Parser - FIBPlus, BDE, legacy Migration

    I didn't understood a thing
  4. Fr0sT.Brutal

    Free Resource Builder Utility?

    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
  5. AFAIK even the strictest GPL allows dynamic linking without the burden of opening your code No, GPL is more severe than I thought
  6. Fr0sT.Brutal

    Twsocket Tcp Client miss some packets

    Because of its async nature, reading from TWSocket is somewhat more complex than "while Read > 0 do". Just check provided demos for the sample
  7. 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
  8. The whole point of this thread is to get all functions executed.
  9. Hmm, I would rather consider it as bug
  10. Okay you're right Sure. Just a little redundant code to make all blocks similar.
  11. 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.
  12. Side note: in general, empty string <> 0 number. Using this helper for all attributes you can ignore invalid input which could be sometimes undesirable
  13. 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; ...
  14. Fr0sT.Brutal

    PyScripter reached 1 million downloads from Sourceforge

    Btw, GitHub offers binary downloads as well.
  15. Fr0sT.Brutal

    August 2020 GM Blog post

    Am I the one wondering WTH Bold is?
  16. Fr0sT.Brutal

    Is interposer class really best to customize TPanel.Paint?

    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.
  17. Fr0sT.Brutal

    While Not _thread.Finished Do Application.ProcessMessages;

    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).
  18. Fr0sT.Brutal

    Should I use path in $Include file or not

    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.
  19. Fr0sT.Brutal

    TEdgeBrowser and 10.2.3...

    Why not? It's just a wrapper, no magic AFAIU
  20. Fr0sT.Brutal

    Is interposer class really best to customize TPanel.Paint?

    You need to add paths to sources for all installed packages, otherwise many useful things won't work.
  21. Fr0sT.Brutal

    Is interposer class really best to customize TPanel.Paint?

    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.
  22. Fr0sT.Brutal

    While Not _thread.Finished Do Application.ProcessMessages;

    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.
  23. 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 😄
  24. Fr0sT.Brutal

    Is interposer class really best to customize TPanel.Paint?

    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 😉
×