-
Content Count
2993 -
Joined
-
Last visited
-
Days Won
176
Everything posted by Uwe Raabe
-
Mix interface with objects
Uwe Raabe replied to Berocoder's topic in Algorithms, Data Structures and Class Design
To connect both worlds I often use this pattern: type TMyCurrentClass = class public procedure MyMethod; end; type IMyInterface = interface ['{B3D71E7A-9066-4407-BFE2-B4BB61221954}'] procedure MyMethod; end; type TMyCurrentClassWrapper = class(TInterfacedObject, IMyInterface) private FMyInstance: TMyCurrentClass; FOwnsInstance: Boolean; function GetMyInstance: TMyCurrentClass; public constructor Create(AMyInstance: TMyCurrentClass = nil; AOwnsInstance: Boolean = False); destructor Destroy; override; property MyInstance: TMyCurrentClass read GetMyInstance implements IMyInterface; end; ... constructor TMyCurrentClassWrapper.Create(AMyInstance: TMyCurrentClass = nil; AOwnsInstance: Boolean = False); begin inherited Create; FMyInstance := AMyInstance; FOwnsInstance := AOwnsInstance; end; destructor TMyCurrentClassWrapper.Destroy; begin FMyInstance.Free; inherited; end; function TMyCurrentClassWrapper.GetMyInstance: TMyCurrentClass; begin if FMyInstance = nil then begin FMyInstance := TMyCurrentClass.Create; FOwnsInstance := True; end; Result := FMyInstance; end; It allows class-based and reference counted interface-based usage without fiddling around with the base class. The key point is that you cannot retrieve the interface from an instance of TMyCurrentClass avoiding most of the mix problems. The scenario with giving a non-owned instance with the constructor still is a fragile usage though. One has to guarantee that the instance is valid for the whole lifetime of the wrapper. -
DUnitX - Assert.AreNotEqual - Compiler error E2532 - Couldn't infer generic type argument from different argument types for method
Uwe Raabe replied to fisipjm's topic in DUnitX
I cannot reproduce with the code given using DUnitX.Assert from D13. -
See here: https://jrsoftware.org/ishelp/index.php?topic=setupcmdline
-
Best strategy to set up global Release/DebugDCU paths in the IDE, as example for Spring4D DCUs
Uwe Raabe replied to HaSo4's topic in Delphi IDE and APIs
I know I am late to the party, but the slowness of this forum during the last days made me think twice before posting anything. First let me tell you that I am in the concise project party - I can take a vanilla Delphi installation, pull and check out a project repository and have all dependencies inside the project folder structure using Git submodules. This turned out to be the most effective approach allowing individual branches holding project specific tweaks. Usually I have the global IDE library path reserved for Delphi units only. This forces me to actively add any newly used library to the submodules and project search path, which always starts a reasoning whether the inclusion of that library is actually worth it. The latter keeps the dependencies low on the long run. In the past, mostly for simplicity, I added the source paths for these projects, requiring to compile all libraries with each build. This counts for each project, because each uses a different Unit output directories to keep the compiled units separated (think of different conditionals). Unfortunately, since a couple of years we have had some Delphi versions that forced me to start a complete build more often than I anticipated. That raised my interest in the concept of pre-compiled units. To get some numbers to compare the benefits of this approach I took a project group of some relative small projects, changed that to pre-compiled units and compared the build times and other performance changes when working with the project. First I needed to create a batch that actually does the pre-compilation after checking out the libraries. I didn't expect that to be the task taking the most effort. To be Delphi version agnostic I had to prepare proper packages and project groups for some libraries. Then I created an MSBuild project file with the project groups of all used libraries, so that I can call MSBuild once for a platform and configuration in a batch file with MSBuild using BuildInParallel, setting DCC_DcuOutput to a common folder. Having this all working correctly (I had to add copying the .dfm and .res files to the project, too), the time to build all libraries for one platform and configuration lasts about 15 seconds, adding up to a less than half a minute for Win32 and Debug/Release. For simpler maintenance of the project search paths I already used an option set, so changing the list of all the the libraries source folders to the one dcu folder was quite a simple task. It even survives changing to a new Delphi version: ..\lib\dcu\$(ProductVersion)\$(Platform)\$(Config) (As some may note: I have all projects a the source root allowing to have the same relative folders). The build time for one of the most used projects reduced from ~10 seconds to ~4 seconds. That doesn't sound much, but it adds up. And it has way more consequences during working at the code. I rarely see the CodeInsight progress bar anymore and when it is just for a glimpse. Also LSP seems much more stable and has to be restarted less often. (Sometimes restarting doesn't even help and it turns out I actually made a mistake myself.) More and more I get away with a plain compile instead of a build. (Probably I only do a build out of habit) MMX Source Indexer is much faster. Instead of 3000 files it now has to scan just 600. All these effects, even if each is small, add up to a significant faster and smoother working experience. I am aware that using the IDE library path approach includes some of these benefits, too. Nevertheless, I still prefer the concise project approach. Also I want to avoid having libraries in the search paths for all projects of which only a small part makes use of. -
The problem with bookmarks and breakpoints is that they are bound either to the current project group or the current project (with a fake group), whatever is opened. Any attempt to keep those during formatting will most likely still damage any of the others. F.i.: Assume unit X is used in several projects. Formatting unit X while project A is open may keep the breakpoints, but the breakpoints saved in project B may not match anymore when opened.
-
Open MMX Properties, select General and disable Allow MMX Actions in IDE toolbars.
-
Removing semi transparency in background compile window
Uwe Raabe replied to Roger Cigol's topic in General Help
I made some tests and found that background compile time increases by 100-150% compared to foreground. Not sure if these numbers are typical. -
Error F2084: Internal Error: L878 in Delphi 13
Uwe Raabe replied to emileverh's topic in RTL and Delphi Object Pascal
... and file a bug report! -
The Uninstall button in GetIt has a drop down option to open that folder.
-
Cursor positions in multiple edit windows
Uwe Raabe replied to dummzeuch's topic in Delphi IDE and APIs
IMHO, that is an oversight (i.e. nobody raised this use case in the past, so nobody added that to the specification). The ToolsAPI provides IOTAEditLineTracker to handle that. Getting the cursor position of an EditView tracked while being deactivated should be an overseeable task. I suggest filing a report. Multiple EditViews of the same source seem to be used rarely. We need more reports like that to drag some attention to it. -
It does not work when the Code Insight Manager is set to Classic Code Insight, but that is expected.
-
And where will the AIs get the newer information then?
-
Regression - Delphi 12 - Unable to debug dynamically loaded packages
Uwe Raabe replied to @AT's topic in Delphi IDE and APIs
Sounds like an off-by-one error. -
NameOf() in D13 to get the name of the current method
Uwe Raabe replied to emileverh's topic in RTL and Delphi Object Pascal
There is a real use case mentioned in the https://github.com/UweRaabe/CmonLib/tree/main/Examples/Observers example of CmonLib. Currently the calls in Main.Form use constants to specify the property to observe: tmp.AddObserver<string>(tmp.cMyString, procedure(AValue: string) begin MyStringEdit.Text := AValue end); tmp.AddObserver<TStrings>(tmp.cMyLines, procedure(AValue: TStrings) begin MyLinesMemo.Lines := AValue end); tmp.AddObserver<Integer>(tmp.cMySelectedIndex, procedure(AValue: Integer) begin MySelectedComboBox.ItemIndex := AValue end); tmp.AddObserver<string>(tmp.cMySelected, procedure(AValue: string) begin MySelectedComboBox.Text := AValue end); tmp.AddObserver<Integer>(tmp.cMyListItemIndex, procedure(AValue: Integer) begin MyListItemListBox.ItemIndex := AValue end); The constants are declared like this (note the QP reference): type TObservableData = class(TData) public const { string representation of TData property names. I am eagerly waiting for the implementation of the top most voted feature request in QP: RSP-13290 "NameOf(T) compiler (magic) function" } cMyLines = 'MyLines'; cMyListItem = 'MyListItem'; cMyListItemIndex = 'MyListItemIndex'; cMySelected = 'MySelected'; cMySelectedIndex = 'MySelectedIndex'; cMyString = 'MyString'; With a proper NameOf the calls above could be written like this: tmp.AddObserver<string>(NameOf(tmp.MyString), procedure(AValue: string) begin MyStringEdit.Text := AValue end); The tricky part here is that NameOf(tmp.MyString) needs to return 'MyString' and not 'tmp.MyString'. (Perhaps I should file a use case for that. Otherwise I may have to wait a few more iterations.) -
NameOf() in D13 to get the name of the current method
Uwe Raabe replied to emileverh's topic in RTL and Delphi Object Pascal
The idea behind NameOf(<someIdentifier>) is to get a string representation of that identifier. If the underlying item of <someIdentifier> gets renamed the parameter to NameOf gets either magically changed too (using a capable rename refactoring) or the old identifier (hopefully) won't compile anymore. F.i. accessing RTTI information about a property using TRttiType.GetProperty requires the name of that property. Currently one needs to keep a string constant in sync with the property name. Unfortunately we have RSB-997 - NameOf() does not allow class members, so I still have to wait for that being implemented. I agree that not everyone wants to make use of NameOf, but is has been the most voted item in QualityPortal for quite some time. Probably there are a couple of users with a real need for that. Pointless doesn't quite hit it. -
V16.0.10.85 Fix: accept single line literal starting with three quotes Show invisible Source Indexer when searching is invoked Don’t auto-dock Floating Explorer when invoked from menu Locate Editor Position Do rename when leaving Entity Insight name edit with changed content Option to hide units from VCL/FMX framework in Use units Parser recognizes new generic constraints interface and unmanaged. Support multi-select with Break up Property and Convert Property to Field Download from MMX Beta Setup
-
Check for a console window waiting for your input.
-
Keybindings get unregistered in an unknown scenario
Uwe Raabe replied to havrlisan's topic in MMX Code Explorer
That's a tricky one and it only happens on non-English keyboard settings. When you set your keyboard to English the shortcut will always work because it is hard-wired in the keyboard interface. Also the behavior is different depending on the keyboard layout: RSP-30422 - Toggle Comment Line works different depending on keystroke used Although this problem exists since quite a time, we were not able to detect the trigger for that. Well, it is sufficient to open the editor context menu to make it work again. -
Keybindings get unregistered in an unknown scenario
Uwe Raabe replied to havrlisan's topic in MMX Code Explorer
I can remember cases (several years ago) where the Explorer shortcuts stopped working and even an IDE restart wouldn't help, but your scenario sounds a bit different. -
NameOf() in D13 to get the name of the current method
Uwe Raabe replied to emileverh's topic in RTL and Delphi Object Pascal
With the introduction of NameOf there are still gaps where it doesn't work (partly huge ones). I guess we can expect extensions to NameOf targets in future updates and releases. -
Bonus KSVC Install RAD Studio 13
Uwe Raabe replied to jcwhit's topic in RTL and Delphi Object Pascal
Can you show the wrong path here, please? -
Bonus KSVC Install RAD Studio 13
Uwe Raabe replied to jcwhit's topic in RTL and Delphi Object Pascal
I can repro, too. It might be related to being installed in HKLM instead of HKCU. -
Bonus KSVC Install RAD Studio 13
Uwe Raabe replied to jcwhit's topic in RTL and Delphi Object Pascal
Please file a bug report at https://qp.embarcadero.com/ -
Most likely because it has been that way forever.
-
Refactor – Rename (Type, Field, Property) Alternatives in Delphi 13
Uwe Raabe replied to dmitrybv's topic in Delphi IDE and APIs
Unfortunately, it has not. Yet.