Jump to content

Vincent Parrett

Members
  • Content Count

    791
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by Vincent Parrett

  1. Vincent Parrett

    Unit testing for beginners

    DUnitX isn't an extreme version (whatever that is) - just a diffferent testing framework.. delphi really only has 2 well used unit test frameworks (other languages have many) - pick one you like. https://www.finalbuilder.com/resources/blogs/introducing-dunitx
  2. Vincent Parrett

    What is part of your contiuos integration?

    Download a trial version and see for yourself. Yes, you will need to give us your email address so we can send you a code and you will get a few follow up emails that are not sales, just trying to help you evaluate the product - we use drip.com for those emails and you can unsubscribe quite easily.
  3. Vincent Parrett

    What is part of your contiuos integration?

    It's a continuous integration server - it's designed to run as a service running all the time. It monitors your source code repositories (git, svn etc) for changes and triggers builds based on those changes. It can only do that when it's running. If you just want to automate the build process without doing continuous integration, then look at FinalBuilder. It's a desktop IDE application (there is also a console version included).
  4. Vincent Parrett

    What is part of your contiuos integration?

    I think perhaps you are coming at this from the wrong angle.. git push is your backup (assuming you are using an offsite git server/service) - and should also be the trigger for automation in CI - ie you push your git commits, the CI server detects those changes and fires off a build, runs your unit tests, builds your installer, ftp's the files to the server and sends out email notificiations. (vendor plug) These days CI is very accessible even for solo developers. Our Continua CI product is free for a single concurrent build and a single build agent (installed on the same machine as the server) - other than that it's fully functional, unlimited configurations (and users) - perfect for solo developers and it's very easy to scale it up (add licenses, install extra agents as needed). It only takes a few minute to install and get up and running with a build process - The video shows using mercurial, visual studio and nunit, but it works just as well using git, delphi and dunitx. https://www.finalbuilder.com/resources/blogs/building-delphi-projects-with-continua-ci If you really want to expand your automation then take a look at FinalBuilder (built with delphi) - over 600 built in actions that cover version control (git, mercurial, svn and a bunch of others), compilation (delphi 3 - 11, msbuild, vs etc) - install builders (innosetup, installshield etc), deployment (FTP/FPTS/SFTP/SSH) and a too many others to mention here. The cool thing about FinalBuilder is you get to develop and debug your build process in an IDE that lets you step through your build process, stop on breakpoints, watch variables etc.. and then your build project can be checked into version control along with your source code and your CI server can run FinalBuilder to build your projects (using the console version of FinalBuilder). Of course Continua CI and FinalBuilder play very nicely together - we build FinalBuilder, Automise and Continua CI with FinalBuilder an Continua CI. https://www.finalbuilder.com/resources/blogs/continuous-integration-with-finalbuilder
  5. Vincent Parrett

    D11 - A bridge too far.. :-(

    A salient point. And then there are the high dpi issues from 10.4.2 that were ignored 🙄
  6. Vincent Parrett

    Menu captions with images are hard to read under Windows 11

    I use runtime packages (the application is mostly plugins) so just taking a copy of the unit doesn't work. I use delphi detours where I can (it's not always doable) and like Uwe I have it error out if the compiler version changes so I know I need to look at it again.
  7. Thanks, I'll take a look.
  8. Vincent Parrett

    Let's Encrypt old root expiry and OpenSSL

    I forgot there was somethings else I also did to fix this - install the new intermediate certificates on the servers. I don't remember having to do this before, but I was clutching at straws and trying things 😉
  9. Vincent Parrett

    Let's Encrypt old root expiry and OpenSSL

    We had issues with some of our certificates, the fix was to renew them - the new certificates use the R3 root certificatge https://techcrunch.com/2021/09/21/lets-encrypt-root-expiry/
  10. Vincent Parrett

    Need help on some C# to Delphi Conversion

    There isn't really a 1 for 1 conversion here - the Delphi language/ppl does not have any async/await constructs . So because of that your translation isn't correct. That said, your c# example isn't valid either. Your TDoTest.Meth doesn't actually return anything so that's a problem there. So you are left with a few options. Deal with it yourself. which as you have found is not easy (even with the PPL) - or find another library that could handle it. If you are doing this for windows only, OmniThreadLibrary is an option but has a fairly steep learning curve (worth it if you need to do complex threading stuff). For simple code, I wrote a wrapper over Omni (VSoft.Awaitable) which provides a poor mans version of async/await (omni does have this too, but it's missing a few features like cancellation and returning values). function TDoTest.Meth(AMessage: string): IAwaitable<Test> begin //configure our async call and return the IAwaitable<string> result := TAsync.Configure<Test>( function(const cancelToken : ICancellationToken) : Test begin //.... do some long running thing result := TTest.Create end, token); end; //calling code procedure TAnotherClass.DoSomething; var doTest : TDoTest; begin doTest : TDoTest.Create; //this will not block. doTest.Meth('the message', FTokenSource.Token) // optional .OnException( procedure (const e : Exception) begin //handle the exception - runs in calling thread end) // optional .OnCancellation( procedure begin // call was cancelled - do any cleanup here // runs in calling thread end) // required, the call to Await actually fires off the task .Await( procedure (const value : TTest) begin //runs in the calling thread. Label1.Caption := value.TestMe; end); end; The FTokenSource above is an ICancellationTokenSource - VSoft.Awaitable depends on VSoft.CancellationToken - in VSoftAwaitable it maps over Omnithread's cancellation token - delphi doesn't have one in the rtl or PPL (a glaring omission imho). It's hard to give a definative example with the invalid c# example though. BTW, to understand what async/await actually does in C#, this page sums it up quite nicely.
  11. Vincent Parrett

    Delphi Package Manager - choices?

    Nice in theory, not really doable though - they are all so different because we all have different ideas.
  12. Vincent Parrett

    Delphi Package Manager - choices?

    That's correct. When you install a package in a project, it first looks in the package cache (typically %APPDATA%\.dpm\packages - can be changed by the DPMPACKAGECACHE env variable) If the package is there then that is used, otherwise it (and any missing dependencies) is downloaded from the registered package sources into the package source. Then using some msbuild variables the package and it's dependencies are added to the project's search path This is an example from the dpm ide plugin for 10.4 <PropertyGroup> <DPMCompiler>10.4</DPMCompiler> <DPMCache Condition="'$(DPMCache)' == ''">$(APPDATA)\.dpm\packages</DPMCache> <DPM>$(DPMCache)\$(DPMCompiler)\$(Platform)</DPM> <DPMSearch Condition="'$(Platform)'=='Win32'">$(DPM)\VSoft.VirtualListView\0.3.0-rc8\lib;$(DPM)\VSoft.Uri\0.1.1\lib;$(DPM)\VSoft.SemanticVersion\0.2.2\lib;$(DPM)\VSoft.JsonDataObjects\0.1.1\lib;$(DPM)\VSoft.HttpClient\0.2.4\lib;$(DPM)\VSoft.CancellationToken\0.0.3\lib;$(DPM)\Gabr42.OmniThreadLibrary\3.7.8\lib;$(DPM)\VSoft.Awaitable\0.2.1\lib;$(DPM)\VSoft.AntPatterns\0.1.1\lib;$(DPM)\Spring4D.Extensions\2.0.0-dev7\lib;$(DPM)\Spring4D.Base\2.0.0-dev7\lib;$(DPM)\Spring4D.Core\2.0.0-dev7\lib;</DPMSearch> </PropertyGroup> Then the DPMSearch variable is added to the project search path <PropertyGroup Condition="'$(Base)'!=''"> <DCC_UnitSearchPath>$(DPMSearch);$(DCC_UnitSearchPath)</DCC_UnitSearchPath> </PropertyGroup> and lastly the package references are stored in the dproj so they can be restored (if missing) next time you open the project <ProjectExtensions> <DPM> <PackageReference id="Spring4D.Core" platform="Win32" version="2.0.0-dev7"> <PackageReference id="Spring4D.Base" platform="Win32" version="2.0.0-dev7" range="[2.0.0-dev7,]"/> </PackageReference> <PackageReference id="Spring4D.Extensions" platform="Win32" version="2.0.0-dev7"> <PackageReference id="Spring4D.Base" platform="Win32" version="2.0.0-dev7" range="[2.0.0-dev7,]"/> </PackageReference> <PackageReference id="VSoft.AntPatterns" platform="Win32" version="0.1.1"/> <PackageReference id="VSoft.Awaitable" platform="Win32" version="0.2.1"> <PackageReference id="Gabr42.OmniThreadLibrary" platform="Win32" version="3.7.8" range="[3.7.8,]"/> <PackageReference id="VSoft.CancellationToken" platform="Win32" version="0.0.3" range="[0.0.3,]"/> </PackageReference> <PackageReference id="VSoft.HttpClient" platform="Win32" version="0.2.4"> <PackageReference id="VSoft.CancellationToken" platform="Win32" version="0.0.3" range="[0.0.3,]"/> </PackageReference> <PackageReference id="VSoft.JsonDataObjects" platform="Win32" version="0.1.1"/> <PackageReference id="VSoft.SemanticVersion" platform="Win32" version="0.2.2"/> <PackageReference id="VSoft.Uri" platform="Win32" version="0.1.1"/> <PackageReference id="VSoft.VirtualListView" platform="Win32" version="0.3.0-rc8"/> </DPM> </ProjectExtensions> Of course I have simplified the description above, there's a lot more to it but that is the basics. I'm currently working on project group support (made some good progress today) and then design time component support.
  13. Vincent Parrett

    Farewell Rx10.4.2

    Look at it another way, why are so many issues created during the beta not resolved? How many of those are the same as those people are now reporting. There are always a lot of duplicates in Jira, perhaps because people don't bother to search first - but then searching for existing reports in jira is not easy.
  14. Vincent Parrett

    Delphi Package Manager - choices?

    The reality is that most people don't modify packages, they just use them. As for packages being global, well that's one of my pet peeves - because I work on different projects or versions of projects that use different versions of a package - can't do that is packages are global - at least not without a lot of hassle. That's something I working to resolve in my package manager. The cool thing about any package manager is that it's optional - you can choose to use it or not, or use it for some packages and reference others manually like before.
  15. Vincent Parrett

    Farewell Rx10.4.2

    Even if some are user error and some are duplicates, that's still a staggering number of issues in a week since the release.
  16. Vincent Parrett

    Delphi Package Manager - choices?

    Interesting, I hadn't seen this before (and I thought I had seen every delphi package manager!). Can't really make heads or tails of it though - not quite sure how it works. The docs are a little out of date - the project is still actively being worked on (source code here) - I'm currently working on project group support, resolving package conflicts between projects - anyone familiar with nuget would understand where I am heading This is what working with an individual project looks like 🤣 thought you were talking about package managers, not a promotional vehicle. I'm skipping D11 so no pain this time - but I am working hard to get DPM usable for everyone - that said, I have a day job that takes most of my time, so contributions and collaboration is welcomed 😉
  17. procedure UpdateTheme(Obj: TFrame); var objAsIThen : ITheme; begin If Supports(Obj, ITheme, objAsIThen) then objAsITheme.UpdateTheme; end;
  18. Vincent Parrett

    Generic Type Inference

    I'm open to suggestions - but really this is a Delphi compiler issue and I'm not sure what else I could do to work around it.
  19. Looking at my unrelsolved issues from 10.4.2 and earlier.. 12 might be optimistic 🙄
  20. And another 5 for it to actually work properly.
  21. Vincent Parrett

    We use DUnitX and it discovers all our silly mistakes before release

    If only this were actually possible.. but your customers would not be happy with your application's performance - codecoverage tools are literally debuggers that put a breakpoint on ever line of code and record when the breakpoint is hit - it slows things down dramatically. So only really practical to use it against unit tests. Our unit tests for FinalBuiilder only take a few seconds to execute, but when running with code coverage it takes about 20 minutes - I tend to turn it on only when making major changes or writing new tests.
  22. If you are using Delphi 7 with the default memory manager then you should look at an alternative memory manager like FastMM or NexusMM which do a much better job of reducing memory fragmentation.
  23. Vincent Parrett

    thread-safe ways to call REST APIs in parallel

    This sort of task looks like something that OmniThreadLibrary would handle - but does require some study to get right (worthwhile imho). I created a wrapper over it's async/await feature that might be useful https://github.com/VSoftTechnologies/VSoft.Awaitable (depends on https://github.com/VSoftTechnologies/VSoft.CancellationToken and omnithread) An extremly naive example (with no queueing or thread limiting) - will probably not compile as mostly hand typed/copypasta 😉 with some details omitted for brevity. var RequestsInFlight : integer = 0; CancelTokenSource : ICancellationTokenSource; procedure DoRequest(const cancelToken : ICancellationToken; const param1 : string) var LParam1 : string; begin LParam1 := param1; //local for capture Inc(RequestsInFlight); TAsync.Configure<string>( function (const cancelToken : ICancellationToken) : string var restclient : TWhateverclient; begin //run rest request here //check cancelToken.IsCancelled or use the cancelToken.Handle with waitformultipleobjects etc restclient := TWhateverclient.Create; try result := restclient.Execute(); finally restclient.free; end end, token); ) .OnException( procedure (const e : Exception) begin //log error end) .OnCancellation( procedure begin //clean up end) .Await( procedure (const value : string) begin Dec(RequestsInFlight); //use result - runs in the calling thread. end); end; procedure StartRequests(const cancelToken : ICancellationToken) begin //Start the requests. for i := 0 to RequestCount - do ExecuteRequest(cancelToken, RequestParams[i]); //monitor requests inflight to know when it's done. end; procedure StopRequests; begin CancelTokenSource.Cancel; end; The cancellation part requires that your rest client supports cancelling requests somehow. Hope that helps.
  24. Vincent Parrett

    Image32 - 2D graphics library (open source freeware)

    Yes, well that can be an issue on some projects - people ask for all sorts of things, when I don't have time I'll slap a `PR Invited` label on it and then... nothing - I guess the feature wasn't that important.
  25. Vincent Parrett

    Image32 - 2D graphics library (open source freeware)

    I see SF is using git now.. that's a plus - but that site hurts my eyes with a bunch of other irrelevant rubbish on each page - won't be signing up (can't remember if I ever did before)
×