Jump to content

JonRobertson

Members
  • Content Count

    289
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by JonRobertson

  1. JonRobertson

    Tool to sort units used in project by dependency

    Unfortunately cnpack causes an AV in rtl*.dll when LiveBindings packages are disabled, and a couple other AVs in the IDE. I had to uninstall cnpack until this issue is resolved: AV after exit RAD Studio 10.2.3 - 12.1 And hopefully this AV in coreide.bpl: Access violation in module 'coreide250.bpl' #170 Access violation in module 'coreide290.bpl' #192
  2. JonRobertson

    Tool to sort units used in project by dependency

    Yes, it is noticeable. My last four projects have been migrating applications from Delphi 7 to 11.3. There were dozens of units referenced that could be either moved to implementation or removed completely. I've been able to get rid of numerous circular dependencies. Although the compile time reduction is not huge, it is noticeable even on a 200K loc project. Sadly, it takes Azure DevOps longer to check out the repo than building the source.
  3. JonRobertson

    Tool to sort units used in project by dependency

    Give it a shot and let us know.
  4. JonRobertson

    Using same form for adding and editing data

    The data shown and potentially edited on a form comes from somewhere. So I populate the controls from the source and update if/when the user makes changes. If this is in the app with the base form and UpdateUIState implementation I described, I am still able to override methods like UpdateUIState for that form, that code doesn't care about a dataset. Another option is to use LiveBinding, although I've avoided LiveBinding myself. Just with Delphi? Do you use other languages with frameworks that provide a cleaner solution? The projects that I currently maintain do this as well. Although I am not a fan of requiring extra mouse clicks. It is easy to detect once a user has changed data and require the user to click Save or Cancel before closing the form.
  5. JonRobertson

    Display a conditional message on data change...

    One suggestion would be to use a timer that is reset in OnDataChange. I've done something similar when implementing an incremental search, using the OnChange event of a TEdit for example.
  6. JonRobertson

    How to debug a Not Responding program element

    Perhaps it can't without knowledge of the helper class TListHelper. Although you were able to trace back to the point of code where Clear was called and it was shown in your screenshot.
  7. JonRobertson

    How to debug a Not Responding program element

    Thanks Anders. This approach is should be used rather than the one I posted.
  8. JonRobertson

    How to debug a Not Responding program element

    TGadgetAnimations is a TObjectList that holds a list of TGadgetAnimation: TGadgetAnimations = class(TObjectList<TGadgetAnimation>) There are multiple instances of TGadetAnimations created here: constructor TGadgetMetaInfo.Create; var i: Integer; begin inherited; for i := 0 to ALIGNMENT_COUNT-1 do begin fVariableInfo[i].Animations := TGadgetAnimations.Create; The TObjectList.OwnsObjects property defaults to True and is not set to False for any instance of TGadgetAnimations. This means that TGadgetAnimations will call Free on the instances of TGadgetAnimation that it holds (which are added by the call to Add). The TObjectList.Clear method will remove all instances of TGadgetAnimation that were added to that instance of TGadgetAnimations. Since OwnsObjects is True, calling Clear will also call Free on each instance. When AddPrimary is called the first time for the instance, it assigns a reference to TGadgetAnimation to fPrimaryAnimation. procedure TGadgetAnimations.Clone(aSrc: TGadgetAnimations); var i: Integer; NewAnim: TGadgetAnimation; begin Clear; NewAnim := TGadgetAnimation.Create(aSrc.PrimaryAnimation.fMainObjectWidth, aSrc.PrimaryAnimation.fMainObjectHeight); NewAnim.Clone(aSrc.PrimaryAnimation); AddPrimary(NewAnim); <-- This will assign fPrimaryAnimation if it is not assigned. When Clone is called, it calls Clear, which frees the TGadgetAnimation instances that were previously created. But, it does not clear the fPrimaryAnimation reference, which is now pointing to unallocated memory. Use the solution posted by Anders of overriding the Notify method.
  9. JonRobertson

    How to debug a Not Responding program element

    I also did not see any place where those particular object lists are created with Create(False)
  10. JonRobertson

    How to debug a Not Responding program element

    If TGadgetAnimation is not being freed, then it would have a reference to fName and the string would also be a leak.
  11. JonRobertson

    How to debug a Not Responding program element

    GadgetAccessor is assigned by the result of GetInterface. GetInterface creates the TGadgetMetaAccessor and assigns the reference to the FInterfaces array: function TGadgetMetaInfo.GetInterface(Flip, Invert, Rotate: Boolean): TGadgetMetaAccessor; var i: Integer; begin i := GetImageIndex(Flip, Invert, Rotate); if fInterfaces[i] = nil then fInterfaces[i] := TGadgetMetaAccessor.Create(self, Flip, Invert, Rotate); <-- Created reference assigned to fInterfaces Result := fInterfaces[i]; end; TGadgetMetaInfo.Destroy loops through fInterfaces and calls Free on each: destructor TGadgetMetaInfo.Destroy; var i: Integer; begin for i := 0 to ALIGNMENT_COUNT-1 do begin fVariableInfo[i].Animations.Free; fInterfaces[i].Free; end; inherited; end; Despite the misleading names of GetInterface and fInterfaces, these are not Delphi interfaces. TGadgetMetaAccessor is a class derived from TObject.
  12. JonRobertson

    How to debug a Not Responding program element

    Never mind, found it. TGadgetAnimations is a class of TObjectList. TObjectList has a property named OwnsObjects that is True by default. Unless OwnsObjects is set to False, TObjectList will call Free to release all objects that are added to it. See the documentation for TObjectList.OwnsObjects. The only place in the SupperLemmix code where I see OwnsObjects set to False is here: fTalismanButtons.OwnsObjects := false; // Because TFLevelSelect itself will take care of any that remain
  13. JonRobertson

    How to debug a Not Responding program element

    fPrimaryAnimation is likely only a reference to which animation is currently the primary animation. TGadgetAnimations adds NewAnim to a list of some kind (see the calls to Add(NewAnim) and Add(aPrimary). I suspect TGadgetAnimations is responsible for freeing all animations that are added. Is this still SupperLemmix? I downloaded SupperLemmix source just now from https://github.com/Willicious/SuperLemmixPlayer and I do not see TGadgetAnimations in that code.
  14. JonRobertson

    Anyone using Clever Components?

    Yes. Several questions, about the Database Comparer VCL components. I downloaded the trial and samples of Database Comparer. With the prebuilt DBComparerDemoAdo, I attempted to compare two versions of one of our databases. The result was "Update script is empty" even though there are certainly differences in the schema of the databases. There are some messages in the log indicating an issue, such as "ambiguous column" and "field not found". However there is no additional information to give insight, such as the DB objects that triggered the errors. I hoped that "The trial version can operate inside Delphi / C++Builder IDE only, all other features are completely available without any restrictions" was accurate. There is no mention on the download page of other restrictions. The trial version appears to be limited to extracting only a few DB objects. The help file is unhelpful on most topics, for example: TCustomScriptExtract.ScriptFileNames property ScriptFileNames : TStrings; A vast majority of the help topics are like this, lacking any description aside from the Pascal definition. Without source, it is difficult to determine the capabilities without better documentation. One of the most important capabilities that I need to test is how well the components handle dependencies between database objects. What order are objects created? If there are stored procedures or functions that depend on other stored procedures or functions, are these created in the correct order so the creation scripts do not fail? How can I iterate through DBStructure.Metadata properties (such as Tables, Views, and Procedures) by name? I don't see a way to get a list of the names of the objects that were extracted, a count of the objects, or a way to iterate them by index. If I have a list of table names, how do I use .Tables['MyTable'] to get the CREATE script? I've tried .Body, .CurrentDefinition, .SourceDefinition, .Text, and .SQLExec (to get to .SQLExec.Statements, but .SQLExec is nil). I greatly appreciate any insight you or anyone else can provide. I need to make a recommendation on purchasing either Database Comparer VCL, Delphi HTML Component Library (primarily for the SQL Library components), or writing my own, which I started investigating today.
  15. JonRobertson

    Anyone using Clever Components?

    I doubt it. The domain register is in Germany and the registered name servers are in Russia.
  16. Embarcadero Partners with Raize Software for KSVC Maintenance
  17. JonRobertson

    TSkAnimatedImage assign?

    The Assign method is introduced in TPersistent. All well-written components should override the Assign method. I believe this dates back to Delphi 1. TPersistent.Assign
  18. Does anyone know how to use reFind to remove a property for a specific component in a DFM? For example, remove BorderStyle from only TMemo components? I have tried #remove TMemo:BorderStyle but that does not work for me the way #migrate TMemo:BorderStyle does. I have tried a few other things, but either no BorderStyle property values are removed or all of them are. Thanks
  19. Or provide the source (not open source, just source like the RTL/VCL source) to active subscribers so we can adapt it as we need. I added a comment to the RSP but I probably need to create a new QP request since mine was closed as resolved.
  20. Resolved: Works as Expected. Given reFind is a tool mostly focused on migration to FireDAC, we don't plan expanding it to support other automatic processing scenarios...
  21. JonRobertson

    Threadvar "per object"

    TLightweightMREW Our "issue" at the time was RTL code. Specially in a DCOM based MIDAS/DataSnap server that created a thread for each user connection. Once the DataSnap server had over 100 users connected, it would frequently lock up due to a deadlock with GlobalnameSpace. However, the contributing factor was we were doing "too much" in RemoteDataModuleCreate, which extended the amount of time that GlobalNameSpace was locked. We also had multiple TRemoteDataModules due to the size of our app. While I don't disagree with your assertion of "people didn't know what they were doing", it wasn't because we were misusing TMREWS. We never used it directly in our code. My apologies for hijacking the thread. I'll stop now.
  22. JonRobertson

    Threadvar "per object"

    Nope. It returns results like Numerous posts about TMREWS having issue and asking if those were fixed. A few posts suggesting an alternate solution. I trust members of Delphi-Praxis more than most other online resources. So I thought I'd ask.
  23. JonRobertson

    Threadvar "per object"

    Does anyone use TMultiReadExclusiveWriteSynchronizer? The application team I was on 20 years ago had some problems with it in D6. But I see that the VCL still uses it for GlobalNameSpace (for Windows anyway).
  24. JonRobertson

    F1 context help to WinAPI ?

    Reminds me of one step forward, two steps backwards.
  25. JonRobertson

    Threadvar "per object"

    Is any instance of TBSItemProvider accessed by multiple threads?
×