

Rollo62
Members-
Content Count
1949 -
Joined
-
Last visited
-
Days Won
25
Everything posted by Rollo62
-
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. -
TLDR; I think you mixed too many stuff in one method. I would separate this into different domains, each in a unit, e.g. like UMailSend.pas, USysInfo.pas, and the caller I usually encapsule separate functions into classes, with static functions/methods. This behaves same like functions or methods, but keep them under a "namespace" of the class, which could be extended if needed. type TMail = class class function Send( AReceiver, AMessage : String, ...); static; end;
-
Android 64: keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect.
Rollo62 replied to MikeMon's topic in Cross-platform
Thats where you should set it, under "All" Android should be the best place, when Debug/Release is not yet set. Be aware that there could be several wrong, old settings under Debug 32/64 and Release 32/64. Maybe you could check with a fresh, new project, just to ensure the that the keysore works well. -
Android 64: keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect.
Rollo62 replied to MikeMon's topic in Cross-platform
There were two passwords, for the keystore and the Alias. Are you sure both of them were correct ? -
How about this Project?
-
How to load a PNG file into TImage, then copy another PNG file into it
Rollo62 replied to alank2's topic in VCL
There are other, simpler methods to copy a bitmap, but maybe this example is worth noting it, (or here) line-by-line using ScanLine. var srce, dest: TBitmapSurface; path: string; scan: integer; w, h1, h2: integer; begin path := 'C:\tmp\Imgs\res.bmp'; srce := TBitmapSurface.Create; try TBitmapCodecManager.LoadFromFile(path, srce); dest := TBitmapSurface.Create; try // first half w := srce.Width; h1 := srce.Height div 2; dest.SetSize(w, h1, TPixelFormat.RGBA); for scan := 0 to h1-1 do Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan]^, srce.Width * 4); Image1.Bitmap.Assign(dest); // second half h2 := srce.Height - h1; dest.SetSize(w, h2, TPixelFormat.RGBA); for scan := h1 to srce.Height-1 do Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan-h1]^, srce.Width * 4); Image2.Bitmap.Assign(dest); finally dest.Free; end; finally srce.Free; end; (the example explains how to handle very large images). Here also a simpler solution (just don't use the "with" ...) -
TMS Maps claims that they support TomTom, not tested that.
-
https://en.delphipraxis.net/topic/5406-image32-2d-graphics-library-open-source-freeware/
-
What does that mean ? The page is here, its not requiring any ther packages, as far as I know. http://www.angusj.com/delphi/image32/Docs/_Body.htm
-
Samples like that ? https://github.com/FMXExpress/Cross-Platform-Samples
-
Just a few posts ago, with Image32.
-
New OpenSSL 3.0.1 and 1.1.1m releases
Rollo62 replied to Angus Robertson's topic in ICS - Internet Component Suite
Thanks, thas very interesting news, to solve the ugly SSL issues once and for all. I wonder what prevents them to make it FMX compatible right away, on all platforms, I expect not much VCL code inside ? -
How do you acquire "Pictures" to be used in your project?
Rollo62 replied to TimCruise's topic in Tips / Blogs / Tutorials / Videos
Pexels -
Have a look at this WP-Client from Embarcadero, maybe its helpful. Not tested it, would be great if you could give us some feedback about it, if you can use it. Looks not that current any more, but maybe a good start.
-
Are future security patches included in a RAD Studio perpetual Commercial License?
Rollo62 replied to TimCruise's topic in General Help
I like clear pricing strategies 👍 -
Are future security patches included in a RAD Studio perpetual Commercial License?
Rollo62 replied to TimCruise's topic in General Help
Thats why I always feel cheatet, as a loyal, many year subscription customer. For the normal, official renewal they offered about 27% higher rate than in this offer, while they claim subscription renewal will get lower every year. I from my perspective think that they choose renewal price by a kind of monte-carlo method, every year new. Shall I contact my sales office ? -
Yes, WordPress has a REST API. There was a security warning some time ago, better not to use it, but I'm not sure about the current state. I think it should be safe and stable.
-
Hi there, maybe that link helps to check the status of some services.
-
No
-
@PeterPanettone Why do you insist of some special stuff, that Uwe and others already explained in detail several times. Why not simply say "thank you very much for the insights and the valuable time you offered to me" ? Why getting more and more agressive about people that only try to help you ? Why do you expect other people doing something especially for you, while shouting at them ? Questions, questions, questions 🤔
-
Maybe thats more current, from Vinicius Sanchez
-
Yes, I considered that approach too. But I am not a big fan of hundrets of sub-folders, especially because Delphi doesn't support relative paths well (except in the .DPR). If Delphi would allow uses including relative paths, I would go for this approach too, meanwhile I try to abstract by "namespaces". The advantage of "mainspaces" like above is, that the files are not cluttered all over different sub-folders, but they are nicely sorted side by side. That way, I can even add further sub-modules, that are related to the domain: My.SpecialUnit.pas //<= Common functionality My.SpecialUnit.SubModule.pas //<=SubModules My.SpecialUnit.SubModule.iOS.pas //<=SubModule with specific workaround for iOS My.SpecialUnit.SubModule.Other.pas //<=SubModule with implementation for all other platforms My.SpecialUnit.Win.pas //<= Specializations, workarounds, fixes My.SpecialUnit.iOS.pas My.SpecialUnit.And.pas My.SpecialUnit.Macos.pas My.SpecialUnit.Linux.pas Of course the folder approach would be nice, because thats even removed IFDEFS, but also make the "path" handling in Delphi more fragile. Thats why I don't use it via the different platform designer in Delphi, this is only differentiating the Form, but hardly to manage different behaviour too. I separate different "Views" in TFrames, and on them I can use whatever I like. My.SpecialView.Frame.Win.pas // Maybe this uses StringGrid My.SpecialView.Frame.Win.dfm My.SpecialView.Frame.Tablet.Mobile.pas // Maybe this uses Popup, (for iOS, Android Tablets) My.SpecialView.Frame.Tablet.Mobile.dfm My.SpecialView.Frame.Phone.Mobile.pas // Maybe this uses ListView, (for iOS, Android Phones) My.SpecialView.Frame.Phone.Mobile.dfm My.SpecialView.Frame.Macos.pas // Maybe this uses HtmlGrid, (for Macos) My.SpecialView.Frame.Macos.dfm My.SpecialView.Frame.pas // Here I can manage to include the right code in the uses, and forward that as interface // All the frames above include the same Interface, so they encapsule the same behaviour, only in different views. // This interface, according to the platform, can be simply forwarded or wrapped if needed My.SpecialView.pas // Here I can handle the interface, for usage of the certail "view" // Like forwarding the right interface and Factory // The whole unit block keeps nicely together, avoiding cluttering into many, unrelated units and folders. The single views can be nicely edited, by the TFrame designer in a RAD manner, and I can add and visually design as many components as needed for each platform. I can handle the different "views" by a single interface, so from the users perspective the different platforms doesn't really matter. The caller doesn't need to care if he is on desktop or mobile (in the best case), he simply can use the same code in many projects. The views can easily be extended. Of course the abstractions of different platforms are somewhat difficult, but it turned out that many "standard views" can be identified, and easily unified. As example: Dialogs, Login, Logger, InternalDebug, View of Lists, and whatsnot This is what are 1:1 same in all my apps, and work on all platforms in the same way. This way I can replace many "components" by such "view interfaces", and the caller deals only with the interfaces with their expected, well defined behaviour. All workarounds, fixes and platform differences, version differences are well hidden in the structures behind.