-
Content Count
920 -
Joined
-
Last visited
-
Days Won
56
Everything posted by pyscripter
-
I am afraid the download link does not work.
-
You can use TPyDelphiWrapper.WrapInterface to wrap interfaces. Have a look at Tests/WrapDelphiTest.pas to see how this works. Alternatively the PyWin32 python module has its own way of wrapping Com objects.
-
python4delphi Python4Delphi module and Wrapping VCL classes
pyscripter replied to shineworld's topic in Python4Delphi
Are you talking about code completion in the editor or the interpreter? If it is in the editor does it help to add you delphi module to Tools, Options, IDE Options, Code Competion, Special packages? You need to restart PyScripter or the Language server. The other thing you could is to create a stub file for your python extension module (see for instance PyScripter: Completion with python extension modules such as PyQt5 and Pandas). -
What is the best (fast) way of checking if a string is number?
pyscripter replied to wuwuxin's topic in Algorithms, Data Structures and Class Design
Have a look at the routines in SVGIconImageList/SVGCommon.pas at master · EtheaDev/SVGIconImageList (github.com) (GetExtended in the implementation section). They were "stolen" from synopse/mORMot: Synopse mORMot ORM/SOA/MVC framework (github.com) and they did make a big difference when parsing SVG files. -
SmartPointer implementations, Pros's and Con's
pyscripter replied to Rollo62's topic in Algorithms, Data Structures and Class Design
I think yes after the fix discussed in this thread. -
SmartPointer implementations, Pros's and Con's
pyscripter replied to Rollo62's topic in Algorithms, Data Structures and Class Design
The Spring4D is the best. If you use Spring4D stick to it. -
Is anybody using the Asynchronous Programming Library? AFAICT, it works like TThread.Synchronize/Queue/ForceQueue, but it gives you greater control on the tasks executed asynchronously. (Cancel, Wait etc.) TComponent.BeginInvoke(procedure begin end, nil).Invoke just uses TThread.Queue. TWinControl.BeginInvoke(procedure begin end, nil).Invoke processes the procedure in the event loop of the WinControl. Are there any examples of usage?
-
Asynchronous Programming Library
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
IAsyncResult is a higher level of abstraction than PPL. You want the async backend to be TThread.Queue, Anonymous Threads, PPL, OmniThread, processing in a message loop, all you have to do is overwrite one method. I would argue that debugging any asynchronous application is kind of hard to put it mildly. -
Asynchronous Programming Library
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
@Vincent Parrett@Dalija PrasnikarI was also quick to dismiss it and I disliked the fact that the functionality is under TComponent. However, after a bit of digging it appears that it does have some nice touches. For example TComponent, uses Thread.Queue to run the tasks and WinControl uses the message loop. But a component descendent can overwrite just one method AsyncSchedule to use the Parallel Libary or OmniThread to run the tasks, e.g.. // Disclaimer: Have not tested! type TPPLComp = class(TComponent) protected procedure AsyncSchedule(const ASyncResult: TBaseAsyncResult); override; end; procedure TPPLComp.AsyncSchedule(const ASyncResult: TBaseAsyncResult); var LState: TComponentState; begin LState := FComponentState; // Snag a local copy if csDestroying in LState then raise EInvalidOperation.CreateRes(@sBeginInvokeDestroying); TTask.Create(ASyncResult.DoAsyncDispatch).Start; end; But I confess I do not see the benefits in the above compared to using TTask.Create directly. ITask and IAsyncResult look quite similar. I have not tested but it does not appear to be that hard. var Comp := TComponent.Create(nil) var AsyncResult := Comp.BeginInvoke(procedure begin end, nil); is equivalent to TThread.Queue(nil, procedure begin end); But with a former method you can do a bunch of stuff with AsyncResult (Wait, Cancel, etc,). Also BeginInvoke takes as an argument an Object (Context) that can be useful in some scenarios. And BeginInvoke works with functions and allows you to get a Result back. (like a Future). It appears that the only reason BeginInvoke is a member of TComponent and not even a class function is to offer the ability to customize the dispatch in TComponent descendents: procedure TComponent.TComponentAsyncResult.Schedule; begin FComponent.AsyncSchedule(Self); FComponent := nil; end; -
Asynchronous Programming Library
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
This does appear to be the work of Allen, same as the Delphi Parallel Library. He blogged about it back in 2008. -
Further to a previous post of mine, I have done some benchmarking to compare the different alternatives. I am using some old benchmark code from Barry Kelly and added a few more options (word of char in, Char.IsInArray and if then). Here are the 6 ways compared: while not CharInSet(cp^, [#0, #13, #10]) do case statement while not (cp^ in [#0, #13, #10]) do (raises a warning) while not (Word(cp^) in [$0, $A, $D]) do while not (cp^.IsInArray([#0, #13, #10])) do while (cp^<>#0) and (cp^<>#$A) and (cp^<>#$D) do Results with optimization turned on. Win32 1. CharInSet: 0.037 seconds 2. case stmt: 0.039 seconds 3. set test: 0.036 seconds 4. Word set test: 0.037 seconds 5. InArray test: 0.219 seconds 6. if and test: 0.037 seconds Win64 1. CharInSet: 0.106 seconds 2. case stmt: 0.047 seconds 3. set test: 0.042 seconds 4. Word set test: 0.044 seconds 5. InArray test: 0.248 seconds 6. if and test: 0.036 seconds What is worrying is that in 64 bits both CharInSet and IsInArray (the recommended options) are much slower than the alternatives. CharInSet is an inlined version of Option 3, but the code cannot take advantage of the specific contents of the set. Here is the assembly code: CharInSet.dpr.15: while not CharInSet(cp^, [#0, #13, #10]) do 0000000000429DAA 480FB708 movzx rcx,word ptr [rax] 0000000000429DAE 6681F9FF00 cmp cx,$00ff 0000000000429DB3 7711 jnbe P1 + $36 0000000000429DB5 480FB7C9 movzx rcx,cx 0000000000429DB9 480FA30D37000000 bt [rel $00000037],rcx 0000000000429DC1 0F92C1 setb cl 0000000000429DC4 EB02 jmp P1 + $38 0000000000429DC6 33C9 xor ecx,ecx 0000000000429DC8 84C9 test cl,cl 0000000000429DCA 74DA jz P1 + $16 CharInSet.dpr.41: while not (cp^ in [#0, #13, #10]) do 000000000042A05A 480FB708 movzx rcx,word ptr [rax] 000000000042A05E 6683F90F cmp cx,$0f 000000000042A062 7716 jnbe P3 + $3A 000000000042A064 66BA0100 mov dx,$0001 000000000042A068 D3E2 shl edx,cl 000000000042A06A 480FB70D3A000000 movzx rcx,word ptr [rel $0000003a] 000000000042A072 6685CA test dx,cx 000000000042A075 0F95C1 setnz cl 000000000042A078 EB02 jmp P3 + $3C 000000000042A07A 33C9 xor ecx,ecx 000000000042A07C 84C9 test cl,cl 000000000042A07E 74D6 jz P3 + $16 CharInSet.dpr.51: while not (Word(cp^) in [$0, $A, $D]) do 000000000042A1AA 480FB708 movzx rcx,word ptr [rax] 000000000042A1AE 6683F90F cmp cx,$0f 000000000042A1B2 7716 jnbe P4 + $3A 000000000042A1B4 66BA0100 mov dx,$0001 000000000042A1B8 D3E2 shl edx,cl 000000000042A1BA 480FB70D3A000000 movzx rcx,word ptr [rel $0000003a] 000000000042A1C2 6685CA test dx,cx 000000000042A1C5 0F95C1 setnz cl 000000000042A1C8 EB02 jmp P4 + $3C 000000000042A1CA 33C9 xor ecx,ecx 000000000042A1CC 84C9 test cl,cl 000000000042A1CE 74D6 jz P4 + $16 Options 2 and 6 are too verbose and Options 1 and 5 too slow. Option 4 (Word(cp^) in [$0, $A, $D]) produces the same code as option 3 (cp^ in [#0, #13, #10]) without raising an exception and it sounds like a good choice. Any downsides? Incidentally combining any of the above options with an initial test for the most common case e.g. while (Word(cp^) > $D) or not (Word(cp^) in [$0, $A, $D]) do is much faster! Source code attached. CharInSet.dpr
-
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
I am not saying that this is the bottleneck. But saving say 1-2/10ths of a second when loading a large file is not insignificant. Especially if it can be easily done. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
Isn't this what you are doing with Spring4D? -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
That begs the question why have the warning and introduce CharInSet only to avoid the warning in the first place. Why din't Embarcadero just eliminate the warning? -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
Yes indeed. StringLists, TTextReader, SynEdit are full of this kind of shit. When you load a big file scanning millions of characters that has an impact. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
The original post was about the best way to replace P^ in [#10, #13] with something concise and efficient in order to avoid the warning assuming the warning is valid. It also showed that the recommended way CharInSet is slow in Win64. So I guess there are two parts to the question: Can I safely ignore the warning? What is a concise and efficient way to achieve the same without a warning? The post also suggests that Ord(P^) in [10, 13] appears to be a good way of avoiding the warning without sacrificing speed or conciseness. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
You could suppress just this warning by {$WARN WIDECHAR_REDUCED OFF} while (P < PEndVal) and not (P^ in [#10, #13]) do Inc(P); {$WARN WIDECHAR_REDUCED ON} I prefer the shorter while (P < PEndVal) and not (Ord(P^) in [10, 13]) do Inc(P); The question still is whether the warning makes any sense. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
Exactly. For instance in Classes.TStringList,SetTextStr you have the following: while (P < PEndVal) and not (P^ in [#10, #13]) do Inc(P); P is a PChar (unicode characther). The problem is that if I put such code in my program it raises a warning. The whole (only) point of CharInSet is to avoid the warning, alas it appears suffering a speed penalty in Win64. My original posts examines alternatives that avoid the warning and the speed penalty. The warning is idiotic. You get the same warning if you write while (P < PEndVal) and not (P^ in [AnsiChar(#10), AnsiChar(#13)]) do Inc(P); So the warning is about downcasting the Unicode char to an AnsiChar. But if you look at the generated code, the compiler does the right thing and does not downcast the Unicode char. It compares the Word value of the Unicode char to the values of the elements of the set. It does the same thing as if you wrote: while (P < PEndVal) and not (Word(P^) in [Ord(#10), Ord(#13)]) do Inc(P); which does not raise a warning. I would appreciate an explanation of the rationale of this warning. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
Sure. The CharInSet and the like are useful if you want to search your unicode string for unicode chars with values less than 255 and typically less than 128. Chars like " : CR LF \ /. These values can be represented as a Delphi set. This is a common operation and that's why doing it efficiently is important. -
CharInSet revisited (again)
pyscripter replied to pyscripter's topic in RTL and Delphi Object Pascal
All of the above assume that the characters you are looking for have a value less than 256 so that the set can be represented as a Delphi Set. Otherwise TCharHelper.IsInArray or the case statement are the only readily available options. -
In System.Classes we have the following: destructor TList.Destroy; begin Clear; end; I know that TObject.Destroy does nothing. Is calling inherited Destroy from TObject direct descendants just a good practice or there are other considerations? Is the omission of the call to inherited just to save a few ms for the call to an empty procedure?
-
The new High DPI Form Designer in Delphi gives you the following choices: Low DPI (96) default Auto DPI FIxed DPI Choice sounds good, however none of the choices is satisfactory: Working with the Low DPI setting in a High DPI monitor is next to impossible given the minute size of the form. Auto DPI is the version control nightmare. If you have different developers working with different screen resolutions, or even one developer working on say sometimes on a desktop with a DPI 96 and sometimes on a high DPI laptop, every time you touch the form on a machine with a different resolution all the coordinates widths and heights of the components will change. Absolutely no go. Fixed DPI has the same issues as Low DPI. You set the Fixed DPI to match one of the screen resolution, but when you open the form to another computer the form will show either too big or too small. What I would like to have is Fixed DPI, so that you avoid the version control issues, but automatic scaling of the form into the Screen coordinates and back to the Fixed DPI when you save the form. I know that the scaling from one DPI to another and back may result in changes of the original values. But the scaling back to the Fixed DPI does not need to happen unless a control is moved or resized. Is it just me that have issues with High-DPI designer? @Marco Cantu @David Millington Your comments will be appreciated.
-
Python code is running in main thread (on standard) ?
pyscripter replied to diaroeh's topic in Python4Delphi
And here is a less simple way running Python code in a thread and keeping the main thread free to handle printing. It also shows how to buffer the output. LessSimpleDemo.zip -
Python code is running in main thread (on standard) ?
pyscripter replied to diaroeh's topic in Python4Delphi
Here is a super simple approach. SimpleDemo.zip -
Python code is running in main thread (on standard) ?
pyscripter replied to diaroeh's topic in Python4Delphi
Have you set UnicodeIO to true? Otherwise the OnSendData handler is called instead of OnSendUniData.