Jump to content

M.Joos

Members
  • Content Count

    57
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by M.Joos


  1. I don't think there is an easy solution. If you really wanna go that route, you would need to intercept the instance creation process by e.g. overwriting the NewInstance method of your FrameXY class. Within that you could then add each created instance into a class var array or a class var TList. You could then e.g add a class procedure "SetLanguage" to your class from within you could iterate over all your instances and delegate this call to a regular instance method.


  2. 3 hours ago, Rollo62 said:

    @vfbb

    Great, getting better with every build :classic_cheerleader:

     

    Could you please clarify some basic internals, since I haven't looked into this too much ?

    FMX has the drawback that it repaints the whole screen, even when only a small fraction of the screen has changed.

    How is the screen painting handled in Skia controls ?

    Is the control handled by Skia external library, or does it still behave like the original FMX ?

     

    Maybe Skia completely replaced the FMX rendering engine, and is optimized after that for the whole FMX controls, or

    the Skia rendering engine is used for their controls only, which leads to optimized drawing performance only for these controls, or

    Skia can not optimize the general FMX behaviour, but it can optimize within FMX's limits.

     

    Well, original FMX canvases are very different depending on the platform. While for Android FMX repaints the whole screen, on Windows FMX only repaints the parts that need to be redrawn. In addition to what Vinicius answered, Skia4Delphi is indeed faster on most platforms, especially Android and has a lot of other advantages. But to answer your question, no, Skia4Delphi renders all controls even if only a small fraction has changed. I myself had the same question, and was thinking that it would be more efficient to only render the parts that have changed, but appraently Vinicius and his brother have done some tests and this was not the case. Implementing "dirty region" repainting within the FMX painting framework is not a trivial task - I have looked into it myself, and have abandoded this project for myself (or postponed at least).

    • Like 1

  3. 2 hours ago, Vandrovnik said:

    Migration Tool copied registry entries from D 10.4.2 to D 11? There is a button "Version upgrade" in Migration Tool during restore, which must be clicked (or manually disable "some" items in the list).

    Thanks for the hint - indeed, I fiddled with the migration tool - I think it's usability is very bad. I will look into it, and maybe jsut need to reinstall - haven't done much anyway.


  4. Last week I sucessfully installed D11.  Since then I continued to work with D10.4.2 until today when I tried to start up D11 again. Now I received the follwoing error:

    image.png.7957ef3fea7b4eb26757cc3dd2fc38dd.png

    Confirming this error dialogs leads to many more with similar messages: D11 is trying to load D10.4.2 packages. Does anybody have any good idea why this happens?


  5. From an old blog post from Allen Bauer (https://blog.therealoracleatdelphi.com/2009/09/:

    "

      • All eligible class constructors and class destructors are invoked in sequence with unit initialization and finalization, respectively.
      • If a given class constructor or destructor is eligible to be invoked (ie. it was linked into your application), it will run immediately before the initialization section for the unit in which the class is implemented. The class destructors will be invoked immediately after the finalization section for the unit in which the class is implemented.
      • Class constructors in a given unit are generally invoked in the same order of declaration, except in cases described below. Class destructors are invoked in reverse order from the class constructors.
      • For an ancestor class declared in the same unit, its class constructor will be invoked before the descendant class constructor and the class destructor is invoked after the descendant class destructor.
      • If the implementation of given class constructor references another class in the same unit with a class constructor, the referenced class’ class constructor will be invoked before the current class’ class constructor. If the references are cyclic (ie. they reference each other in their class constructors), then they are invoked in reverse order of declaration. This means that there can be cases where a class constructor can reference an “unconstructed” class.
      • Ancestor classes from external units used in the interface section are guaranteed to already have their class constructors run prior to any class constructors on descendant classes within the current unit.
      • Unit cycles can break down the deterministic nature of the above rules in the same manner as unit initialization and finalization. However, for a given unit, it is guaranteed that all the class constructors declared within in it will have already run immediately before the initialization section runs. Congruent to this rule is that it is guaranteed that all the class destructors will run immediately after the finalization section.
      • Dynamically loaded packages, using LoadPackage. Because there is no way to know exactly which classes are going to be used, just like there is no way to know which units are going to be used, all class constructors and destructors along with all unit initialization and finalizations are invoked according to the above rules.

    Other rules about their use are:

      • You do not have to declare a class destructor if you declare a class constructor, and vice versa.
      • They cannot be virtual, dynamic or message.
      • They cannot be explicitly called.
      • They cannot have any parameters.
      • They do not have to be called Create and Destroy. (ie. Init and Fini are equally valid names).

    With this implementation, it was easier to leverage the same table that the compiler creates for unit initialization and finalization. It satisfies this requirement: “Called automatically to initialize the class before the first instance is created or any static members are referenced.” Issues with cycles are also clearly warned against in VB.NET and C#: “Avoid circular references in Shared … since it is generally impossible to determine the order in which classes containing such references are loaded.”

    Another benefit is that since it is running during the initialization/finalization phases, any threading implications are no different than the existing rules regarding unit initialization and finalization."

     

    What we don't know is, if the compiler behavoiur has changed since then.

    • Like 2
    • Thanks 1

  6. 3 hours ago, Anders Melander said:

    While this isn't related to your threading problem, it seems you are processing the bitmap by column instead of by row. This is very bad for performance since each row of each column will start with a cache miss.

    I think you will find that if you process all rows, transpose (so columns becomes rows), process all rows, transpose again (rows back to columns), the performance will be significantly better. I have a fast 32-bit (i.e. RGBA) blocked transpose if you need one.

     

    Another thing to be aware of when multiple threads read or write to the same memory is that if two threads read and write to two different locations, but those two locations are within the same cache line, then you will generally get a decrease in performance as the cores fight over the cache line.

    Indeed, this is then called "false sharing" and is very well explained from Microsoft's C++ Herb Sutter with an overview here: https://herbsutter.com/2009/05/15/effective-concurrency-eliminate-false-sharing/


  7. 7 minutes ago, aehimself said:

    I already started to experiment with the TReader component, unfortunately OnCreateComponent will only let me to use a different constructor other than the default. If the component is not created in the handler it will be created anyway.

    This thing is still a mess to me though... how do I specify WHERE the new components will be created...? As it needs a stream I need to get it from the executable - I guess it will be stored as a resource...?

    I'm only at the beginning. I'll find the answers soon enough.

     

    This is actually a really neat idea. As the TReader method will create the components anyway I suppose the memory usage will be close to equal anyway. As a huge bonus, I know how to create a new form instance 🙂

     

    An other good idea. Tags are - unfortunately though - already in use in said project 😞

     

     

    I'll dig into the TReader a little bit so I'll have a basic understanding of how it works / what it does. It never hurts to know something, you never know when you'll need such a thing.

     

    Thank you all for your answers!

    For inspiration you may also look into this excellent answer from Uwe Raabe on Stackoverflow on a related question: https://stackoverflow.com/questions/47347578/manually-skip-a-component-from-being-created-from-the-dfm

    which also shows a hacky way to prevent components from getting created. I guess Uwe wasn't aware of his answer more than 3 years ago 😉

    As for loading the dfm from the resource that's in the executable have a look at http://docwiki.embarcadero.com/Libraries/Sydney/de/System.Classes.TStream.ReadComponentRes

    • Thanks 1

  8. I guess it is theoretically possible to shoehorn Delphi's streaming mechanism to do what you want. Essentially you could just reread your form with an adjusted TReader. Specifically you would not want for the components to be recreated. Have a look at

    the TReader events, specifically TReader.OnCreateComponent

    One problem though is how to "skip" rereading of components as you want to only select a number of components.

     

     

    • Thanks 1

  9. 1 hour ago, Arnaud Bouchez said:

    DWSScipt is my favorite.
    Its syntax is modern, and its implementation is very clean. It even has a JIT!

    The problem is that it is not cross-platform yet.

     

    The veteran PascalScript is my favorite if cross-platform is needed.

    It is stable, and widely used since years.

    About DWscript: You said it is not cross-platform yet , does that mean that someone is already working on making it cross platform? And what is it that makes it so Windows specific?


  10. For those of you who are more interested about the differences in class vs. interface inheritance, here is a transcript from several live chats with the founders of Delphi:

    http://edn.embarcadero.com/article/20384

    For those that don't want to read all (but it intersting anyway) here is the gist from Chuck Jazdzewski :

    Quote

    "The reason is a little complicated, but it is for compatibility with COM. COM does not assume that if you implement a descendent of an interface that it qualifies for an implementation of the descendent. This is because you are allowed to implement the ancestor completely different from the ancestor. To support this we cannot just assume you have implemented an ancestor. Also, you might not want to support the ancestor, only the descendent. If we always assumed you implemented the ancestor as well there would be no way to declare you didn't want the ancestor."

     

    • Like 1
    • Thanks 2
×