Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 12/09/24 in Posts

  1. I can of course not say I made this as the channel header tell. My contribution is very minor. But I want to share this story anyway. And hopefully someone can use or even contribute to Bold framework. Yesterday I committed a bunch of updates to Bold for Delphi https://github.com/Embarcadero/BoldForDelphi/tree/develop History of Bold for Delphi Bold for Delphi is a Model-Driven Architecture (MDA) framework developed in the late 1990s by BoldSoft, a Swedish company. Jan Norden was one of thefounders. Bolds main focus was to enable developers to create business applications by defining the application's data structure and business rules at a higher abstraction level, rather than writing low-level code manually. In 2002, Borland acquired BoldSoft, and Bold for Delphi was included in Borland’s release of Delphi 7 Architect. This made the framework more accessible to Delphi developers and encouraged its adoption within the Delphi ecosystem. However, after Borland sold its development tools division to CodeGear. Later Embarcadero took over. Now Bold for Delphi was no longer actively developed as part of the Delphi IDE. Bold for Delphi was used in many hundreds of projects with Delphi 7. Developers was now abandoned with no support from Code/Gear/Embarcadero. But development never stopped completely. Before Borland bought Boldsoft Ahola Transport, a Finnish company bought source-code license from Boldsoft. They developed an in-house ERP application Attracs for transport business now with full access to Bolds source. Around 2010 Attracs company hired a consultant Daniel Mauric from Serbia mainly because hes deep knowledge about Bold. This turned out to be a very good move. Now the development of Bold for Delphi really gained momentum. Daniel has made countless optimizations, bug fixes but also some completely new additions to Bold. But one problem was that Bolds Intellectual Property (IP) was still hold by Embarcadero. We couldn't legally publish our changes even if we want to cooperate with other developers around the source. In May 2012 I Roland Bengtsson made a petition to release Bold with opensource license. And the petition got attention. After a while when I contacted Embarcadero we agreed on a meeting and it looks promising. But later Embarcadero changed their mind and set up unreasonable conditions like all changes with source remain Embarcaderos IP. And the years passed... Delphi product manager at Embarcadero changed to Marco Cantu. When I discussed this issue with him I noticed quickly he had a more realistic view on this. Marco realized that the only way forward was to make Bold opensource. I have no idea what happened behind the scenes but Marco convinced Embarcaderos management and published this blog 22 Sep 2020 So a big thank you to @Marco Cantu for his work! Our company now renamed to Ahola Digital continue to work with our main Bold application Attracs. Our Bold source continue to improves thanks to Daniel Mauric. These changes are now published in repository above. There is a lot more to do. Many inhouse tools and source are not commited in to repository yet. Main Purpose of Bold for Delphi The primary purpose of Bold for Delphi is to simplify the development of business applications by automating data persistence, object lifecycle management, and business rule enforcement. It emphasizes separation of concerns by letting developers focus on defining the model (business logic and rules) while the framework handles boilerplate tasks such as: Object-relational mapping (ORM) Automatic data synchronization with a database Real-time data updating in the user interface Implementation of business logic constraints and rules It essentially follows the MDA approach, where application logic is derived from the model, reducing repetitive code writing and increasing consistency across applications. Main Components of Bold for Delphi Bold Model and UML Integration: Developers define the application’s data model using UML diagrams. Rational Rose is supported but unfortunately IBM have The model is then translated into Delphi classes with associated behavior and persistence rules. Bold Business Classes: These are Delphi classes generated from the UML model. They represent the business objects, containing properties, associations, and behavior logic. Bold Object Layer: Handles the lifecycle of objects, including creation, deletion, and memory management. Ensures real-time synchronization between the application and the database. Bold Persistence Layer: Manages object persistence by mapping the Bold business classes to database tables. Abstracts database interactions, so developers don't need to write SQL manually. Bold Expression Language (OCL): A query and constraint language similar to SQL but designed for object models. Used to express rules, queries, and computed attributes in the model. Bold User Interface Components: Data-aware UI components, such as grids and editors, are bound directly to the Bold object model. Provides real-time updates as the model changes. Bold Subscription System: Ensures the UI and other dependent components react automatically when model data changes. Key Advantages of Bold for Delphi Rapid Development: Reduces repetitive coding by generating classes and managing persistence automatically. Model-Driven Approach: Ensures the application's logic and design are consistent and well-structured. Scalability: Supports complex object relationships and business rules with minimal effort. Real-Time Updates: Automatically synchronizes UI and data layers for responsive applications. Example Use Cases Bold for Delphi is particularly suited for: Enterprise resource planning (ERP) systems Customer relationship management (CRM) systems Applications with complex domain models and business rules It remains a valuable tool for Delphi developers who need to build sophisticated, model-driven applications efficiently. If you are interested to contribute or just have a question about Bold do not hesitate to ask me. I would do my best to help!
  2. No, because the parameterless TObjectList<T> constructor sets OwnsObjects to True. And that is nothing new but also already was the case in the old TObjectList from Contnrs.pas I am glad I can use Spring4D and have several flavors of multimaps at my disposal
  3. Remy Lebeau

    for loop variable value after the loop

    W1037 FOR-Loop variable '%s' may be undefined after loop (Delphi) Also see: What is The Loop Variable After a For Loop in Delphi?
  4. dummzeuch

    for loop variable value after the loop

    A for loop is not a while loop with inc. the compiler might create code that counts down to zero rather than up, if the variable is not used inside the loop. Edit: Or it might even completely unroll the loop doing away with the variable altogether. But it does not matter: Relying on an undocumented implementation detail is a bad idea, regardless of whether it works or not. The next compiler version or a different compiler e.g. for a different platform might change that detail.
  5. JohnLM

    The Advent of Code 2024.

    Yes, I agree about the solutional changes. But I sometimes veer past it in my hair-pulling while debugging alternative solutions. Oh, I just started Day-2, half an hour ago. I've got up to the point of generating the random values for filling in the levels list and a few other tid-bits. And, now about to start the real challenge of how to determine what level(s) are safe and unsafe. Should take me many more hours to solve. . . can't wait!
  6. Cristian Peța

    for loop variable value after the loop

    I think this should be reported. Something like this I discovered in FastReport and it surfaced in rare circumstances. First when I reported it was ignored till I come with a case to reproduce. Because this, the report should have also the link to documentation.
  7. DelphiUdIT

    Import .NET Assembly

    The structure was changed and reported to the release notes: The new field "val" is an Hcpar type. It contains the old "HPar" members ("par" pointer) and "&type". So, while before it was possible to access the value of the Tuple directly, now it is accessed via "par": var fDeviceHandle: HTuple; ----- //New way if fDeviceHandle.val.par.l <> 0 then ..... //Old way if fDeviceHandle.val.l <> 0 then Other important thing is that the float field "f" doesn't exist anymore .... (I dont' know any official notes about that). This should not have a major impact on the code, since "f" is a further definition of an identically field type "d", so replacing "f" with "d" in the code will make both the old and new code compile without errors and without any {$IFDEF... This is the first time in many years that they have changed the interface to a basic structure like HTuple making the code totally incompatible with the past. In the past they had changed some definition of some parameters, but by changing only the declaration of the variable everything was back to normal without any change in the "procedural" code (I remember something about the parameters of the "get_mposition" function for example). What I did: 1) Copy all include files (except Halcon.h) in a single directory wherever you want; 2) Run CHET (this is my example): You will see some errors about include files not found ... change the relative path in the source originated the error. Retry the RUN, and go redoing the same until all errors are gone. After that you have the PAS file. Now You have to change (in reality move at the top of file) some declarations, for obviuos reasons that you will see ... is more complicated to explain that to do. Some change to definitions (like NULL), and you should also modifiy some declarations that point to wrong DLL, refer to my original wrapper searching for "LIB_MVTEC_SYSTEM". Without this you will have a runtime error in the application if you use some system functions. A little bit too: you must delete (or divide) some very long commented lines: That's all.
  8. You're better off doing something like function myfunc(const InVal: String; out OutVal: Double): Boolean; Return True if the value was set and false if not. There are other ways to handle this but the worst way is a magic value in Double. There's no reason to do that when it is so easy to indicate explicitly whether or not the value is valid.
  9. Glenn Dufke

    Registration Limit

    That's not the correct place to contact. Now, when you have an active update subscription - besides always having access to the latest Delphi releases which is important nowadays - getting registration bumps is pretty straight forward and resolved quickly through support. When your active update subscription is expired, which it is in your case according to your initial post, you would have to contact your reseller (If you got your license through that in your home country) or Embarcadero sales directly to get the license bumped. They might offer you a renewal or new license depending on your status, but it isn't a requirement, you can decline the offer and just request a license bump. https://www.embarcadero.com/company/contact-sales As it is a perpetual license, you can keep continuing using that version. You can manually check your registration limit yourself if you need to reinstall in the future. I wrote a guide here: https://docs.code-kungfu.com/books/licensing-and-registration/page/how-to-check-your-registration-limit Hope it helps.
  10. Anders Melander

    Profiler for Delphi

    Here's a quick update on the two issues @Allen@Grijjy encountered: The problem with the overlapping segments has been worked around in code by ignoring conflicts caused by the .tls segment. Incidentally, Allen found an old QC report about a similar issue (RSP-12824). Unfortunately, that issue was closed by someone who apparently doesn't understand what the map file segment offset values signify. Regardless, an overlapping .tls segment now only produces a warning message. The filter problem turned out to be a copy/paste problem. Allen had copied his map2pdb parameter list from a post here, and somewhere along the way, two invisible zero-width no-break space characters (#$F0FF) got inserted into the string he pasted. So what looked like '-include:0001' was actually '-include:000'#$F0FF#$F0FF'1'. I've been bitten by that one myself a few times when I've copied code from a browser.
  11. type TObjectDictionaryWithDuplicateObjects<K,V:class> = class(TObjectDictionary<K, TObjectList<V>>) public procedure AddObject(const Key: K; Value: V); end; procedure TObjectDictionaryWithDuplicateObjects<K, V>.AddObject(const Key: K; Value: V); var list: TObjectList<V>; begin if not TryGetValue(Key, list) then begin list := TObjectList<V>.Create; Add(Key, list); end; list.Add(Value); end;
  12. You always can use a TObjectDictionary<String, TObjectList<TMyClass>>. That way you can have multiple instances of TMyClass assigned to the same string key.
  13. Does anyone know of any Delphi libraries that tackle directed acyclic graphs (DAG) and layout algorithms? In particular I'm interested in a layered layout (Sugiyama's algorithm).My goal here is to produce a visual representation of a target dependency graph - something like this. [Clean] [Build] |________| | [Rebuild] [Sign] |_________| | [Deploy] It seems like every other language out there has tons to choose from (open source to $$$$ commercial), but so far I have found nothing useful for Delphi. Of course I could attempt to translate another library to delphi.. but I was hoping to avoid that if possible .
  14. Stefan Glienke

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

    Working on some better integration and result format that can be consumed by state of the art tooling such as https://github.com/danielpalme/ReportGenerator or https://github.com/marketplace/codecov but thats a side project that I don't spend much time on. Also still fighting some spurious crashes with DelphiCodeCoverage that result from it putting its breakpoints where it really should not (I suspect some incorrect debug information from the map file).
  15. Anders Melander

    Profiler for Delphi

    I'm once again in need of a good 64-bit profiler so I've been looking into what would be needed in order to generate PDB files from whatever Delphi can produce. First of all it seems the only good debug info source on the Delphi side is the MAP file and the format of that seems a bit unstable. However since it's a text file it should be easy to adapt to any changes in it. Then there's the PDB file format. The only good and reliable documentation of that appears to be what the LLVM project has produced. Microsoft at one time published some of their source code for dealing with PDB files but since then the repository appears to have gone into limbo and they have not kept it up to date like they said they would. Anyway, in short, a PDB file is a MSF container file consisting of a number of streams containing the different debug info in CodeView format. The MSF format is pretty simple and since I only need to produce PDBs I don't need to bother about decoding MSF files. That leaves the PDB CodeView streams. Thanks to the LLVM documentation their format are known. However, after reading the LLVM source, it has become clear that it would be a huge task to implement all the different stream formats and all the different data types. I guess one could get by with a subset but it doesn't really seems worth the effort to create something that only works sometimes. The biggest problem however is that I would be implementing something based on a port of a third party's interpretation of Microsoft's old (and by now out of date) source. PDB is an internal VS format and Microsoft has stated that it can, and mostly will, change with each new version of VS. For this reason they provide the Debug Interface Access API for those that need to read PDB files. Unfortunately there's no (known) corresponding API to write PDB files. PDB support is important for the LLVM project (they too would like VTune to work with their output ) so they appear to be trying to keep up with the PDB changes and since they obviously have more resources for that task than I do I've decided to aim for a solution that piggybacks on their work instead of rolling my own. The solution I'm going to try is to parse the MAP file in Delphi, write out the relevant information in YAML format and then use the LLVM llvm-pdbtil tool to convert the YAML to PDB. Sounds easy and it probably would be except for the fact that the required YAML format is undocumented... The llvm-pdbutil yaml2pdb documentation does a handwave with "The YAML syntax is not described here. Instead, use llvm-pdbutil pdb2yaml and examine the output for an example starting point.". Lazy bastards Anyway, this was just a dump of the information I've been able to gather on the topic of generating PDB from Delphi in case I burn out before completing anything usable.
  16. This is the best solution I have found so far. It might be of use to someone else. I call GetMemoryManager to retrieve the FastMM memory manager and keep a reference to it. I then register my own memory manager. I only provide new implementations of GetMem and FreeMem. For all other calls I just forward the call to the FastMM memory manager. In my implementation of GetMem, I first delegate the call to the FastMM memory manager. I then call the FastMM function DetectClassInstance. {Returns the class for a memory block. Returns nil if it is not a valid class} function DetectClassInstance(APointer: Pointer): TClass; I was actually not expecting this to work, as I thought that calling this function at this stage would be way too early, and the call would always return nil. But to my pleasant surprise, it works. It returns the TClass for the just allocated memory block. 🙂
  17. uses Spring.VirtualClass; procedure NotifyFree(const Self: TObject); var freeInstance: TFreeInstance; begin freeInstance := GetClassData(Self.ClassParent).FreeInstance; Writeln('Object of class ', Self.ClassName, ' destroyed'); freeInstance(Self); end; var vc: TVirtualClasses; o: TObject; begin vc := TVirtualClasses.Create; try o := TObject.Create; try vc.Proxify(o); GetClassData(o.ClassType).FreeInstance := NotifyFree; finally o.Free; end; finally vc.Free; end; end.
  18. Stefan Glienke

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

    Among a few minor things it allows for a more declarative approach of writing tests by using attributes to provide the test data. In a classic DUnit test if you have to test an algorithm with 20 different value combinations you need to write 20 tests (either as different methods or by putting them into one test). However DUnit can be pimped to allow the same so you don't need to migrate (*) - since DUnit is kinda abandoned development wise Vincent decided to roll his own library instead of modifying and possibly cleaning up the code from DUnit which dates way back. (*) I did that way back even before DUnitX existed: https://stackoverflow.com/a/9006662/587106 and later also put that into a unit of Spring4D. As you can see in the screenshot you have multiple tests shown although there is only one method declared the extension takes care of producing them so you can run them individually (if for example certain data produces a failure) while you are fixing it. Another thing (which personally never bothered me much) is that with DUnitX you can write testcase classes without inheriting from a base class (this can also be done with an extension for DUnit - did it but never put it anywhere because it was not useful for me). The last thing that I remember is the fact that DUnitX can do is have fixture setup/teardown - they only run once even if there are multiple tests in the class - classic DUnit runs Setup/TearDown methods before and after every single test - guess what? You can also plug that onto DUnit. My personal opinion: do automated unit tests but it does not matter what framework you are using. I use DUnit with the before mentioned extensions and we do so at work because its powerful and compact. And regardless which one you are using - use them with TestInsight and make them part of your CI. 😉
×