-
Content Count
247 -
Joined
-
Last visited
-
Days Won
11
Everything posted by Primož Gabrijelčič
-
Issue with several TOmniContainerWindowsMessageObserver for the main thread
Primož Gabrijelčič replied to Fulgan's topic in OmniThreadLibrary
I don't understand how that should work. "Several windows are interested in receiving messages from the queue" - are they then fighting to fetch that message? It is quite possible that something goes wrong in such case. I don't believe I ever tested such setup. Can you get me a sample program so I can repeat the problem? -
message posted to a queue not processed until application.processmessage is called
Primož Gabrijelčič replied to Fulgan's topic in OmniThreadLibrary
I thought your code that calls Application.ProcessMessages runs in the main thread. (Otherwise you really should not do that.) If it is running in a background thread, I don't know. I would have to see a working (and as minimal as possible) test program that exhibits your problem to tell you more. Re 1: I assumed FTask is your task controller. So reading from its Comm property would read messages sent FROM the task. Re 2: Task.Comm.Receive runs in the task thread and it DOES receive messages that were sent TO the task. -
message posted to a queue not processed until application.processmessage is called
Primož Gabrijelčič replied to Fulgan's topic in OmniThreadLibrary
When you send a message from a background thread to the main thread, the message is inserted into internal message queue and a Windows message is dispatched to a hidden window created by the main thread. (Actually, by the thread that created the task, but in your case this is the main thread.) When this hidden window receives and processes the message, all messages from the internal message queue are fetched and processed. The Application.ProcessMessage call triggers the message loop so Windows messages may be processed. Similarly, if a background thread creates OTL task, that background thread (the owner) must call MsgWaitForMultipleObjects[Ex] so that messages are processed. (Alternatively, if that background thread (the owner) is itself an OTL thread, you can create it with modifier .MsgWait.) IOW, if you want to use messaging subsystem, messages must be processed. You can pump the FTask.Comm channel manually during the wait. Instead of Sleep(10) you can call FTask.Comm.Receive(msg, 10). This will return False on no message and True if there was a message in the queue (in which case it is fetched and stored in the `msg` parameter.) Then you will not need Application.ProcessMessages. -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
As expected. I think we now all agree on how it works 🙂 -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
Indeed. That's what I was trying to say four posts back 🙂 -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
@Dalija Prasnikar Test started TTestObj.Create obj = TTestObj End of nested scope Test completed TTestObj.Destroy -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
Makes sense. In your code an 'inline var' is an interface of type `IShared<TTestObj>` and is destroyed at the end of the owning scope (begin..end). In my code, the 'inline var' is of type `TTestObj`. The `IShared<TTestObj>` interface is just something that was created during the execution and is owned by the method itself. -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
Nope. Interface is cleared - and object destroyed - in the final `end` of the method. I verified with the debugger. -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
I ran a test in Rio and it works quite well: type TTestObj = class public constructor Create; destructor Destroy; override; end; constructor TTestObj.Create; begin inherited Create; Writeln('TTestObj.Create'); end; destructor TTestObj.Destroy; begin Writeln('TTestObj.Destroy'); inherited; end; procedure Test; begin Writeln('Test started'); begin var obj := Shared.Make(TTestObj.Create)(); Writeln('obj = ', obj.ClassName); Writeln('End of nested scope'); end; Writeln('Test completed'); end; Output: Test started TTestObj.Create obj = TTestObj End of nested scope Test completed TTestObj.Destroy Inline var object is not destroyed at the end of scope, but at the end of the method. Still, that's something I more or less expected. Other than that, the code works fine. For the record, this can also be achieved with the "traditional" syntax. Delphi will kindly keep the interface alive until the end of the method: procedure Test; var obj: TTestObj; begin Writeln('Test started'); obj := Shared.Make(TTestObj.Create)(); Writeln('obj = ', obj.ClassName); Writeln('Test completed'); end; And there's also a bit slower but shorter variation to create a shared object: Shared<TTestObj>.Make() Just saying 😉 -
Smart Pointers - Generics vrs non-generic implementastion
Primož Gabrijelčič replied to pyscripter's topic in RTL and Delphi Object Pascal
@pyscripter You don't need a temp variable at all: procedure MeasureSpring; var i: Integer; begin with Shared.Make(TStringList.Create)() do for i := 1 to ADD_COUNT do Add(i.ToString); end; Just ... with ... brrrr, terrible. This may also work (didn't test): procedure MeasureSpring; begin // something ... begin var s := Shared.Make(TStringList.Create)(); for var i := 1 to ADD_COUNT do s.Add(i.ToString); end; // something ... end; I would really like Embarcadero to enhance `with` block in that direction, so I could write: procedure MeasureSpring; begin with var s := Shared.Make(TStringList.Create)() do for var i := 1 to ADD_COUNT do s.Add(i.ToString); end; This should compile to the same code as my second example. (Except that at the moment it is not support.) -
Conditional compilation for various Delphi versions
Primož Gabrijelčič replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
And sometimes fighting with bugs becomes too much and you just remove some functionality for specific subset of compilers. That's why OTL uses OTL_Generics and OTL_GoodGenerics. -
Conditional compilation for various Delphi versions
Primož Gabrijelčič replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
In my opinion, the best solution is to use jedi.inc and then IFDEF against features (SUPPORTS_OVERLOAD, SUPPORTS_GENERICS, HAS_UNIT_VCL_THEMES ...) and not against Delphi versions. -
Version 3.07.6 brings official support for Delphi 10.3 Rio, few changes and bugfixes. You can get it now on git, download the ZIP archive, install it with Delphinus or with GetIt (soon). For more information, visit OmniThreadLibrary home page or write your question on this forum. New features Implemented TOmniValue.LogValue. Implemented TOmniBlockingCollection.FromArray<T>, .FromRange<T>, and .AddRange<T>. Added timeout parameter to TOmniMREW.TryEnterReadLock and TOmniMREW.TryExitReadLock. Bug fixes Fixed race condition in TOmniBaseBoundedQueue.RemoveLink which could cause TOmniBaseBoundedQueue.Enqueue to return False when the queue was empty. Fixed race condition between TOmniResourceCount.[Try]Allocate and TOmniResourceCount.Release. [tnx to Stephen Melnyk] ThreadData is destroyed in the worker thread and not in the thread pool management thread. Reduced hints&warnings.
-
OmniThreadLibrary 3.07.6
Primož Gabrijelčič replied to Primož Gabrijelčič's topic in OmniThreadLibrary
Now also available on GetIt. -
What is the fastest way to check if a file exists?
Primož Gabrijelčič replied to dummzeuch's topic in Windows API
Why don't you test and tell us? 🙂 (I have no idea but it would be good to know.) -
Speed up reading multiple text files
Primož Gabrijelčič replied to dummzeuch's topic in RTL and Delphi Object Pascal
And just to prevent misunderstanding - my longer solution was not attempting to speed up the sorting but the whole process. -
Speed up reading multiple text files
Primož Gabrijelčič replied to dummzeuch's topic in RTL and Delphi Object Pascal
Indeed, TStopwatch.ElapsedMilliseconds works great. -
Speed up reading multiple text files
Primož Gabrijelčič replied to dummzeuch's topic in RTL and Delphi Object Pascal
Loading 2800 files in 4 seconds doesn't seem slow to me ... Sorting is damn slow, though. Maybe IntroSort from Spring4D can do it better. I know @Stefan Glienke introduced some optimizations for fast element swapping (which should help with strings). How much time do you want to spend with this? The fastest solution would definitely be: Load each file into one large block of memory. Scan the file and find all strings. Put the offset to each string into a list. Replace each #13#10 with #0#0 during the process. Sort this list with a custom comparison method which follows the offset into the large block of memory and uses that string for comparison. You can treat strings as PChars as they will be #0 terminated. Note: allocate one byte more than the file size for each block and put #0 in the last byte to ensure that the last string is properly terminated. After you have that working, you can parallelize the loading and scanning process for additional fun. -
Speed up reading multiple text files
Primož Gabrijelčič replied to dummzeuch's topic in RTL and Delphi Object Pascal
"Did you measure it?" 🙂 I can confirm that sorting at the end is faster. Before we start guessing, however, you should do some profiling. -
Just a quick note - last OTL release compiles and works fine in Rio. here will be a new release with some bugfixes and official Rio support in few days.
-
Today I was porting some legacy code and noticed a weird warning: Weird warning, I thought. Obviously the loop variable can be passed as a var parameter as the code compiles. Why a warning and not an error, then? Stefan later reminded me that warnings are quite extensively covered in the documentation. Indeed, the docs for W1015 clearly state: Ah! So they actually want to say “… FOR-Loop variable ‘i’ should not be …” Furthermore, this brings several interesting possibilities to the table. For example, we can finally write for..to..step loops in Delphi! program ForInStep; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; procedure Step(var loop: integer; step: integer); begin loop := loop + step - 1; end; var i: integer; begin for i := 1 to 10 do begin Writeln(i); Step(i, 2); end; Readln; end. Indeed, this works! Danger, Will Robinson! To be clear, I do not recommend writing such code. If you get warning W1015, you should rewrite the code. Such code is hard to maintain and will eventually cause you big problems. I certainly did fix the original code although the method that was called from the for loop did not modify its var parameter. (It was declared var and not const because the method was written before const parameters were introduced to Delphi. Oh, the joys of legacy code!)
-
For..to..step in Delphi
Primož Gabrijelčič replied to Primož Gabrijelčič's topic in Tips / Blogs / Tutorials / Videos
As I have said: -
For..to..step in Delphi
Primož Gabrijelčič replied to Primož Gabrijelčič's topic in Tips / Blogs / Tutorials / Videos
Of course, Andre. There are many ways of doing this in a clean manner. You can also write a nice iterator and call for i in Range(1, 10, 2) do That was not a point of the post, though. I wanted to point out one shady part of our bellowed language. -
Smart Mobile Studio 3.0.1 is released This is the first release since 3.0. Biggest new feature is TW3LeafletMap, which lets you use OpenStreetMap. As it does not need API keys (like TW3GoogleMaps), it’s really fast and easy to use: Create a project Add a TW3LeafletMap -control on the form Set AutoCreateMap to true on the map control Please see the changelog at the end of this post. Installers Smart Mobile Studio installer Free command-line compiler Portable installation Smart Mobile Studio can also be downloaded with the SmartUpdate utility. Select the MASTER -channel for the official version. Changes since 3.0 RTL EventManager Add procedure AllowDefaultAction, that can be called from OnClick when the default action should happen. For example: To let the virtual keyboard to pop up from OnTouch. Bug fixes Native scrolling was prevented if scrolling was done from an unknown element. Prevent an extra OnClick from being fired on mobile devices. TW3ListView: Bug fix to resizing of items. Bug fixes to GeoLocation. Also update the Geolocation demo. Deprecate PhoneGapAPI’s JGeolocation functions. SmartCL.GeoLocation.pas should be used instead. Fix slider so that OnMouseDown, OnMouseUp and OnMOuseMove can be used. TW3TabControl Tab’s OnShow was sent twice for the first tab SmartCL.RegEx moved to System.RegEx. Also fixed TW3RegEx.Exec to return a proper empty array instead of nil. Bug fix to Chart: TSeriesData.Refresh now also updates the X axis SmartCL.Effects: Properly handle padding and margins while doing effects. Fix to css-files for selected text in TW3Edit and TW3Memo TW3Grid Added TW3ImageColumn Add Alignment-property to TW3ColumnHeader Added a new OnCellControlCreated-event, which fires when a button, toggle, progress bar or image is created. Makes it possible to change properties of the control easily. Added support for OpenStreetMap using the Leaflet library New control: TW3LeafletMap New featured demo: LeafletMap IDE/Compiler Fixed search path compilation issues Relative and absolute paths are working now Compiler is updated when search path is modified in options $I will look for include file in the project folder first $R supports absolute paths, wildcards, folder name extension and ($Libraries) macro Fix exceptions in Search Upgrade to UPX 3.95
- 2 replies
-
- smartmobilestudio
- javascript
-
(and 3 more)
Tagged with:
-
Looks good to me. Stays fine if I resize the form. If you want me to test something specific, let me know. Primož