Jump to content

SwiftExpat

Members
  • Content Count

    94
  • Joined

  • Last visited

  • Days Won

    4

Everything posted by SwiftExpat

  1. I am signed up. Anything I can learn ( or hear out loud and realize that I actually understand the effect of the code I am writing ) is worth my time. This is a focused topic, I expect the content will be more focused than 'choosing the best ui framework for x' .
  2. SwiftExpat

    TDataModule OnDestroy event never triggered?

    OnSaveState did not fire when I tested 😞
  3. SwiftExpat

    Split String

    split the string based on the delimiter for the last string in the list, ('0011') convert to integer (11) and increment (12) convert the int back to a string ('12') compare the lengths and then loop to add in the padding zeros ('0012') concate the list back to 1 string
  4. SwiftExpat

    TDataModule OnDestroy event never triggered?

    Many of those lines are just there just to be able to place break points and verify what lines are actually executed (or not executed ) when the application terminates. Think of the situation where you need a child window, when that window is destroyed ( destroyed and closed are not the same ). In the parent window you would call free on the child window to have the destructor called.
  5. SwiftExpat

    TDataModule OnDestroy event never triggered?

    I thought about this one quite hard today, a bit of fun learning, and here is my suggestion. FMX has the following mapped: procedure TPlatformCocoa.Terminate; begin FRunning := False; FTerminating := True; TMessageManager.DefaultManager.SendMessage(nil, TApplicationTerminatingMessage.Create); NSApp.terminate(nil); end; So in my app I implemented it as this , similar to what they recommend for android. unit dmDestroyMe; interface uses System.SysUtils, System.Classes, System.Messaging; type TDestroyVersion = class public VersionString: string; constructor Create; destructor Destroy; override; end; TDestroyMeDM = class(TDataModule) procedure DataModuleCreate(Sender: TObject); procedure DataModuleDestroy(Sender: TObject); private FVersion1, FVersion2: TDestroyVersion; v1, v2: string; msgSubId: integer; procedure ApplicationTerminatingHandler(const Sender: TObject; const Msg: TMessage); public { Public declarations } end; var DestroyMeDM: TDestroyMeDM; implementation {%CLASSGROUP 'FMX.Controls.TControl'} {$R *.dfm} { TDestroyVersion } uses FMX.Forms; constructor TDestroyVersion.Create; begin VersionString := '1.2.3.4'; end; destructor TDestroyVersion.Destroy; begin VersionString := '0.0.0.0'; inherited; end; procedure TDestroyMeDM.ApplicationTerminatingHandler(const Sender: TObject; const Msg: TMessage); begin v1 := '0.0.1.0'; Fversion1.Free; v2 := '0.1.0.0'; end; procedure TDestroyMeDM.DataModuleCreate(Sender: TObject); begin v1 := '2.0.1.0'; v2 := '3.1.0.0'; FVersion1 := TDestroyVersion.Create; FVersion2 := TDestroyVersion.Create; msgSubId := TMessageManager.DefaultManager.SubscribeToMessage(TApplicationTerminatingMessage, ApplicationTerminatingHandler); end; procedure TDestroyMeDM.DataModuleDestroy(Sender: TObject); begin FVersion2.Free; TMessageManager.DefaultManager.Unsubscribe(TApplicationTerminatingMessage, msgSubId, true); end; end. I will keep looking for the QP issue, but honestly this is one they expect you to implement. I just did not have the experience when I saw this the first time around. DestroyMe.zip
  6. SwiftExpat

    TDataModule OnDestroy event never triggered?

    On MacOS the process is killed, so the app never gets to shutdown correctly. I opened a support ticket with Embarcadero and was not given a resolution to this. I ended up with a timer to save state every x seconds 😞 Maybe someone else has a better solution.
  7. SwiftExpat

    TDataModule OnDestroy event never triggered?

    2 basics that might help take this thread further. What platform are you debugging on? Just to be sure, are you compiling in Debug not Release?
  8. It is worth reporting in QP. As a work around you could create a link and then add that linked folder to the end of your search path. Creates a symbolic link. MKLINK [[/D] | [/H] | [/J]] Link Target /D Creates a directory symbolic link. Default is a file symbolic link. /H Creates a hard link instead of a symbolic link. /J Creates a Directory Junction. Link Specifies the new symbolic link name. Target Specifies the path (relative or absolute) that the new link refers to.
  9. SwiftExpat

    Android: Opening files in external application

    Mustafa, Great job putting together that readme for your github repo. I like the inline samples and android version cross references.
  10. SwiftExpat

    Windows APIs?

    https://docs.microsoft.com/en-us/windows/win32/api/_wua/ You should almost be able to follow this C# example https://stackoverflow.com/questions/64203306/c-sharp-get-pending-windows-updates-updates-that-cant-be-found Also you might prototype it in powershell just to make sure you are getting the results you want before you spend time writing Delphi code. here is almost a step by step https://mcpmag.com/articles/2016/06/23/finding-pending-updates.aspx
  11. You can also get the line size with sysinternals coreinfo, output looks like this: Logical Processor to Cache Map: **---------- Data Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 **---------- Instruction Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 **---------- Unified Cache 0, Level 2, 512 KB, Assoc 8, LineSize 64 ************ Unified Cache 1, Level 3, 32 MB, Assoc 16, LineSize 64 --**-------- Data Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 --**-------- Instruction Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 --**-------- Unified Cache 2, Level 2, 512 KB, Assoc 8, LineSize 64
  12. SwiftExpat

    F2084 Internal Error: D33566

    If that happens consistently, then you might be able to trace the last unit compiled using sysinternals process monitor. Having that might help you work backwards into a "reproduce failure package". You would have to judge if that activity is worth the effort, and i honestly do not know if it will fix anything for you. I always disable Enable Unit Directory Cache under Computer\HKEY_CURRENT_USER\SOFTWARE\Embarcadero\BDS\22.0\Compiling
  13. The client only knows / reacts to what it sends receives, so it could stay established. Sending keep alives is still a possible strategy. You can still have a timer on a router expire and the router will not send anything to the client(s). at that point it should be a re-transmit. It is still worth asking your network guys to understand if there is anything in the middle. Especially a load balancer in front of that HTTP server.
  14. SwiftExpat

    New Delphi job opportunity

    They are not even planning on having full time trained staff. An MBA will tell you something like, "IT should be 1% of budget". The employer believes (plans) they have 2 options, outsource the project at a fixed price (which is never really fixed) or hire 3-4 low cost developers. The last developers I worked with in Brazil explained the situation, school is on the first floors of a tall building. Floors 7-8 were for our company, and our competition had floors 11&12. So when they go down for coffee at street level they are recruited, for a small pay increase, so naturally you they jump after 6 months. I don't blame them, it is better pay. School is also heavily sponsored by Microsoft and Oracle, so no surprise what they were trained in. The contract negotiators go in a room and promise to provide a complete solution and a fully trained staff at a fixed cost (except travel expenses and ...). And they substitute players whenever they feel like it (see the above, just a different angle). So no it does not compute. If you are the full time company employee, you will be looking for that career change. The circle just continues.
  15. My guesses are: TCP connection went into timewait on the client. Netstat is the only tool that I am aware will show you this, so you need to wrap it in loop and capture the output. Router killed it to conserve memory. The registry reference you are looking for is here (older version, but you can adjust): https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc757512(v=ws.10) It is a mix of timed wait and keep alive that you try to tune. I have only had mixed success trying to keep long db connections open, the keepalives are often killed at the firewall / router level. A lot of modern network equipment tracks those connections and kills them to save router memory. I help it helps you to get some insight.
  16. I just had some time to look for examples of 9 axis and that is incredible work. Your UI looks good and I think it is interesting to extend via python. You should be Embarcadero's case study 🙂
  17. It looks like you have a great start, what are you using for communication between the 2 processes? Just curious, is the CNC a laser or mechanical machine?
  18. When you use python embedded, you have to be aware of the OS system path. Assume that nothing is on the OS path and you will be ok. I choose not to modify the path as part of my app install, and python is in a subdirectory to my exe. This allows me to delete the python directory when I need to update. This forces me to load everything relying only on site to find the module. I install pip in the embedded distribution and let pip install the packages and dependencies.
  19. I feel the same way every time I try something different. You already know a lot of python, now you are on to finishing details to make your app just a little better.
  20. What is in python310._pth? I think the 2nd line is relative to your exe, so it is not trustable. python39.zip . .\Scripts .\Lib .\Lib\site-packages # Uncomment to run site.main() automatically import site Personally I would put cnc_vision_ext.cp310-win_amd64.pyd in \Lib\site-packages\'your folder'\ and then modify the import statement.
  21. SwiftExpat

    A question for thread reference

    What if the user wants to see the image without the lines drawn? Possibly this will help you see the problem / goal differently. Maybe you can do something like this, I have the image and then draw the boxes at display. Draw Boxes.mp4
  22. SwiftExpat

    A question for thread reference

    This might take a lot of code to accomplish, but this would be my goal before going multiprocess. Keep in mind thread construction has a cost and IPC will always have a high cost. The code works fine in my usage, the thread hosts the engine and stays in a loop. No reason to use TPythonThread, you are not creating a thread in Python. In your example you have the thread performing several tasks, split them. The blocking point is Python, so the goal is to keep a steady stream of work going to it. This is the limit you design around. The thread that is executing the python should only be watching a work queue, TThreadedQueueCS. Handle all the synchronization in Delphi. procedure TThreadProcess.Execute; var v: Variant; itm: TItem; begin inherited; do while not terminated begin itm := QSessionAnalyze.PopItem; v := MainModule.ProcessImage(ImageToPyBytes(BMP)); QSessionDraw.PushItem(itm) end; end; Could all of this other could happen in another thread or at the time it is rendered. procedure TThreadDraw.Execute; var v: Variant; begin inherited; DT.Init(true); DT.FillObjsData(v,0,0); DT.DrawObjects(BMP.Canvas,1280); DT.DrawSpeedInfo(BMP.Canvas,'NA',1280); FitDrawEx(Img,BMP); Img.Invalidate; end;
  23. SwiftExpat

    A question for thread reference

    It looks to me like your thread is doing processing and display, can you seperate it? Have you considered running PYEngine on a thread instead of main? Create a work queue on the thread and only have it execute the python steps necessary, then send the instructions to draw the result back to Delphi for display. My thread looks like this and I use DEB for messaging between main and the python thread. type TSERTCPythonEngine = class(TThread) private PE: TPythonEngine; PythonIO: TPythonInputOutput; PythonResultVar: TPythonDelphiVar; PyMod: TPythonModule; QSessionAnalyze: TThreadedQueueCS<IEventSessionAnalyze>; function FilePathPython(AFilePath: string): string; procedure PythonIOReceiveData(Sender: TObject; var Data: AnsiString); procedure PythonIOReceiveUniData(Sender: TObject; var Data: string); procedure PythonIOSendData(Sender: TObject; const Data: AnsiString); procedure PythonIOSendUniData(Sender: TObject; const Data: string); procedure StartEngine; procedure SetInitScript; function InstallVerify: boolean; procedure InstallPython(AUpdateLocation: string); procedure InstallRttkPackage(AUpdateLocation: string); procedure InstallDependDLLs; procedure InstallDLLCopy(ADllName: string); procedure ProcessSessionAnalyze; procedure PySessionAnalyze(ASessionAnalyze: IEventSessionAnalyze); procedure ProcessSshHostReload; procedure PyModExecHostConfigFound(Sender: TObject; PSelf, Args: PPyObject; var Result: PPyObject); procedure PyModExecHostConfigUpdated(Sender: TObject; PSelf, Args: PPyObject; var Result: PPyObject); protected procedure Execute; override; public class function PythonDll: string; class function PythonDir: string; class function PyPkgDir: string; class function PythonExists: boolean; constructor Create; destructor Destroy; override; [Subscribe(TThreadMode.Background)] procedure OnEventSessionAnalyze(AEvent: IEventSessionAnalyze); end; procedure TSERTCPythonEngine.Execute; begin inherited; NameThreadForDebugging('THPythonEngine'); try try CoInitialize(nil); if InstallVerify then if PythonExists then begin StartEngine; while not Terminated do begin ProcessSessionAnalyze; sleep(10); end; end else Logger.Critical('Python does not exist') else Logger.Critical('Python install verifiction failed!'); finally CoUninitialize(); end; except on E: Exception do Logger.Critical('Python Exectue failed with ' + E.Message); end; end; procedure TSERTCPythonEngine.ProcessSessionAnalyze; var lEsa: IEventSessionAnalyze; begin if (not QSessionAnalyze.ShutDown) and ((QSessionAnalyze.TotalItemsPushed - QSessionAnalyze.TotalItemsPopped) > 0) then begin lEsa := QSessionAnalyze.PopItem; if TFile.Exists(lEsa.SessionFileName) then PySessionAnalyze(lEsa); GlobalEventBus.Post(lEsa, 'Processed'); end; end;
  24. SwiftExpat

    Developer Express gave up on FMX

    Two items that might help you get a focused answer: Collection based, virtual or using a TDataset? What performance (insert, sort, scroll, filter) are you concerns? TMS has 2 for FMX, so make sure you evaluate the FNC one not the legacy FMX one. It is very clear on the page which one to look to.
  25. SwiftExpat

    Tag editor?

    Commerical, but this might fit your needs, TMS FNC UI Pack, they give a trial version. I do not remember how the delete works, but the demos should let you play with it.
×