

Rollo62
Members-
Content Count
1977 -
Joined
-
Last visited
-
Days Won
26
Everything posted by Rollo62
-
I have no external keyboard, how does it behave differently ? Isn't it catched by the normal TEdits OnKeyDown, OnKeyUp or OnChangeTracking in same way as should with the virtual keyboard ?
-
Is IPhone SE suitable for testing purposes?
Rollo62 replied to Michael Collier's topic in Cross-platform
Yes development should be possible, but you should be aware that more modern iPhones might have Notch, no Button anymore and different display sizes with certain "no-go areas" when showing portrait or landscape. Not sure how SE compares against the never, but its looks definitvely like the older ones, where it was much easier ( good old days .... ). -
Right, the demos from lottiefiles.com are great, but I need to tweak them a little. One hope is maybe InkScape https://inkscape.org/de/~mattia.basaglia/★tgslottie-importexport https://lottiefiles.com/animation/inkscape But that seems very gamma/beta still, but I will try to get this running.
-
Yes, but it seems that Adobe After Effects is the only tool which is able to create serious animations, while no other competitors or free tool exists so far, that could reach that quality. That is a little strange I think, since Lottie is not that complex and widely used, I would have expected many other tools in the market. I personally dislike Adobe tools, thats why I look for an alternative.
-
@vfbb Great library, thanks for that. Especially the Lottie support I find very interesting. Yesterday I was checking some Lottie tools, and I must find out that there is no real simple Lottie editor, beside Adobe After Effects. Do you have the same experience, or could you recommend some simple animation tools ?
-
iOS, Metal, Bitmaps, RGB becomes BGR?
Rollo62 replied to John van de Waeter's topic in Cross-platform
---- -
Class properties: Wins prettyness over functionality ?
Rollo62 posted a topic in Algorithms, Data Structures and Class Design
Hi there, sorry for the exiting question above, but this article leads me to this question, what is grumbling deep in my guts for quite some time now. There are some fractions of people, also in other languages, that think properties are superfluous. Not that I am thinking like that, but I really would like to point out the special usefulness, and to ask the language experts what the advantages of properties really are. Properties: Advantages - prettiness, looks nice and clean in the caller (not so much in the called ) - Shorter names - Can be assigned to - Can be used in boolean operations, without the brackets () - Can be used on fields directly, without getter/setter ( this is their biggest advantage, IMHO ) - Encapsules internal implementation, by a well defined interface ( this is no advantage, it is true for every method too ) Properties: Disadvantages - More overhead to maintain the property - Changing names, needs changing in 3 places - Separates getter/setter (private) and property (public) into different sections of the class interface position, must jump there to edit - Cannot be used in nested calls, for setting all, like FMyOne.DoOne( FMyTwo.DoTwo( FMyThree.DoThree( True ) ) ); ( OK, this also not works with separated setter/getter, but I could do that ) While properties cannot FMyOne.One := FMyTwo.Two := FMyThree.Three := True; ( which could be the only real advantage of properties, IMHO ) - Encapsulates internal implementation, by a well defined interface ( same true, as above ) - When used in Interfaces, I also must define setter/getter, so no advantage over functions, by saving setter/getter - When used in Interfaces, I cannot use them with pure fields, but I'm forced to define setter/getter ( this could be a second advantage of properties, IMHO, if that could be possible ) Is there something I overlook here ? To me it seems there is no real technical argument that speaks pro properties at all, beside their "prettiness", am I right ? I hope you can show me situations where I really need them, or where they have huge performance advantages. -
Class properties: Wins prettyness over functionality ?
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
I'm not beeing lazy, I use them heavily, even I rarely use them with public fields alone, but initially gave them getter/setter ( so I'm overdoing more often than I should ). The question was: Are they worth the efford, how exactly do they make code better ? From above arguments I'm already convinced, and my gut feeling gets more towards seeing their advantages. Agree to all your points, beside that. What I really dislike is when mixing both concepts, that is ugly to me, not beatiful. FThing.Enable := True; FThing.Execute( 1 ); //vs FThing.Enable( True ); FThing.Execute( 1 ); I would say the latter is better readable, but we could argue the whole night about that But your discussions brought two real advantages to my mind: - Performance by using direct field access vs. function calls - When published, can be used in Designers, which would be nit possible by get/set that elegant Good point too ... I think I have to update my list Properties: Advantages - prettiness, looks nice and clean in the caller (not so much in the called ) - Shorter names - Can be assigned to - Can be used in boolean operations, without the brackets () - Can be used on fields directly, without getter/setter ( this is their biggest advantage, IMHO ) - Can have better performance with private field access - Can be used as published properties, in designers - Supports indexes - Supports array-style access - Have good RTTI support - Supports decorations/attributes - Encapsules internal implementation, by a well defined interface ( this is no advantage, it is true for every method too ) Properties: Disadvantages - More overhead to maintain the property - Changing names, needs changing in 3 places - Separates getter/setter (private) and property (public) into different sections of the class interface position, must jump there to edit - Cannot be used in nested calls, for setting all, like FMyOne.DoOne( FMyTwo.DoTwo( FMyThree.DoThree( True ) ) ); ( OK, this also not works with separated setter/getter, but I could do that ) While properties cannot FMyOne.One := FMyTwo.Two := FMyThree.Three := True; ( which could be the only real advantage of properties, IMHO ) - Encapsulates internal implementation, by a well defined interface ( same true, as above ) - When used in Interfaces, I also must define setter/getter, so no advantage over functions, by saving setter/getter - When used in Interfaces, I cannot use them with pure fields, but I'm forced to define setter/getter ( this could be a second advantage of properties, IMHO, if that could be possible ) Well that are enough good arguments on the PRO side for me, thanks for pointing that out. Its worth the efford to use them, my daily workflow doesn't need to be corrected. -
A better way to share global data structures than as global variables?
Rollo62 replied to DavidJr.'s topic in Algorithms, Data Structures and Class Design
Related to your title "A better way to share global data structures than as global variables?", Not sure if always "better", but for sure an "other" way: I like to "share" global data by TMessage sometimes, which could completely decouple separate units. You only have to initialize a "global" module, sunscribing to its message, and then you can request global (or non-global) data by messaging from everywhere you want. You can implement thread-safetyness, imutability as you like. -
The Curiously Recurring Generic Pattern
Rollo62 replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
Thanks for clarification, I hadn't recognized from your article that this feature is D5 compatible, sounded D11 related to me, and it looked a little alien to me anyway and ringing my alarm bells Much better that this pattern has such a long history, I was not using D5, but BCB5 at those days, so I'm still learning new features every day. -
The Curiously Recurring Generic Pattern
Rollo62 replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
Very interesting article, I love C++ Delphi Especially the use case samples are great, where I think this could make it possible to be used in a nested way, what I consider for some time. Something like that: var Builder := THtmlStringBuilder.Create; Builder .Html .Header.Enter .Header.Text( 'In header' ) .Header.Leave .Div.Enter .Div.Id( 'main' ) .Div.Color( clYellow ) .Div.Text( 'In div' ) .Div.Leave .Footer.Enter .Footer.Text( 'In footer' ) .Footer.Leave ; WriteLn(Builder.Data); I think that should be possible and should make sense too, I have to check that. What I'm a little unsure is, how stable and reliable this "self reference trick" is tested under different Delphi versions. Can-I-Use it without any unexpected quirks, or do I better wait and see if this is still running in the next version(s) ? -
Which option to use for a large batch of REST queries?
Rollo62 replied to David Schwartz's topic in OmniThreadLibrary
Sorry for giving you totally wrong and off-topic hints. I thought you wanted to work with huge amount of REST queries, maybe with lots of unneccessary data to download as well, where GraphQL as server interface could help to optimize requests paths and download sizes. -
Which option to use for a large batch of REST queries?
Rollo62 replied to David Schwartz's topic in OmniThreadLibrary
Consider GraphQL, which is more effective than REST. -
You mean libraries like this ? There you can add custom libraries, bei right click the Android32/64 Node and add them to the list.
-
Tl;Dr; Like that ?
-
Interesting, need more consideration where/how to use that ... 🤔
-
Hi there, I have a general question regarding this topic. There is a lot information out there, even in the DocWiki. https://blogs.embarcadero.com/what-are-the-mistakes-we-made-in-creating-delphi-objects/ https://sergworks.wordpress.com/2015/01/21/think-twice-before-raising-exception-in-constructor/ https://stackoverflow.com/questions/39110021/delphi-raise-exception-in-constructor To summarize: It is perfectly fine to raise an exception in a class constructor ( and in some cases its even not avoidable, I assume ). My question is: Shall and raise an exception on purpose, and if so, what strategy is best ? In a normal situation, this is completely OK. LA := TRaiseOnMinus.Create( -2 ); //<== Raise try //some code finally LA.Free; //<== Never called end; But like that it causes issues: try LA := TRaiseOnMinus.Create( -2 ); //<== Raise //some code finally LA.Free; //<== Will be called on an unconstructed object end; But there is the pattern of encapsuling multiple try - finally's How shall I handle that ? LA := nil; LB := nil; try LA := TRaiseOnMinus.Create( AInputA ); //<== PossibleRaise try LB := TRaiseOnMinus.Create( AInputB ); //<== Possible Raise finally LB.Free; end; finally LA.Free; end; Either I can guarantee that NO Exception can be raised ( can I guarantee that really ) ? Or maybe guarding the Free might help, but I doubt that. LA := nil; LB := nil; try LA := TRaiseOnMinus.Create( AInputA ); //<== PossibleRaise try LB := TRaiseOnMinus.Create( AInputB ); //<== Possible Raise finally if Assigned( LB ) then LB.Free; end; finally if Assigned( LA ) then LA.Free; end; Are there any recommendations or best practices, about using Exceptions in class constructors ( Shall I use them, or not ) ? I see the problem that the caller never knows if Create might be able to throw an exeption, so he must be analysing the internals of the TRaisedOnMinus class first. Beside that, there could be the possibility to prevent any damage from inside the class, by guarding internals, to ensure that double-calling Free doesn't do any damage. Only I'm afraid that this guarding inside Destroy is bad practice too ( but I like double-safetly measures anyway ). constructor TRaiseOnMinus.Create( AParam : Integer ); begin inherited; FMyList := nil; if AParam < 0 then raise Exception.Create( 'Bum' ); FMyList := TStringList.Create; end; destructor TRaiseOnMinus.Destroy; begin if Assigned( FMyList ) then FMyList.Free; inherited; end; How do you design classes with exceptions ?
-
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
... and there we are again with Uwe's Initialize and my Conf_Setup_ scheme ... I like that approach too, because of the clear separation, but its hard to say where I should use that or better constructor parameters. Maybe the experienced developer has always the right answer, but not me, I usually try and rework my classes many many times, until I find a stable, acceptable final design. Would be great to have some rules in what situations such separation makes sense, you gave already a good hint to that. I like to use the Conf_Setup scheme in combination with the fluent interface, which makes class creation, or class builder, more nice and well readable. begin LMyObj := TMyObj.Create {} .Conf_Setup_Begin {} .Conf_Setup_Color( clBlue ) {} .Conf_Setup_Events( EvOnChange ) ... {} .Conf_Setup_End {} ; end; Most of the time I use class functions in those "Builders", which encapsulates class creation within the class itself. Another step of separation creation and initialization within the "Builder". -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
That external parameter is not in the domain of the class, so I have to take care outside, to keep everything clean. Or do you mean issues with some kind of delayed access, in anonymous procs, events or threads ? When the object might be released, while the event proc might still try to touch it. I think this could has to be guarded by other means, its not related to the constructor exceptions. I would not need Guards on every internal operation, to ensure all parameters are OK. I would hardly see any strange sideeffects later on, when an invalid parameter causes issues only under rare conditions, the creation fails gracefully immediately before that happens. -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
Right, I'm also wondering how such a "simple" question touches so many basic language concepts. But to clarify the original question again: It was not about if raising exception in Create is possible and how to do that and catch it, the question was: "Shall I raise exceptions on purpose, or better not". Yes, this is exactly what I am looking for, especially here I should raise exceptions if something is wrong with these parameters. Thanks to all, who brought so many different aspects into this discussion. I came already to the conclusion: Raising on purpose in Create() is fine, especially to guard against missing or faulty injected parameters. Everything else is just an intermediate state to the final, perfect design, but there is no real reason to keep such intermediates. ( only I'm not so sure if I am ready to "finalize" all my classes in time ) -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
Right, but why does it feel so bad Maybe I need to think a little out-of-the-box: 1. If I have a little complex classes with quite a few parameters that may rearranged in many ways, while the class is intendet to use direkt operations anyway, then the Conf_Setup pattern for initialization seems to be reasonable. Conf_Setup can throw exceptions when needed. If I remove all the guards on each operation, this is a little risky step. When "forgetting" such Setup, might result in failures usually that should be directly "visible" and easily spotable, but they also might occur in any unpleasant, unforseen situations. So I better use Conf_Setup ALWAYS with Guards on each operation. 2. If I have small, simple objects with < 5 parameters, which are mainly intended to be passed to other objects ( like TTtreeNode ), then the raise in Create might be the right choice. As advantage I can remove all Guards inside that class. 3. A third rule might be, if you have a class of 1.) it is maybe too complex. Try to re-arrange or decompose it, so that the class(es) can fall under 2.) But this is not so easy sometimes, as you might know. This would mean the Conf_Setup rule 1.) is something temporarily only, until I find some better design solution. So a set of rules for different use cases should be fine too, but I'm not sure if these considerations are complete yet. But looking at 1-3.), I would think that the final goal could be to move most classes to 2.), with raising exceptions at the point of their creation. So reaching design 2.) should be the most attractive, I would assume. -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
Right, Destroy should have no exceptions. But is there any difference if the Exception happen in Destroy or in Conf_Teardown ? If Conf_Teardown is called only in Destroy, and raises an exception, the bad result might be the same. The only advantage to put things in Teardown might, that there a try - finally block could catch such Events, in a central manner. Which is maybe a better place for try-finally, than to put that in Destroy itself. -
Smart characters editing in strings in Delphi
Rollo62 replied to Bob Baudewyns's topic in Algorithms, Data Structures and Class Design
You can also find a nice online tool -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
Thanks for those descriptions, they are very enlightning too. I use the Assigned() check as another (bad) habit too, inspired by the DUnit-Tests, which is somewhat related to the separation idea from above ... destructor TRaiseOnMinus.Destroy; begin if Assigned(FMyList) then begin FMyList.Conf_Teardown; FMyList.Free; end; inherited; end; Related to the Conf_Setup_.... scheme, I like to implement Conf_Teardown as well, but this is maybe less reasonable. My goal with that approach was to get also all cleanup in one place, outside the Destroy, thats why I often use the Assigned() before .Free. But as explained above, I find Conf_Setup_... and Conf_Teardown not that attractive, and hope to get rid of this. One reason ist that the external call to Conf_Setup is maybe missing, and the internal fields stay maybe uninitialized. procedure TTest.Run; var LA : TRaiseOnMinus; begin LA := nil; try LA := TRaiseOnMinus.Create; //<= No more exception LA.Conf_Setup( -1 ); //<= It's possible here now LA.Conf_Setup( TStringList.Create ); //<= Another configuration, maybe this line is missing ?? finally if Assigned( LA ) than begin LA.Conf_Teardown; LA.Free; end; end; end; Either I guard any internal access to the internal StringList field variable, or I throw an exception at such accesses. This behaviour I dislike very much in the Conf_Setup approach, and I see no simple way how to intrinsically detect if Conf_setup was called, or not. Allowing uninitialized, unguarded fields would cause random AV, which is by far the worst case of all, IMHO. -
BestPractices: To raise, or not to raise ... an Exception in a class constructor
Rollo62 replied to Rollo62's topic in Algorithms, Data Structures and Class Design
@Uwe Raabe Thanks Uwe, it turns out that I used a similar approach for a few classes. Only that I called them Conf_Setup_..., which allows me to have different Conf_Setup_.... for different purposes ( Conf_Setup_Initial, Conf_Setup_Module, Conf_Setup_Events, .... ). This way I have them all nicely bundled together under the same Prefix. LA := TRaiseOnMinus.Create; try LA.Conf_Setup_Initial( AInputA ); //<== PossibleRaise ... This works Ok, but it feels a little wrong, when I try to use clean DI via constructor injection a the same time. To separate this, from constructor to property injection, would bring DI to a less strict level, IMHO. I have hope to keep simple classes as clean as possible, that was the main reason of my initial question in the first place. Would clean separation of construction and initialization be able to resolve ALL the unwanted issues completely ? If that is the case, then I think the overhead is worth it. Only I am not so sure if I can achive the same, with lower overhead cost too. @Dalija Prasnikar Thanks, these rules are very helpful to sort out the right behaviour. @Dalija Prasnikar Doesn't that bite with your bullet point from above ? Once you have half-created instance, you also may have hals constructed internal fields, or is that guaranteed that this never happened ? Thats why I put the FMyList := nil; before the Raise, but it's more like an old habit of mine, to initialize before use. Ok, with your rule: "object instance fields are always zero initialized when constructor chain is being called", thats obsolete. But are all kind of field types secured, like Pointers, [ Weak ] field, and whatsnot, ... ? My habit shall prevent any unexpected glitch, but is of course double-safety in most cases. (Is this an AntiPattern maybe ? ) I also used the "flat" try - finally here and there, but this always left a bad taste to me. What happend if I use this for more than two variables, which often may happen in Bitmap related stuff ? var LA, LB, LC: TRaiseOnMinus; begin LC := nil; LB := nil; LA := nil; try LA := TRaiseOnMinus.Create( -2 );  LB := TRaiseOnMinus.Create( -3 ); LC := TRaiseOnMinus.Create( -3 ); //some code finally LC.Free; LB.Free; LA.Free; end; end; Wouldn't it be OK as well, when I use them "flat", but take special care on managing them in the right order ( ABC - CBA ), like above ? Why should I use one Create outside the try scope ? @Lars Fosdal Right, I also avoid to raise Exceptions, but currently I am working on a class where this could make sense. So I would like to find the best answer or rule-of-thumb for this case, could be like this: - never raise Exception on purpose, it's evil - never raise Exception on purpose, it's an antipattern ( because ... see GOF page xxx ) - you can raise Exceptions safely, if you do prepare this and that - if you always do it like this, you guaranteed to never ever run into any issues. I think we already have a lot of useful rules identified already, thanks to all. @Fr0sT.Brutal Yes, I only try to find the rules for raising my own Exceptions on purpose. But they may raise by system at any time, maybe not only memory, but also file system or other hardware related. Would be good to have the best set of rules for all cases, my exceptions and system exceptions, in the same way.