Jump to content

Lachlan Gemmell

  • Content Count

  • Joined

  • Last visited

  • Days Won


Lachlan Gemmell last won the day on May 28 2023

Lachlan Gemmell had the most liked content!

Community Reputation

33 Excellent

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Lachlan Gemmell

    Rad 12 Beta - Link to News

    The most underwhelming release ever was Delphi 7. https://en.wikipedia.org/wiki/History_of_Delphi_(software)#Early_Borland_years_(1995–2003)
  2. Lachlan Gemmell

    Problems with Delphi class structure / visibility

    So you'll need to find an instance of the TRenderer to access it's internal theme instance (hopefully via a public Theme property on the renderer). Use the same technique. Do a find in files for TRenderer.Create and find where the renderer is created. You may find it's contained by another class, in which case you repeat the same process for that class to find it's instance(s). To get access to the theme LemNames you may end up doing something like SomeGlobalInstanceOfSomeClass.SomePropertyForTheRendererInstance.Theme.LemNames := 'Cats'; Note that none of the parts of that made up line are unit names or class names. They're all instances, a global instance in the case of the first part, then properties within a class representing an instance, and finally the LemNames string property of the TNeoTheme class. To get this fictional line of code to compile I need to add to my uses clause whichever unit contains the declaration for the first instance, in this case the SomeGlobalInstanceOfSomeClass global variable.
  3. Lachlan Gemmell

    Problems with Delphi class structure / visibility

    I watched the rest of the video. A few comments. Firstly if you find yourself typing unit names (e.g. LemNeoTheme) outside of a uses clause, 9 times out of 10 you're doing it wrong. Secondly if you find yourself accessing a property through a class name (e.g. TNeoTheme), 8 times out of 10 you're doing it wrong. Think of a unit and the classes inside it as the paper instructions on how to build a table (a real physical table you sit at). The class procedures and functions are the steps you will need to follow to build that table and the data variables inside that class are just a list of the tools you'll need. Lets call this class TFantasticWoodenTableBuilder and it has public property HammerColour (which is a string). Don't think of that TFantasticWoodenTableBuilder class (or the unit that contains it) as being "alive" in any sense. It is as inanimate as an actual set of paper table building instructions. It can't actually physically do or verbally tell you anything. Next a real person Frank comes along and reads those instructions. Frank commits them to memory, goes away and starts building a table. Frank is now an instance of TFantasticWoodenTableBuilder and his HammerColour happens to be red. John reads the instructions and decides to build a wooden table with them. His hammer is blue. We now have two instances of TFantasticWoodenTableBuilder, Frank and John each with their own separate properties (though both called HammerColour) that stores their own respective hammer colours. If you want to know the colour of somebody's hammer you have to ask them (via an instance variable). There's no point asking the class (TFantasticWoodenTableBuilder), it's just a piece of paper, it's not going to talk back to you. The Frank and John instance variables are declared like this var Frank : TFantasticWoodenTableBuilder; John : TFantaticWoodenTableBuilder; This is how they are created (as in memory allocated to them) John := TFantasticWoodenTableBuilder.Create; Frank := TFantasticWoodenTableBuilder.Create; This is how you get or set their hammer colours if John.HammerColour <> 'blue' then ShowMessage('John has pinched somebody elses hammer'); Frank.HammerColour := 'green'; When you're done with them you free these instances so they release their memory Frank.Free; Frank := nil; { to everyone else, lets not make this line a thing please :-) } John.Free; John := nil; So the above code declared two instances John and Frank, created those instances, interrogated their respective hammer colours, and lastly freed the memory associated with those instance variables. Very important, if you're in another unit and you want to know what Frank's hammer colour is, you need to be able to reference the Frank instance through the Frank variable. Now that Frank variable is probably not declared in the same unit as the TFantasticWoodenTableClass. It's probably declared in some other unit. You have to add that other unit to your uses clause, not the unit that has the TFantasticWoodenTableClass in it. How do you know which other unit? Well you have to go searching for it just like you did at 7:04 in your video. How do you know what to search for? Detective work. Welcome to programming. At the 7:30 mark of the video you're getting close to understanding the problem but the actual solution is going to evade you until you learn more about object oriented programming. I haven't watched it but this video might be a good start.
  4. Lachlan Gemmell

    Problems with Delphi class structure / visibility

    I watched the first third of your video. You don't have an instance of your class TNeoTheme to actually retrieve the property from. A theme sounds like something you only need a single instance of in your whole application (I could be wrong on that, but for now let's say I'm right). Since there's only going to be one of them a global TNeoTheme instance variable will be acceptable for now. Let's declare it in the LemNeoTheme.pas unit unit LemNeoTheme; interface type TNeoTheme = class private FLemNames : string; public property LemNames : string read FLemNames write FLemNames; end; var MyTheme : TNeoTheme; { this variable MyTheme will represent the single instance of the class TLemNeoTheme } { it does not however create that instance here, just declares the variable } implementation { code, code, code, more code } { now at the very bottom of the unit, just before the final end. statement } initialization MyTheme := TNeoTheme.Create; { this is where the memory for the instance of TLemNeoTheme is allocated } { and assigned to the MyTheme variable. It will occur when the program starts } finalization MyTheme.Free; { this is where the memory for the instance is released. It will occur when the program shuts down } MyTheme := nil; end. Now over in TGamePreviewScreen.GetTextLineInfoArray you access the LemNames property via the MyTheme instance variable Result[2].Line := Result[2].Line + IntToStr(zombies + lemmings) + MyTheme.LemNames; Please be aware that we're only scratching the surface with the code above. It's probably appropriate for your TNeoTheme class but most other class instances will not be global variables like this and will require other techniques. Actually surely there is already a TNeoTheme instance somewhere in this code already. Do a Find in Files search for "TNeoTheme.Create". Ignore the actual constructor implementation but you'll likely find something like: AnotherThemeInstanceVariable := TNeoTheme.Create; That variable AnotherThemeInstanceVariable is probably the one you should be using rather than the MyTheme variable I declared and created above. I hope you'll take this in the spirit that it's intended in but a quick look at the project on that video makes me think you've picked a pretty big mountain to climb for your first outing. Maybe go find a few gentle hills to train on first before attempting something as large and complex in scale as game development.
  5. Lachlan Gemmell

    Cost benefit analysis of moving project from Classic compiler to Clang

    Thanks for the heads up. We're in a controlled environment with high DPI screens for the users being a distant reality but it's good to know about the issues before they happen.
  6. Lachlan Gemmell

    Cost benefit analysis of moving project from Classic compiler to Clang

    Thanks for the feedback gents, it sounds like this particular project is best suited to stay with the classic compiler for the foreseeable future. As Delphi programmers we've worked with similarly sized and structured Delphi projects that take around 20 seconds to do a full build. With a current build time of around 10 minutes for this C++ project I can't even conceive of doing anything that would increase the build times even further. QuickReport no longer being supported isn't an issue as it was shipped with full source so we can move it to the later IDEs as we need to. As to why TwineCompile and the pre-compiled header wizards fail on this project, my guess is that the "uniqueness" of how the code has been structured in some places may be defeating them. We're gradually replacing that "uniqueness" with some more straightforward code and perhaps one day in the future those tools will run successfully.
  7. We're a Delphi development company but we've inherited a C++ Builder project that we're now responsible for maintaining. The rough stats of the main application project are Rad Studio Berlin, classic compiler approx 500K C++ lines, 200+ forms, 100+ QuickReports, Quite a lot of very long files 10K+ lines Lots of very long functions 1K to 5K lines Compile and link time is about 10 minutes The precompiled header wizard fails on the project Twine compile fails on the project There's also a bunch of support BPLs (largest about 60K lines) and the application is built with runtime packages. We can't get it to link with runtime packages turned off but that's a question for another day. As Delphi programmers who haven't really touched C++ in decades this code base is extremely easy to read. It reminds me very much of the C++ I was taught at university in the early 90s. Swap curly brackets for begin/end and there is barely anything in there we don't immediately understand. I'd say it's unlikely that we would want to start using advanced C++ language features until much further down the line. At the moment we're just trying not to upset the apple cart. We will in the near future move from Berlin to Alexandria and then attempt to stay no more than a version behind from then on. We are yet to even give it a try but should we attempt a move to the Clang compiler? I guess the primary thing we're really looking for is a way to improve compile times. Is Clang faster than Classic? Are there other major benefits to Clang that as Delphi programmers we're just not aware of? If you would recommend switching to Clang, how difficult a process is it likely to be give that our C++ knowledge is not all that great.
  8. Lachlan Gemmell

    Documentation on deployment

    I'm considering using Python4Delphi in a Delphi VCL Win32 application but I can't find documentation on the deployment for such an application. Is there a reference I'm missing that details the various options?
  9. Lachlan Gemmell

    DelphiMVCFramework-3.2.2-nitrogen has been released

    My vote would be just chuck the word "Remoting" in there and pretend it was there all along. 🙄 Name change, what name change? It's always been called "Delphi MVC Remoting Framework".
  10. Lachlan Gemmell

    DelphiMVCFramework-3.2.2-nitrogen has been released

    We use the DelphiMVCFramework in a few systems. It's much nicer way to create a REST server than DataSnap or Rad Server. @Daniele Teti it's probably too late now but have you considered changing the name of the project? I stayed away from the project for longer than I should have because I saw the name and thought, "I don't need a framework to implement an MVC pattern for me". I had no idea it was a REST server until someone else actually cleared up the misconception for me. The current name is a bit like saying I have an internal combustion engine in my driveway rather than a car.
  11. Wow that's great. Much cooler than I expected. So glad to have been of assistance. So did OpenGL ever add "built-in mechanisms for rendering hierarchical models"?
  12. OK I'm intrigued now. Most of the content in that edition seems pretty outdated 20 years later. From the Palette Take Action — Bill Todd For those of you who need to give an application’s menus and toolbars the look and feel of Microsoft Office 2000, Bill Todd introduces the new Delphi 6 ActionManager and ActionBars components. Dynamic Delphi From XML to Object: Part II — Keith Wood Keith Wood wraps up his two-part series on the XML Data Binding Wizard by sharing sample applications that demonstrate how to read and display XML documents — and generate new ones. In Development Build Your Own Compiler: Part I — Fernando Vicaria Fernando Vicaria demystifies compilers using the straightforward approach of showing you how to build one with Delphi, and by keeping the jargon and formalism to a minimum. It’s the first of a four-part series. Sound+Vision Hierarchical Models in OpenGL — Araz Yusuf OpenGL provides a wide range of routines for modeling complex objects, but it has no built-in mechanisms for rendering hierarchical models. Araz Yusuf shows us how he gets the job done with Object Pascal. On the ’Net Taming the Beast from Redmond — Dave Ball Dave Ball provides a step-by-step explanation of how to deploy ISAPI DLLs within an MTS or COM+ memory-protected development environment, by configuring IIS settings within the MMC. Inside OP — Gary Warren King Forms and dialog boxes often have interdependent field and display properties whose friendliness can rapidly decay. Mr King shows how to keep your UI responsive — by delaying events. I'm going to guess you're either building your own compiler or doing some sort of throwback ISAPI DLL deployment?
  13. I'm a packrat who holds on to those sorts of things. Will contact you via direct message.
  14. Lachlan Gemmell

    EULA declined installing 11.1 with Network Named license

    So I went with the Alexandria 11.1 ISO and installed it in my Win7 VMs. That went fine but I’m regretting the decision. It turns out though that GetIt in 11.1 (and now also 11.0) uses TLS1.3 and while you can view the contents of GetIt, you get the 12175 error or something similar if you try and install anything via GetIt including IDE patches. I’ll get by with hacks and workarounds for now but for me regrettably it is time to retire Win7 and move to Win10 based virtual machines.
  15. Lachlan Gemmell

    EULA declined installing 11.1 with Network Named license

    It makes for a much more lightweight VM than one based on Windows 10. If you have a multitude of VMs that makes a difference both in terms of memory and disk consumption (particularly since we took a backwards step in capacity terms with SSDs). I use them purely for writing code in, I don't go browsing random websites with an outdated Win7.