Jump to content

Dalija Prasnikar

Members
  • Content Count

    1061
  • Joined

  • Last visited

  • Days Won

    91

Posts posted by Dalija Prasnikar


  1. 9 hours ago, at3s said:

    But is there a way to move an application at least in background mode like [Home] iPhone hardware button does?

    Sure, the easest way will be to hide those [Exit] button from the application in case it doesn't work in iOS.

    Why? iOS users know how to move application to the background using Home button. Such functionality does not belong in the iOS application.  Just remove the Exit button or hide it on the iOS and avoid calling problematic code on iOS with compiler directives.

    • Like 2

  2. 43 minutes ago, at3s said:

    Actually it's [Exit] button functionality in the application.

    iOS does not support terminating application, so Delphi does not have that support either.  If Delphi previously implemented Terminate on iOS it was most likely removed as such functionality would cause rejection on the AppStore. See https://stackoverflow.com/questions/355168/proper-way-to-exit-iphone-application

    • Like 1

  3. 18 minutes ago, Lars Fosdal said:

    My suggestion would be to try to narrow down the behaviour to a minimal example and submit it to QualityPortal.

    @PaulM117 like Lars suggested, if you can create test case, please submit a bug to Quality Portal. However, even if you cannot create reproducible test case, submitting a bug report (with as much information as you can provide) might still be a good choice as at least it gives some feedback to Embarcadero that there is something seriously broken in the area.


  4. 14 hours ago, Pat Foley said:

    When I switch from 64 to 32 I use the syntax check to (alt-p-s) Before the compile. 

    I have noticed that switching between platforms often chokes if you just compile or do syntax check. Full build works. It seems like some internal compiler status or cache is not properly cleaned during platform switching. 

     

    However, I haven't been able to create small reproducible test project to report the issue and I don't switch platforms that often so I never tried to investigate deeper. 

    On 3/19/2023 at 3:12 PM, PaulM117 said:

    6. Ensuring "Enable unit directory cache"  is enabled

    The issue sounds like it is cache related, so I would say that enabling cache option might be counter productive. Try disabling the cache and see how it goes.


  5. 20 minutes ago, dummzeuch said:

    Has anybody ever implemented something like this in a Delphi program? Or did we all just sit there and tell everybody that this is not possible because the VCL is not thread safe?

    Sometimes it would be really nice to be able to create additional (VCL) controls in a background thread and then somehow pass these on to the main thread to add to a form. I never came around spending any time on this though.

    Implemented what? If you mean full thread-safe UI, then no. For one thing Windows API has thread-affinity, meaning that you cannot create windows in one thread and use it in other. 

     

    There is currently another thread that talks about FMX and VCL thread safety as well as Windows API thread safety and what can and cannot be done any why. 

     


  6. 3 minutes ago, Fr0sT.Brutal said:

    However, what if we step further to the rabbit hole and place a bg-thread-owned control into a main-thread-owned one? In theory this shouldn't raise issues as long as all interaction is done via Send|PostMessage.

    You can do that, but you can only use non-blocking communication. This means SendMessage is out of the question as it can deadlock. This means that your hierarchy of controls must be specifically handled to allow such usage. Which means using Windows API directly for creating such controls.

    Any steps into using VCL or FMX to do that are recipe for disaster. Yes, I know that people are doing all kinds of things and that it "works" but they are just being lucky.

     

    I am not going to say, yes you can do that when you are out of options, because then people stop and don't look for other options. Another problem is recognizing all thread-safety issues as UI is complex and interactions are also complicated and it is very easy to miss problematic scenarios. Again, they are just being lucky.

     

    We need better controls and libraries that can perform heavy tasks outside UI controls and main thread.


  7. 24 minutes ago, programmerdelphi2k said:

    Ok, but if we use "Create" from Delphi, as it is the default and widely used for this task, and... Delphi calls (uses) the class of this control defined in MSWindows, for example, TEdit uses the definitions from the MSWindows Edit control, so aren't we actually calling a task defined in MSWindows and transferring its owner to Delphi?

    No you are not calling a task as in something that will create and run on different thread, you are merely calling a piece of code (function) that will run in the context of your thread.

     

    25 minutes ago, programmerdelphi2k said:

    OS API thread (performs the actions of a lower level)

    There is no separate OS API thread. your application runs in one OS thread. IN terms of OS application is a process. When you run application you are starting a process that will create and run in new thread. but if your application does not explicitly create another thread everything will just run in that one thread, even when you call Windows API.


  8. 5 minutes ago, programmerdelphi2k said:

    Which thread actually creates the visual control (i.e. the object used by Delphi), the MSWindows API or the pseudo class in Delphi?

    The thread from which you call Windows API. When you call API like CreateWindow or you create object in Delphi there are no other threads involved. (Unless specific API or object is specifically meant to handle thread functionality or is part of some asynchronous API)


  9. 2 hours ago, Fr0sT.Brutal said:

    Why prevents?

    I underscore - we're talking about a control fully isolated inside a non-main thread - this means it has no parent window belonging to another thread of the app. With pure WinAPI window and bg thread running message loop, what issues could arise when talking to that control from main thread only by messages?

    Yes, you can have control that completely runs in the different thread that runs its own message loop. That is different scenario from the one I said - constructing the controls in background thread and then using them in main thread. Using (inside main thread) and merely communicating (sending messages are different things. There are boundaries between controls that belong to different threads. In other words there are different levels of thread-safety. Since Windows API has thread affinity, it is not fully thread-safe. 

     

    In practical terms having such application means that you need to deal with more complexities in places where you otherwise wouldn't, Using UI in same thread means you can use SendMessage to perform operations quickly because in the context of same thread SendMessage will avoid the message queue and will simply run the windows proc. However, when you SendMessage to window that belongs to different thread, SendMessage will go through message queue. But, SendMessage is blocking call and in complex to-way communication between two threads with SendMessage you can easily cause deadlock. OK, solution to that is that you don't use SendMessage, but only non blocking communication, which is slower. and that would probably work if you handle all those windows manually directly through Windows API and you exactly know to which thread they belong to. Assing any abstraction layer on top your be a nightmare (this is where we start stepping into Delphi RTL and visual frameworks).

     

    3 hours ago, Fr0sT.Brutal said:

    I could be wrong here but I want to know what exactly makes WinAPI thread-unsafe.

    Again, thread affinity is what makes it thread-unsafe. Now, you may have different viewpoint on what thread-safe is in this context, but not being completely thread-unsafe is still far from being completely thread-safe.

     

    Some additional reading:

     

    https://devblogs.microsoft.com/oldnewthing/20051010-09/?p=33843

     

    https://devblogs.microsoft.com/oldnewthing/20051011-10/?p=33823

     

    https://devblogs.microsoft.com/oldnewthing/20051012-00/?p=33803

     

    https://devblogs.microsoft.com/oldnewthing/20051013-11/?p=33783

     

    • Like 2

  10. 19 minutes ago, Fr0sT.Brutal said:

    My position: as long as communication to WinAPI control is done via Post/SendMessage (which is the 99% of cases), it is thread-safe.

    There is way more in UI thread safety than thread safe communication between controls.

     

    In Windows API windows can communicate across thread-boundaries, but each window still belongs and is bound to a thread where it is created and that thread's message queue. This basically prevents you to create window control in one thread (background) and use it in another (main).

    • Like 2

  11. 5 hours ago, havrlisan said:

    Android SDK 25.2.5. I highly doubt they'll upgrade their SDK anytime soon as that means they'll have to update all the java interfaces written in Delphi (Androidapi units) and add new ones.

    This version  number is not SDK version it is tools version. SDK version for supporting Android API levels is set in SDK panel in Options dialog under "SDK API level location". You can find which SDK platforms you have installed in SDK\platforms folder. Fro API 33 there should be android-33 folder inside.

     

    Also Java interfaces don't change with each API version and they are pretty stable, so they don't need to be constantly updated. Occasionally, when new API has some additional features or some interfaces are changed Delphi Java interfaces will be changed accordingly. When Embarcadero says they support some API level, that means they actually do support that API level.


  12. 11 hours ago, TazKy said:

    Where is SDK 33?  Are we suppose to get it from Android Studio?  Or is there a weird work around for this problem?

    I am using SDK from Android Studio, so I cannot comment on whether SDK 33 is installed with 11.3. 

     

    You can use Android Studio to update the SDK, but you can also use avdmanager.bat and sdkmanager.bat tools in the <ANDROID-SDK-FOLDER-PATH>\cmdline-tools\bin folder. I am assuming that your referral of missing SDK Manager was about SDKManager.exe that was previously available. See: https://quality.embarcadero.com/browse/RSP-34730

     

    This change is because support for new Android versions required newer Android tools version which no longer ships with SDKManager.exe because Google integrated all those within Android Studio and removed standalone version. See: https://issuetracker.google.com/issues/197818591?pli=1

     


  13. 10 minutes ago, omnibrain said:

    I guess I can't use TThread.Synchronize because that's a whole different library?

    TThread.Synchronize and TThread.Queue are parts of core RTL functionality. You can use them and they are appropriate way to synchronize any Delphi code with main thread, regardless of what other libraries you are using.

     

    BTW, following line also needs to be synchronized with main thread.

    memo1.append(datetimetostr(now)+': Start Processing');
    • Like 1

  14. 3 hours ago, bzwirs said:

    Have reinstalled Delphi with delete registry entries option this time and reinstalled all 3rd party components.....project now opens without error and compiles for Win32.  Unable to compile for Android yet but have found that SDK paths are not there so probably need to reinstall Android SDK.

    Interesting. That would be my last option. I wonder what caused it. When you installed the update, did you reinstall your 3rd party components, too? 


  15. 7 hours ago, bzwirs said:

    At this stage I am thinking about a complete reinstall of Delphi (third party components and all) to see if that helps before I try anything else.

    Do you use any 3rd party controls on that form? Maybe something changed that causes issue in particular component. You can try adding those to your blank project one by one, or try removing them from that unit and fmx file with some other editor. Or maybe even some IDE plugin that is additionally installed could cause the problems.

     

    It is very unlikely that something is wrong with your installation. It is not completely impossible scenario, but I don't think it will help.


  16. I guess that only thing left for you is to report a bug to Embarcadero, if you can create small test case from your project that will show same behavior. 

     

    One way to create a test case would be by copying your dpr and dproj files in another folder and opening that. If that crashes you can add that to the report. If it does not crash, then the problem you are having is in some other file. You can try locating it by copying other files from the project in small groups. Besides that the only other option would be to create new FMX application and add your files to it. I don't have other ideas.


  17. 13 minutes ago, bzwirs said:

    Thanks for your advice Dalija.

     

    I have tried to open it through File/Open as you suggested but that didn't work for me.  Over the next few days (when I get some time) I will try your other option in trying to re-create from scratch.  I'll let you know how it went.

    Opening dpr file works only if you have deleted dproj file. 

     

    Another thig just occurred to me. Have you tried deleting project dsk file, which holds opened IDE files, IDE layout, breakpoints and watches. Maybe something is wrong there and not in your dproj file. 

     

    What is exact error you get?


  18. 35 minutes ago, Lars Fosdal said:

    The only time you would get an issue with performance in the UI, is if the render takes longer than the timer

    This can also be easily solved if you either disable timer while you are updating UI and enable it back when you are finished. Alternative solution is adding some boolean flag and simply skipping UI update if previous update is still running.

    • Like 1

  19. 3 minutes ago, bzwirs said:

    If I remove the .dproj file then I get the following error:

     

    image.thumb.png.c10a74e58c17af10e6d60dc080a16964.png

     

    You get this error because you are trying to open project from recent files which links directly to .dproj file. If you open it through File -> Open and open .dpr then dproj will be recreated.

     

    Anyway, deleting dproj file, while it can help in certain scenarios is not the best course of action, especially for cross-platform FMX projects as you will lose all custom setup required for those projects, but that depends on how complicated your setup is.

     

    If your dproj file is corrupted in some way and it cannot be loaded, then creating brand new project with same name and configuring it from scratch, is better option as autogenerating can cause you other troubles down the road because auto-generation does not properly configure and add all platforms.

    • Like 1
    • Thanks 1

  20. RTTI had (and possibly still has) issues with thread safety when acquiring and releasing pool token. 

     

    Unless you are using Windows application with dynamically loaded packages, the best option to avoid those issues is to call TRttiContext.KeepContext; in initialization section of some base unit and TRttiContext.DropContext; in finalization section. This will create pool token and keep it alive during lifetime of you application, avoiding thread safety issues, and it will also speed up RTTI operations. 

    • Like 3
    • Thanks 1

  21. 53 minutes ago, aehimself said:

    What if the form and all the controls are created runtime by the thread? Then once the thread is completed the main thread can show it.

    This is not possible because constructing forms and controls also interacts with the OS in thread-unsafe way. For instance creating window has thread affinity and window belongs to a thread that creates it. You cannot construct window in one thread and pass it to another. If you remove initialization code that interacts with OS and other thread-unsafe parts, controls would need to have separate initialization that would need to be synchronized with the main thread. This would be rather messy as different controls have different requirements and construction of controls would get additional layer of complexity which would also only slow things down. Forms streaming also uses global lock mechanism to protect global namespace (data modules can be constructed and streamed in background depending on used components), so adding synchronization during loading forms would also open potential for deadlocking, and preventing the deadlocks would also require additional calls and checks which would again slow everything down.

    53 minutes ago, aehimself said:

    I recall a post about a background thread being able to build and even show a form in VCL; it's just two threads should not access it the same time.

    Even if so, maybe that is not even applicable under FMX...

    This never worked in VCL and it does not work in FMX. Threading issues can be hard to catch. Just because you can create some components in background thread without immediately bumping into issues does not mean such code is bug free.

    • Like 3

  22. 2 hours ago, havrlisan said:

    My initial thought was that TBitmap should be creatable and drawable in a background thread, but that doesn't seem possible because of global Canvas lock, and IIRC it also uses the TMessageManager (and that's where I expanded my opinion to all other components). That seems like a good idea, no?

    From OS perspective bitmap operations can be performed in background threads and then bitmap could be transferred to UI for painting. This is where FMX has some issues that could and should be fixed. Same goes for working with 3D graphics primitives.

    • Like 2

  23. 1 hour ago, havrlisan said:

    Thanks for the detailed explanation. So if I understood correctly, FMX is designed in such a way that it is nearly impossible to separate the rendering part (which is done in the main thread) from the rest of the code? If, for example, one would rewrite the framework from scratch, would it be possible to separate the whole control creation and manipulation from the actual canvas drawing? To my understanding, the only part that must be run in the main thread is the drawing on canvas (which directly uses graphics API).

    In theory when writing and GUI framework from scratch, it could be possible to make that framework thread-safe.

     

    But drawing is not the only part that needs to run in the main thread. Any interaction with the OS - creating OS handles (like windows, graphic objects...), mouse interaction, keyboard interaction, OS notifications, needs to run in the main thread. too. Also access to all resources would have to be protected by locks. That means every single field and property inside control. So while background threads would be running doing some work on those controls, UI thread would not be able to use them. Now it may look that this would still be solution if you want to just create and destroy controls in background threads, but again to do that safely ALL access ALL the time have to run through locks, That means even if you never use background threads, accessing and working with UI controls would be much slower ALL the time. Multithreading is not cost free. 

     

    I don't know what is your intent behind the question. Again, the fact that FMX is not thread-safe is not a flaw in its design, or anything similar. It is because thread-safe UI frameworks are basically non existent (I am saying basically, because like I said in theory they are possible, but I don't know about any). All major OS-es have thread-unsafe UI frameworks: Windows, Linux, Android, iOS, macOS - simply because making those thread-safe does not make sense. 

     

    Thread safety is not just about throwing locks around some lists, but also defining what interactions need to logically happen without any interruptions from other threads. That would mean locking would have to extend to much broader code besides just accessing lists, and the more complex the scenarios (and UI are extremely complex frameworks with complex code paths) the more chances are that there will be bugs and concurrency issues that cannot be easily resolved.

     

    Patching FMX to add thread-safety is impossible as it is not just adding few locks here and there, it would have to be thorough rewrite. If you want to write your own framework, you are always free to do so, but I would have to ask "You and what army?" 

    • Thanks 1

  24. 44 minutes ago, havrlisan said:

    Besides these, what else could be an issue?

    Plenty.

     

    User interfaces in general (not just Delphi) are not thread-safe. Thread safety comes with hefty price. You would have to lock just about everything and it would significantly slow down the UI. Also, UI controls are complex and have plenty of interactions. Due to that complexity, making UI thread-safe would be complicated and error-prone. Not only that, but UI needs to interact with OS layer where UI controls are also not thread-safe as such where you cannot access the same control from different threads. That means if you would construct one control in background thread to be used in main thread afterward, not only you would have to make sure that interaction with Delphi UI side of controls have to be thread-safe, but control would have to avoid triggering any code that interacts with OS part which is almost impossible.

     

    UI is not thread-safe by design and that is something that will not change as it is not practical nor beneficial. 

     

    There are some parts around handling images that could be fixed to fully support processing images in background threads and then passing them to the UI for presentation.

    • Like 2
×