Jump to content

Dalija Prasnikar

Members
  • Content Count

    1137
  • Joined

  • Last visited

  • Days Won

    105

Posts posted by Dalija Prasnikar


  1. 2 minutes ago, dormky said:

    That's not a problem here, the code called by the timer is "fire and forget".

    It seems like you don't even need a timer in a background thread, you just want to periodically run some task in the background thread. 

     

    procedure TForm2.Timer1OnTimer(Sender: TObject);
    begin
      TTask.Run(
        procedure
        begin
          // call here anything that needs to run in the background thread
        end;
    end;

     

    Again, it would be so much easier to give you some suggestions if you would just show some of your code.

    • Like 1

  2. Just now, dormky said:

    It feels so wasteful to have a method running with something like "while not Terminated do Sleep(10);". Is there not a better way of having the thread idle ?

    If you want the timer to run in the thread then the thread will not idle. You need to run your timer related code within the Execute method. To simplify, the Execute method is the one that runs in the background thread, thread constructor does not run in the background thread. 

     

    You have some deep misconceptions about how threads work, but I cannot help you if you don't show your code. Right now you are doing everything wrong and you are not running any code in the background thread.

    • Like 3

  3. 16 minutes ago, dormky said:

    I have a thread that uses a timer to do work at fixed intervals and doesn't do anything except that. This means I have nothing to put in the Execute method ;

    The code within Execute method is what runs in the background thread. If you don't have any code there then you don't have a thread. If you want to run a timer in background thread, then you need to create that time in the Execute method , run a loop which handles messages and then release the times when thread terminates. There is plenty of code that needs to go in the Execute method. 

    Quote

    but if I don't the thread never terminates. What am I supposed to do ?

    Background thread that is created by TThread class (at some point) will terminate when it exits the Execute method. Because there is nothing in the Execute method thread will terminate immediately when it runs. (since there is nothing there, it will  On the other hand, your thread object instance will be alive until you free it.

     

    I cannot tell you more because you haven't shown any code you already have.

    • Like 2

  4. 45 minutes ago, Bart Kindt said:

    This is an issue started in Android 11, but since Android 13 it has become impossible to access (read/write) any files even in the so called 'public' directory structures.

    If you cannot access the public folder with application built with Delphi 12, and you could with application built with older Delphi, then it is probably that your application needs additional code/configuration added to the manifest, because now application runs as fully compatible with Android 13 which was introduced in Delphi 12. Older application was running in compatibility mode on Android 13 and that is why those additional requirements were not needed. 

     

    I don't know what exactly you need to do as my Android applications don't require such access.


  5. 3 hours ago, Bart Kindt said:

    After upgrading to Delphi 12, I could no longer install my personal App (for myself only) on my phone, du to incompatible signature.

    Did you deploy that application in debug mode? If you did, then the application will be signed with debug key stored in debug.keystore that is located in C:\Users\YOURUSERNAME\AppData\Roaming\Embarcadero\BDS\XX.0 where XX is the Delphi release version. For Athens that is 23.0, for Alexandria it is 22.0....

     

    One you install your application on a phone, you always need to sign it with same key, otherwise you need to uninstall the application and install it again, but when doing so, you will lose all local files visible to that application and new application signed with different key. The similar would ahppen if you would switch between debug and release keys.

     

    Because release key is the one that matters the most, Delphi allows you to specify the location of the release keystore, but when it comes to the debug keystore, if you want to use the same one you need to manually, copy it from previous version folder into a new version folder where it will be picked up, instead of being automatically generated again.

     

    You cannot copy your files to the local application storage from the outside. If you want to do that you would have to implement import feature in your application that would be able to copy files from public folder to application local folder. 

     

    There are possibly some ways to handle local application storage through adb connection, but I have never done that.

    • Like 2

  6. 15 hours ago, Darian Miller said:

    That's not exactly true as you can earn up to $5,000/year.   His app is making less than $400/year so it should qualify.

    How much he earns from the Android app is not relevant. How much he earns in total is relevant. See:  https://www.embarcadero.com/products/delphi/starter/faq

     

    Yes, subject to the restrictions summarize below and stated in the License Agreement. If you're an employee of a small company or organization with revenue up to $5,000 per year, you can use the Community Edition. Once the company's total revenue reaches US $5,000 per year or your team expands to more than 5 developers, you must buy an unrestricted paid commercial license.

     

    Also there are some restrictions if you already have other Delphi versions. the last thing anyone would want is receiving invoice for regular version, because they used CE edition for writing Android part of they regular Windows app developed in Delphi. Verifying that CE could be used in particular scenario is the best option.

    • Like 2

  7. 5 hours ago, Yaron said:

    Use the community version?

    Community version has very strict requirements considering who can use it. If you are earning money with your older Delphi version, then you definitely cannot use the community edition. Even if you don't earn money with it, you may get in trouble because community edition is cannot coexist with other Delphi versions not only on the same computer, but also on the same local network. If you think you have grounds for using it, you should check with Embarcadero officials first about your particular use case to avoid potential issues.

    • Like 1

  8. It is very likely that you would have less issues with interface based class and then you would be able to pass around interface reference without having to worry about memory management too much. 

     

    If you still want to use record, you need to fix your Clear procedure. You are calling CustomButtons.Free there which will destroy CustomButtons instance and then you would have crash in Finalize which would try to destroy that same instance. You should just clear the list and not free it there. So that memory management happens solely within Initialize and Finalize methods.

     

    procedure TTaskDialogParams.Clear;
    begin
      CustomButtons.Clear;
    end;
    
    class operator TTaskDialogParams.Finalize(var Dest: TTaskDialogParams);
    begin
      Dest.CustomButtons.Free;
    end;

     

    • Like 2

  9. 3 hours ago, David Heffernan said:

    Clearly it's using some AI library to do this.

    https://learn.microsoft.com/en-us/visualstudio/ide/ai-assisted-development-visual-studio 

     

    3 hours ago, David Heffernan said:

    This is only going to get better and better, but it's already amazing. So far as I know, there's nothing remotely like this for us Delphi users. Or would we get this is we wrote our code in an editor like VS Code?? 

    You can use GitHub Copilot with VS Code.

     

     

    My current problem with those AI tools is accuracy (which is less of a problem if you know what you are doing and you are using it for small code snippets completion),  potential legal issues (they trained on open source, but that does not mean that they haven't violated open source licenses), and next question is how much of my code ends up in training data which may leak security sensitive data.

    • Like 2

  10. 44 minutes ago, pmcgee said:

    I have to problem with pointer to record ... I have been pretty scathing about C-style function declarations that are not broken down into more readable sub-types.

     

     

    I am not following. What function declarations have with records and record pointers we are talking about here?

     

    44 minutes ago, pmcgee said:

    We could separate ownership from access with something like :

    
    begin
      var o := TRecObject.Create;
          begin
             var p:PRec := @o.r;
             // use p for whatever
          end
      o.Free;
    end

    That pointer could be copied, passed to functions, whatever ... and simply pass out of scope.

    It wouldn't have ownership of the data object, and has no responsibility to release it.

     

    You cannot separate ownership from access. The pointer no longer has the responsibility to release it, but instead of having one problem - one reference that needs to be tracked, managed and released. You now have two you need to pay attention to. Just because you only need to release one, does not mean that you can do just about anything with the other. And if you pass such pointer to the record out of scope, you have just created access violation. Once you free the wrapper object, your record pointer becomes dangling reference. 

     

    I am not even going to comment about whole wrapping record into object and then working with pointer to that record instead of just using pointer and be done with it...

     

    44 minutes ago, pmcgee said:

    [edit - forgot] Or of course, you can have methods in the class to control and implement the access to the data object.

     

    I think this also highlights that the outer wrapper can be something other than manually managed.

    Whether or not you would do all that depends on the context of the code you are dealing with. Wrapping object in a object or an automatically managed object could make sense, but it could also be the opposite. first you need to write such wrapper code and then you need to maintain it. Again, it could make sense in some scenarios where you want to add some additional functionality to a record you cannot otherwise change, but just for allocation it on the heap it doesn't.

    • Like 1

  11. 14 minutes ago, pmcgee said:

    I don't think it is the generally accepted meaning of 'raw pointer'. 

    Well, in Delphi we commonly use phrases untyped and typed pointers. so when you say raw pointer in Delphi context my immediate association is untyped pointer, especially since your next comparison with C++ unique pointer and shared pointer which are automatically managed was completely unrelated feature to Delphi objects which are not automatically managed. So I assumed that you wanted to say untyped, as I haven't made the connection with the rest and what you are trying to say.

     

    I am still not certain what was your original point... as it seems that you were arguing for both style and memory management, otherwise why mentioning unique and shared pointer. I have chosen to disregard the automatic memory management part as this would be adding additional level of complexity and focus on the class part alone.

     

    22 minutes ago, pmcgee said:

    Yes. I was arguing from a consistency and code-style view point.

    Again, that depends on the rest of the code. In general, if you are dealing with records, then using typed pointer to that record is more consistent and idiomatic than wrapping that record into a class, just to have it allocated on the heap. Especially, since Delphi no longer requires dereferencing typed pointers when working with their content.

     

      TRec = record
        x: Integer;
      end;
    
      PRec = ^TRec;
    
      TRecObject = class
      public
        r: TRec;
      end;
    
    var
      p: PRec;
    begin
      New(p);
      try
        p.x := 5;
      finally
        Dispose(p);
      end;
    end;
    
    
    var
      o: TRecObject;
    begin
      o := TRecObject.Create;
      try
        o.r.x := 5;
      finally
        o.Free;
      end;
    end

     

    If you look at the above code, the using pointer makes code more readable than having wrapped record as you can directly access its content through pointer reference instead of having another level of indirection between.

    • Like 1
    • Thanks 1

  12. 5 hours ago, pmcgee said:

    I don't think it's a wild opinion in 2023 that pretty much nobody outside of C code should be cooking up raw pointers.

    Typed pointers are quite different from raw pointers. 

     

    Both class and pointer in make sense, but which one you will chose, pretty much depends on the other code in the context. Declaring a class merely for a single procedure might be an overkill. From the safety perspective typed pointers in Delphi are equally safe or unsafe as classes. You still have to manage their memory and pay attention to what you are doing with them. 

    • Like 1

  13. 17 minutes ago, Ledklom said:

    I am using .canvas bitmap handle to do a basic task with GDI routines but when I split the task into two steps only the first is done,

    VCL implements "garbage collection" for unused device contexts and it periodically releases them. To prevent that you need to call Lock on Canvas, and call Unlock when you no longer need the same device context.

     

    But, without seeing your code it is hard to say whether there is more going on.

    • Like 4

  14. 36 minutes ago, Daniele said:

    For some reason in my code I had to move the addlog procedure declaration from public to private and now it works.

    This is very strange. But the whole issue has been strange from the beginning. AddLog should work both inside or outside task. The only possible explanation would be that AddLog was never called from within the task because some code before it is called triggered exception.


  15. 43 minutes ago, Daniele said:

    Sorry but does my code work for you? Ok for ErrorData it is indeed redundant. But I'm very surprised that it works for you. I've tried and tried but I just have no way to make it work.

    Yes, your code works for me. so the problem must be in some other code you have. Is the AddLog procedure called at all, or just the writing to file does not work? The best thing you can do is to create empty project and test writing to log there.


  16. 25 minutes ago, Daniele said:

    Yes, I debugged it but no exceptions are triggered.

    Saving to log file works fine to me (from the task). The only thing I noticed is that you don't have ErrorData defined within the AddLog procedure. Move it inside, as there is no reason to have broader scope.


  17. Have you tried debugging? 

     

    Besides the fact that your AddLog code is not exactly thread-safe (if you call it from multiple threads, you can get corrupted log), there is nothing there preventing it to work. And the thread-safety issue would be solved with TThread.Sysnchronize call. So if there is nothing written, your code probably never reaches AddLog call. Make sure that there is no exception raised before that call.


  18. 1 hour ago, PeaShooter_OMO said:

    Do you have a project on it that is bigger than your largest Delphi project? For which language? If so, how does that IDE behave with that project?

    My projects are all rather small, regardless of the platform and the tools I am using.

     

    I am personally using Android Studio with Java. Comparing to Delphi, Android Studio is way more resource hungry and slow. 

     

    Opening a project takes more than a minute, building about 3 (also highly depends on how AS mood at the moment as rebuilding the same project can last up to 10 minutes). Similar Delphi sized project (actually a tad larger) opens up immediately, and builds in under a minute. AS gobbles up over 4 GB of memory while doing that and burns my CPU at 98%. While Delphi uses a little over 600 MB and 8% CPU. 

     

    Also I had a AS bug report open for years before it was finally fixed, where it would eat up memory on opening second project, and crawl down to a halt and had to be killed through Task Manager. So if I had to switch projects I had to restart the IDE. I am sayin all this so that people wouldn't think that the grass is much greener on the other side and that there are no problems. But the IDE has more features than Delphi and it definitely has some I would want to have.

     

    My son is using IntelliJ for Java, and Rider for C# and he is very satisfied with both.

    • Like 2

  19. There is one other feature I like, is ability to change editor font size in pixels. I would like to use Consolas, but size 10 is too small (13 pix) and size 11 is too large (15 pix). I am using 14 pix in other editors. I would post the QP number for that feature request, but it is currently down. But it seems that this would have to wait for new editor because AFAIK the current one can only deal with size in points.

     

    One thing they implemented in Delphi 12 is increasing the line height, which is another important feature, when my eyes switch to overly sensitive mode.


  20. 9 minutes ago, dummzeuch said:

    Hm, I have just read through that page and another one but I'm not quite sure whether I would find inline hints useful or annoying. I'd probably have to try it.

    I am used to named parameters in Swift (which you have to explicitly write), so once you get used to the fact there there is more information in code, you learn to easily ignore it when you don't need it, but when you do need it is extremely helpful when you are going through code you are not familiar with or your own old code. Yes, you could also hover over the method to see the names and types, but that significantly slows down reading the code. 

     

    I even find it helpful for the code I know well. I guess my brain likes the extra information being served on a plate. 

    • Like 2

  21. 12 minutes ago, dummzeuch said:

    I've moved this to a new topic because it is not much related to Delphi 12 being released.

    OK, I bite: What's your favorite feature(s) in a JetBrains editor that Delphi does not offer? (Excluding things that Delphi offers but that don't work.)

    Inlay parameter hints. It is extremely useful for reading and understanding the code https://www.jetbrains.com/help/idea/inlay-hints.html#change-inlay-hints-appearance

     

    Excluding things that Delphi offers but don't work is tough restriction 😉 Well working code completion and refactoring are next. 

    • Like 1
×