Jump to content

pyscripter

Members
  • Content Count

    785
  • Joined

  • Last visited

  • Days Won

    42

Posts posted by pyscripter


  1. @Anders Melander

     

    You are using an old version of SynEdit.  The key difference is the calls to UnionRect in TCustomSynEdit.InvalidateLines.  Please compare to the SynEdit master branch.  The difference is subtle, but in effect in your version any character entry invalidates the whole Window and this why you PaintTransient works.

     

     UnionRect(fInvalidateRect, fInvalidateRect, rcInval)

     

    is not the same as

     

    UnionRect(fInvalidateRect, rcInval, fInvalidateRect)!

     

    when fInvalidateRect is empty!


  2. Another issue with your code is that since you are using TArray.BinarySearch your bracket array needs to be sorted.

     

    But 

    OCSYMBOLS: Array[0..7] Of Char = ('(', ')', '{', '}', '[', ']', '<', '>');

    is not.

    • Like 1

  3. By the way in the code above:

      a := SynEdit1.RowColToCharIndex(bufcoord);

    followed by

     c := SynEdit1.Text[a];

    in fact twice, is not efficient.   

     

    You are better-off just using

    c := SynEdit1.Lines[bufcoord.Line][bufcoord.Char]

     

    • Like 1

  4. Anders is probably not using TurboPack SynEdit.  His version of SynEdit is not handling ttBefore painting and the only way this can work is if SynEdit invalidates everything every time a character is typed.

     

    Turbopack SynEdit painting has been optimized to avoid flicker, so his version of Bracket Highlighting will not work with Turbopack SynEdit.

     

    I have committed some changes to Turbopack SynEdit (see Matching brackets highlighting with PaintTransient handler error · Issue #110 · TurboPack/SynEdit (github.com)).  Could you please try with the latest version and see whether it now works correctly?


  5. I think the above should work.  Have you enabled the generation of RTTI in your project?

    Does adding {$M+} help like in:

    {$M+}
    ITestInterface = interface(IInterface)
    ['{AD50ADF2-2691-47CA-80AB-07AF1EDA8C89}']
      procedure SetString(const S: string);
      function GetString: string;
    end;
    {$M-}

     


  6. 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).

    • Like 1

  7. 5 hours ago, Dalija Prasnikar said:

    How is this useful in combination with PPL I still cannot figure out.

    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. 

     

    5 hours ago, Dalija Prasnikar said:

    But, have you ever tried debugging such asynchronous HTTP requests.

    I would argue that debugging any asynchronous application is kind of hard to put it mildly.


  8. @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. 

    1 hour ago, Uwe Raabe said:

    OK, it may still be true that for today no one else actually knows how to use it properly.

    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;

     


  9. 1 hour ago, Vincent Parrett said:

    Does embarcadero have a chief architect these days - someone to guide the overal design of the rtl and frameworks? Doesn't seem like it. I miss the days when we have people like Allen Bauer - every major feature was carefully considered with regards to future impact etc.  

    This does appear to be the work of Allen, same as the Delphi Parallel Library.  He blogged about it back in 2008.

     

     


  10. 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?


  11. 1 hour ago, David Heffernan said:

    I find that hard to believe. That operation is disk bound, or if the file is in disk cache then it is memory bound. 

    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.


  12. 26 minutes ago, David Heffernan said:

    Yes you can. After all, CharInSet is implemented using the in operator.

    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?

    • Like 1

  13. 11 minutes ago, David Heffernan said:

    Unless I missed something, that's not the question in the original post. Is that what you are asking?

    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.


  14. 24 minutes ago, David Heffernan said:

    For instance you may be looping through the elements in a string. 

    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.


  15. 8 minutes ago, Lars Fosdal said:

    A char in a Unicode string is a word, not a byte.  The old set operator is useless for Norwegian characters, unless you convert to ANSI - and that is not desirable.

    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.

×