Robert Gilland 5 Posted April 26, 2023 I am trying to create a function that creates a class at runtime lie this: function CreateDescentantClass( pcAncestorClass : TClass; const psDescendentClassName : String ): Class; begin Result := psDescendentClassName of pcAncestorClass; end; Is this possible? I am using Delphi Alexandria Share this post Link to post
FPiette 383 Posted April 26, 2023 Not directly possible. If you explain why you think need that, and given an example of usage (the call!), maybe we can give a better answer... Share this post Link to post
PeterBelow 238 Posted April 26, 2023 2 hours ago, Robert Gilland said: I am trying to create a function that creates a class at runtime lie this: function CreateDescentantClass( pcAncestorClass : TClass; const psDescendentClassName : String 😞 Class; begin Result := psDescendentClassName of pcAncestorClass; end; Is this possible? I am using Delphi Alexandria Basically you have to enumerate all classes defined in the application and check their classname and ancestry to find one that matches the criteria you pass to the function. So it is misnamed: it does not creaste a class, it searches for one and returns it. The enumeration can be done using the advanced run-time type information support provided by the System.Rtti unit. You start with a variable of type TRttiContext, which has a GetTypes method to enumerate all types that have advanced RTTI info available. You check with the individual types IsInstance property whether it describes a class type, use the AsInstance property to obtain a TRttiInstanceType and use its methods and properties to examine the class to see whether it matches your criteria. There are two drawbacks to be aware of: RTTI generation can be disabled for individual units or even the whole application through compiler switches ($RTTI), so may not be available for 3rd-party classes you use, and RTTI can be used to examine the compiled executable and thus be considered a security risk. If you need this funktionality only for a limited set of classes it may be better to just create your own class registry and register all relevant classes in it in the initialization sections of the relevant units. Share this post Link to post
programmerdelphi2k 237 Posted April 26, 2023 https://en.delphipraxis.net/topic/4799-how-to-create-an-object-instance-from-its-class-name/ 1 Share this post Link to post
Robert Gilland 5 Posted April 26, 2023 Okay, the requirement is to build a Delphi form descendant from a pre-existing form class adding to it a set of component definitions sent to the Delphi Application in a stream. The Delphi Application has no prior knowledge on what these components are and where they will be placed. It does however receive a form name and form version for these components. The process is already running and working. But speed is a critical factor and there is a need to increase performance. As a result of this, my idea is to build a new form class, then store it locally in a component resource file. Using WriteComponentResFile and ReadComponentResFile functions. Only when the version of the set of component definitions change then to recreate this resource. Share this post Link to post
Brian Evans 105 Posted April 26, 2023 Find out where the performance is being lost. Dynamically creating a form instance and it's content like that should be quick. I could see it being slow if it was incrementally built in a way that causes endless events for things like resizing, drawing, layout and themes or something else causing cascading methods/events/etc that could be cleaned up. Share this post Link to post
David Schwartz 426 Posted April 27, 2023 A TForm is a class. It has some methods to stream in a definition of components that get instantiated on it. That's how the IDE works. Alternatively you can do the exact same thing in code. The .frm files are simply declarative descriptions of all of the objects, their relationships, and their property values saved from a previous session. If what you've got there isn't running at a comparable speed to what Delphi's IDE is able to do, then I'd guess there's a bottleneck with your code, because there's just not that much going on. Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called). I suspect that everything you need is already there. You just need to figure out how to best leverage it. Share this post Link to post
SwiftExpat 65 Posted April 27, 2023 12 hours ago, Robert Gilland said: The process is already running and working. But speed is a critical factor and there is a need to increase performance. Profiling that code is necessary to figure out which component is taking the time, as Brian Evans said above. I use one component which takes 23 ms to execute the create. That is a long time considering there are 5 instances on the form. My fix was to delay creation of the 4 instances not visible. Share this post Link to post
Fr0sT.Brutal 900 Posted April 27, 2023 9 hours ago, David Schwartz said: Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called). How should that help ? Share this post Link to post
Robert Gilland 5 Posted April 28, 2023 On 4/27/2023 at 3:23 PM, David Schwartz said: Read up on Dependency Injection, which is pretty much what's involved here. And look at Spring4D (or whatever it's called) I have downloaded Spring4D. I have looked for something to give me some idea about what it is. I cannot understand the purpose of Spring4d is, and I am not sure how it could help me, as I don't know what it is or what it does. Share this post Link to post
David Schwartz 426 Posted April 29, 2023 On 4/27/2023 at 11:19 PM, Robert Gilland said: I have downloaded Spring4D. I have looked for something to give me some idea about what it is. I cannot understand the purpose of Spring4d is, and I am not sure how it could help me, as I don't know what it is or what it does. I believe that Spring4D includes support for DI in it, but that's just based on lots of comments I've seen on this board. That said, in my experience, looking through a code library isn't a very good way to learn new subject matter. There are several books on Dependency Injection, including one that applies directly to Dephi. https://amzn.to/3LOO6Y9 One book that I particularly like is from Mark Seeman, "Dependency Injection in .NET". I have the first edition. The code examples aren't very useful for Dephi, but the principles apply. I think the newer one has more code examples, so it might not be any more useful. However, the code examples wouldn't be hard to translate to Delphi in most cases if you wanted to. I was looking more for understanding the topic, not code examples. https://amzn.to/44c1lJg 1 Share this post Link to post
David Schwartz 426 Posted April 29, 2023 (edited) On 4/27/2023 at 8:05 AM, Fr0sT.Brutal said: How should that help ? On 4/26/2023 at 1:00 AM, Robert Gilland said: I am trying to create a function that creates a class at runtime He seems to be talking about a Factory pattern. In my mind, that's what DI is involved with: creating instances of things at runtime that may vary in different ways. Edited April 29, 2023 by David Schwartz Share this post Link to post
Attila Kovacs 629 Posted April 29, 2023 so you are trying to cache the incoming stream to gain performance why don't you just feed the form from a local reader instead of downloading it when the version matches? using the same method I don't think any other solution would pay off in the long run Share this post Link to post
Robert Gilland 5 Posted May 5, 2023 On 4/26/2023 at 10:24 PM, programmerdelphi2k said: https://en.delphipraxis.net/topic/4799-how-to-create-an-object-instance-from-its-class-name/ Using the above as a starting point I have been able to write a function as asked for at the start. It has not solved my problem so far, but the function works. I have attached this function unt_myforms.pas Share this post Link to post
programmerdelphi2k 237 Posted May 5, 2023 (edited) @Robert Gilland when you register a new class, you needs UNregister it when it's not more needs it. to knows all types registered on system (your app), you can use RTTI query. see this sample https://docwiki.embarcadero.com/CodeExamples/Sydney/en/Getting_RTTI_for_Rooted_Types_(Delphi) the register is done in "INITIALIZATION" section, and unregister is done in "FINALIZATION" section from unit where this class is defined, normally. Edited May 5, 2023 by programmerdelphi2k Share this post Link to post
Robert Gilland 5 Posted May 9, 2023 On 4/29/2023 at 7:38 PM, David Schwartz said: There are several books on Dependency Injection, including one that applies directly to Dephi. https://amzn.to/3LOO6Y9 Came in the mail, got two copies, even though I only ordered one. 2 Share this post Link to post
David Schwartz 426 Posted May 10, 2023 Well, there ya go! I hope it's helful. Share this post Link to post