Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 11/08/18 in all areas

  1. Primož Gabrijelčič

    Smart Mobile Studio 3.0.1

    Smart Mobile Studio 3.0.1 is released This is the first release since 3.0. Biggest new feature is TW3LeafletMap, which lets you use OpenStreetMap. As it does not need API keys (like TW3GoogleMaps), it’s really fast and easy to use: Create a project Add a TW3LeafletMap -control on the form Set AutoCreateMap to true on the map control Please see the changelog at the end of this post. Installers Smart Mobile Studio installer Free command-line compiler Portable installation Smart Mobile Studio can also be downloaded with the SmartUpdate utility. Select the MASTER -channel for the official version. Changes since 3.0 RTL EventManager Add procedure AllowDefaultAction, that can be called from OnClick when the default action should happen. For example: To let the virtual keyboard to pop up from OnTouch. Bug fixes Native scrolling was prevented if scrolling was done from an unknown element. Prevent an extra OnClick from being fired on mobile devices. TW3ListView: Bug fix to resizing of items. Bug fixes to GeoLocation. Also update the Geolocation demo. Deprecate PhoneGapAPI’s JGeolocation functions. SmartCL.GeoLocation.pas should be used instead. Fix slider so that OnMouseDown, OnMouseUp and OnMOuseMove can be used. TW3TabControl Tab’s OnShow was sent twice for the first tab SmartCL.RegEx moved to System.RegEx. Also fixed TW3RegEx.Exec to return a proper empty array instead of nil. Bug fix to Chart: TSeriesData.Refresh now also updates the X axis SmartCL.Effects: Properly handle padding and margins while doing effects. Fix to css-files for selected text in TW3Edit and TW3Memo TW3Grid Added TW3ImageColumn Add Alignment-property to TW3ColumnHeader Added a new OnCellControlCreated-event, which fires when a button, toggle, progress bar or image is created. Makes it possible to change properties of the control easily. Added support for OpenStreetMap using the Leaflet library New control: TW3LeafletMap New featured demo: LeafletMap IDE/Compiler Fixed search path compilation issues Relative and absolute paths are working now Compiler is updated when search path is modified in options $I will look for include file in the project folder first $R supports absolute paths, wildcards, folder name extension and ($Libraries) macro Fix exceptions in Search Upgrade to UPX 3.95
  2. Everything is the best tool ever. I use it multiple times a day and I find every file i need. In one second.
  3. Renaud GHIA

    We need a Delphi Language Server

    I just discovered this project: https://github.com/CWBudde/DWScript-Language-Server
  4. David Heffernan

    Custom Managed Records Coming in Delphi 10.3

    There's nothing to switch off. You choose to switch it on on a type by type basis.
  5. Uwe Raabe

    Managing Version Information Across Builds

    Project Magician has an option to strip all version info from child configurations. That way the values from the base (platform if you have non-Windows targets) configuration are effective. It doesn't hinder you to edit any child values, though - they just have no effect any more. https://www.uweraabe.de/Blog/2018/05/17/keep-your-project-files-clean-with-project-magician/
  6. Just wanted to share my last blog post on changes to the Delphi language in 10.3: http://blog.marcocantu.com/blog/2018-november-custom-managed-records-delphi.html Still a bit rough in some details, but a very handy feature overall.
  7. When writing libraries you sometimes want to provide users (that is, programmers) with a flexible API. If a specific part of your library can be used in different ways, you may want to provide multiple overloaded methods accepting different combinations of parameters. For example, IOmniPipeline interface from OmniThreadLibrary implements three overloaded Stage functions. function Stage(pipelineStage: TPipelineSimpleStageDelegate; taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload; function Stage(pipelineStage: TPipelineStageDelegate; taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload; function Stage(pipelineStage: TPipelineStageDelegateEx; taskConfig: IOmniTaskConfig = nil): IOmniPipeline; overload; Delphi’s own System.Threading is even worse. In class TParallel, for example, there are 32 overloads of the &Forclass function. Thirty two! Not only it is hard to select appropriate function; it is also hard to decode something useful from the code completion tip. Check the image below – can you tell which overloaded version I’m trying to call? Me neither! Because of all that, it is usually good to minimize number of overloaded methods. We can do some work by adding default parameters, but sometimes this doesn’t help. Today I’d like to present an alternative solution – configuration records and operator overloading. To simplify things, I’ll present a mostly made-up problem. You can download it from github. An example type TConnector = class public procedure SetupBridge(const url1, url2: string); overload; procedure SetupBridge(const url1, proto2, host2, path2: string); overload; procedure SetupBridge(const proto1, host1, path1, proto2, host2, path2: string); overload; // procedure SetupBridge(const proto1, host1, path1, url2: string); overload; end; This class expects two URL parameters but allows the user to provide them in different forms – either as a full URL (for example, ‘http://www.thedelphigeek.com/index.html’) or as (protocol, host, path) triplets (for example, ‘http’, ‘www.thedelphigeek.com’, ‘index.html’). Besides the obvious problem of writing – and maintaining – four overloads this code exhibits another problem. We simply cannot provide all four alternatives to the user! The problem lies in the fact that the second and fourth (commented out) overload both contain four string parameters. Delphi doesn’t allow that – and for a good reason! If we could define both at the same time, the compiler would have absolutely no idea which method to call if we write SetupBridge(‘1’, ‘2’, ‘3’, ‘4’). Both versions would be equally valid candidates! So – strike one. We cannot even write the API that we would like to provide. Even worse – the user may get confused and may expect that we did provide the fourth version and they try to use it. Like this: conn := TConnector.Create; try conn.SetupBridge('http://www.thedelphigeek.com/index.html', 'http://bad.horse/'); conn.SetupBridge('http://www.thedelphigeek.com/index.html', 'http', 'bad.horse', ''); conn.SetupBridge('http', 'www.thedelphigeek.com', 'index.html', 'http', 'bad.horse', ''); // this compiles, ouch: conn.SetupBridge('http', 'www.thedelphigeek.com', 'index.html', 'http://bad.horse/'); finally FreeAndNil(conn); end; Although the last call to SetupBridge compiles, it does something that user doesn’t expect. The code calls the second SetupBridge overload and sets url 1 to ‘http’ and url 2 to (‘www.thedelphigeek.com’, ‘index.html’, ‘http://bad.horse/’). Strike two. The output of the program proves that (all ‘1:’ lines should be equal, as should be all ‘2:’ lines): Last but not least – the API is not very good. When we need to pass lots of configuration to a method, it is better to pack the configuration into meaningful units. So – strike three and out. Let’s rewrite the code! A solution Records are good solution for packing configuration into meaningful units. Let’s try and rewrite the API to use record-based configuration. TURL = record end; TConnector2 = class public procedure SetupBridge(const url1, url2: TURL); end; Much better. Just one overload! Still, there’s a problem of putting information inside the TURL record. I could add a bunch of properties and write: url1.Proto := 'http'; url1.Host := 'www.thedelphigeek.com'; url1.Path := 'index.html'; url2.URL := 'http://bad.horse/'; conn2.SetupBridge(url1, url2); Clumsy. I have to declare two variables and type lots of code. No. I could also create two constructors and write: conn2.SetupBridge(TURL.Create('http', 'www.thedelphigeek.com', 'index.html'), TURL.Create('http://bad.horse/')); conn2.SetupBridge(TURL.Create('http://www.thedelphigeek.com/index.html'), TURL.Create('http://bad.horse/')); That looks better, but still – in the second SetupBridge call both TURL.Create calls look completely out of place. Do I have to pull back and rewrite my API like this? TConnector = class public procedure SetupBridge(const url1, url2: string); overload; procedure SetupBridge(const url1: string; const url2: TURL); overload; procedure SetupBridge(const url1, url2: TURL); overload; procedure SetupBridge(const url1: TURL; const url2: string); overload; end; Well, yes, this is a possibility. It solves the problem of supporting all four combinations and it nicely puts related information into one unit. Still, we can do better. Operators to the rescue! I’m quite happy with the Create approach for providing an information triplet. it is the other variant – the one with just a single URL parameter – that I would like to simplify. I would just like to provide a simple string when the URL is in one piece. To support that, we only have to add an Implicit operator which converts a string into a TURL record. (Another one converting TURL into a string is also helpful as it simplifies the use of TURL inside the TConnector class.) Here is full implementation for TURL: TURL = record strict private FUrl: string; public constructor Create(const proto, host, path: string); class operator Implicit(const url: string): TURL; class operator Implicit(const url: TURL): string; end; constructor TURL.Create(const proto, host, path: string); begin FURL := proto + '://' + host + '/' + path; end; class operator TURL.Implicit(const url: string): TURL; begin Result.FURL := url; end; class operator TURL.Implicit(const url: TURL): string; begin Result := url.FURL; end; Simple, isn’t it? The implementation uses the fact that TConnector has no need to access separate URL components. It is quite happy with the concatenated version, created in the TURL.Create. This allows us to provide parameters in a way that is – at least for me – a good compromise. It allows for a (relatively) simple use and the implementation is also (relatively) simple: conn2 := TConnector2.Create; try conn2.SetupBridge('http://www.thedelphigeek.com/index.html', 'http://bad.horse/'); conn2.SetupBridge('http://www.thedelphigeek.com/index.html', TURL.Create('http', 'bad.horse', '')); conn2.SetupBridge(TURL.Create('http', 'www.thedelphigeek.com', 'index.html'), TURL.Create('http', 'bad.horse', '')); // this works as expected: conn2.SetupBridge(TURL.Create('http', 'www.thedelphigeek.com', 'index.html'), 'http://bad.horse/'); finally FreeAndNil(conn2); end; The output from the program shows that everything is OK now:
  8. This is something I struggle with a lot and there has to be an easier way?! I have many projects that have both debug and release configs for win32 and/or win64 targets. Is there a simple way to have the version information THE SAME across all of these? There config options for all builds, all targets, and all configurations, but no matter what I do they all appear to be maintained separately?! All I want it to be able to set my version info in the Project | Options | Version Info | All Configurations section, and have it JUST WORK...
  9. Fellow Delphi Developers! You can find a lot of modern VCL and FM styles here: https://www.delphistyles.com Regards, DelphiStyles
  10. Zacherl

    Aligned and atomic read/write

    Well, okay seems like the Intel SDM needs to be updated. Did anybody test the same szenario with multi-threaded atomic write operations (`lock xchg`, `lock add`, and so on)? Could imagine different results in terms of performance here. Anyways .. I guess the original question is answered. To summarize this: 1 byte reads are always atomic 2/4/8 byte reads are atomic, if executed on a P6+ and fitting in a single cache line (any sane compiler should use correct alignments by itself) For multi threaded read-modify-write access, read this (TLDR: you will need to use `TInterlocked.XXX()`): https://stackoverflow.com/a/5421844/9241044
  11. Tommi Prami

    Aligned and atomic read/write

    Check out this fabulous book about memory alignment and performance.
  12. Primož Gabrijelčič

    Aligned and atomic read/write

    Can you please give me some references that proof your statement I can confirm (from experience) that this is indeed true. I cannot find any definitive document about that, but it looks like since 2011/12 unaligned access doesn't hurt very much (at least on Intel platform). Some 3rd party posts that confirm my finding: https://lemire.me/blog/2012/05/31/data-alignment-for-speed-myth-or-reality/ https://www.reddit.com/r/programming/comments/2la6qc/data_alignment_for_speed_myth_or_reality/
  13. ByteJuggler

    fast file searching, what do you recommend, please?

    To make a general observation first: There's a reason why tools like "Everything" exists, and why TortoiseSVN (and TortoiseGit and TortoiseBazaar etc) has a cache built in, and/or why Windows itself creates search indexes etc. to speed searching in Explorer. And it all boils down to the same thing, the fact that searching the filesystem via the existing API's isn't particularly fast. The broad solution in all of the above cases is conceptually the same: Create an index or cache of the stuff you're trying to search. And so the answer to your question is then IMHO essentially the same: You have to create some sort of cache to speed the type of search you're doing and think about how that cache is to be maintained. In one of the solutions we've developed we basically wrote something basic but similar to "Everything" that hooks into the Windows filesystem change notifications to keep a cache updated, which is then used to find file locations vastly faster than trying to trundle over gigantic folder trees. Obviously this also means you get to own a new set of additional problems/responsibilities, e.g. dealing with cache integrity/consistency/reliability etc. but its possible to deal with these.
  14. Dalija Prasnikar

    Custom Managed Records Coming in Delphi 10.3

    Automatic invocation is the whole point of managed records. If they have constructors and destructors, you want them to run. Yes, you can do that manually, but then they would not be called managed records. If you don't want managed records, and you want to perform some initialization and finalization code manually, you can use plain record procedures. You don't need constructors and destructors in that case.
  15. In the MARS repository a new demo (check the Demos folder) is now available: https://github.com/andrea-magni/MARS/tree/master/Demos/EKON22 It is a project I created through the MARSCmd utility and used as a playground for my EKON 22 session, yesterday. There are a number of features showcased in this demo, from parameters passing to object/record/dataset serialization passing through FireDAC integration and MARS Client library components. To enable the FireDAC part of the demo, be sure to have a MAIN_DB FireDAC connection defined in your system, against the Firebird demo db (EMPLOYEEDB) or please adapt the simple SQL statements to your own database. I am available for questions or discussion. Sincerely, Andrea
  16. Andrea Magni

    Welcome!

    Welcome in this subgroup dedicated to MARS-Curiosity (MARS in short), a REST Library for Embarcadero Delphi! First of all I want to thank the Delphi Praxis team for the opportunity to have a dedicated subgroup here. MARS is an open source project, at the time I am writing this I am by far the main contributor. The project is hosted on GitHub ( https://github.com/andrea-magni/MARS ). This forum will supersede the G+ community and it is the right place where to ask questions about the project. If you actually find an issue with the library (and it is not a matter of knowing how to achieve something using the library's functionalities), please use the GitHub Issue tracker. Feel free to let me know your opinion about MARS as well as suggest new functionalities or changes in the library. I will be happy to hear from you all. Sincerely, Andrea
  17. Switch off the option to scroll to the newest message, Auto Scroll (F6), Fifth icon from the right on the top toolbar.
  18. Rudy Velthuis

    Custom Managed Records Coming in Delphi 10.3

    They don't intrduce automatisms you don't want. In fact, they now let you customize or even avoid the already existing automatisms (e.g. for records with managed content), allowing for better optimization. At the moment, normal, so called plain records (i.e. not M-records) are not managed. But records with managed content are already automatically managed using the usual (hidden) functions System._InitializeRecord, System_CopyRecord and System._FinalizeRecord. That management always takes place, and there (was) no way to get out of that. But these routines are slow and use TypeInfo. They must walk through that type info to determine which members must be initialized, refcounted, finalized, etc. at what moment. That takes time. With the new M-records, you can replace these routines by declaring a (default) constructor without parameters, a (default) destructor and a new Assign operator. These *replace* _InitializeRecord, _CopyRecord and _FinalizeRecord. So now you can selectively only initialize/copy/finalize what needs to be done. This saves time, as your code doesn't have to slowly walk/search the typeinfo to find what must be done for each member field. This is a possibility for manual optimization many people (including me) have asked for already. And it opens up new possibilities, like e.g. RAII. If you combine it with inline declared, block local variables, there are many possibilities.
  19. Edwin Yip

    Delphi SQL Formatter

    Try GExperts -> Editor Experts -> Paste String As. This is a gem from GExperts. Furthermore - you have 'Copy Raw Strings' which does the opposite.
  20. dummzeuch

    How to know that a file is not used by another program?

    Building on Lars Fosdal's answer: Let your external program generate the file under a different name (or in a different location on the same drive) and when it is done, rename/move it to where your program expects it.
  21. Lars Fosdal

    New in 10.3: IDE UI Improvements in the Main Window

    I got 32Gb RAM, and I rarely go above 18-20Gb - so I got a lot of RAM to spare for IDEs excessively wasting memory.
×