Jump to content

DavidJr.

Members
  • Content Count

    39
  • Joined

  • Last visited

Everything posted by DavidJr.

  1. Hi, I am supporting a large "legacy" application and it uses a lot of global variables especially Array of records that are used by different methods. Recently I moved all the methods into a TThread class and implemented properties with "getters" and "setters" to make certain information available to the Main Form thread. However, there is still the problem of global variables that I need to address in a clean way. These global variables are NOT accessed outside the Thread class right now using the global variables as class members but they are still technically global. . How can I get access to these global variables without them being global. The application just works as it, but I would like to start refactoring the application. Is there basic hierarchy using classes and sub classes I should consider? Thanks.
  2. DavidJr.

    SAX parser

    Yes. I purchased a license. great stuff! Thanks!
  3. DavidJr.

    XML Parsing and Processing

    I am glad I found this thread the other day. I was able ot get a large 3MF file to load much faster using OXml instead using the DOM method. so I concure for OXml suggestion.
  4. DavidJr.

    SAX parser

    Hi, Have you tried this (saxforpascal) with Delphi 11.3? Or is there anything newer that may work. I am opening 3MF files and the XML files that are big take too long so I was wanting to convert to using SAX implementation of XML parsing. Thanks, David
  5. Hi, I am following this example for setting up a VideoCaptureDevice app: https://docwiki.embarcadero.com/RADStudio/Sydney/en/Video_Capturing I could not get the VideoCaptureDevice to start. I tried 4 known good cameras and get the same thing, I modified the code a bit to give me an indicator that I am indeed setting up the app right, still nothing. The app compiles just fine, just won't start capture. My version of Delphi is 10.2.3 and the following is my current code: unit FMXCamera_Main; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.Media, FMX.Edit; type TForm1 = class(TForm) Layout1: TLayout; btnStart: TButton; ComboBox1: TComboBox; Image1: TImage; procedure FormCreate(Sender: TObject); procedure ComboBox1Change(Sender: TObject); procedure btnStartClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } VideoCamera: TVideoCaptureDevice; procedure SampleBufferSync; procedure SampleBufferReady(Sender: TObject; const ATime: TMediaTime); end; var Form1: TForm1; implementation // Delphi version of the implementation {$R *.fmx} procedure TForm1.btnStartClick(Sender: TObject); begin if(VideoCamera <> nil) then begin if(VideoCamera.State = TCaptureDeviceState.Stopped) then begin VideoCamera.OnSampleBufferReady := SampleBufferReady; VideoCamera.CaptureSettingPriority := TVideoCaptureSettingPriority.FrameRate; VideoCamera.StartCapture; if(VideoCamera.State = TCaptureDeviceState.Capturing) then begin btnStart.Text := 'Stop'; end else begin VideoCamera.StopCapture; btnStart.Text := 'Start'; end; end else begin VideoCamera.StopCapture; btnStart.Text := 'Start'; end; end else begin Caption := 'Video capture devices not available.'; end; end; procedure TForm1.ComboBox1Change(Sender: TObject); begin VideoCamera := TVideoCaptureDevice(TCaptureDeviceManager.Current.GetDevicesByName(ComboBox1.Selected.Text)); if (VideoCamera <> nil) then begin btnstart.Text := 'Start '+VideoCamera.Name; btnStart.Enabled := true; end; end; procedure TForm1.FormCreate(Sender: TObject); var DeviceList: TCaptureDeviceList; i: integer; begin DeviceList := TCaptureDeviceManager.Current.GetDevicesByMediaType(TMediaType.Video); for i := 0 to DeviceList.Count - 1 do begin ComboBox1.Items.Add(DeviceList[i].Name); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin if(VideoCamera <> nil) then begin VideoCamera.StopCapture; end; end; procedure TForm1.SampleBufferReady(Sender: TObject; const ATime: TMediaTime); begin TThread.Synchronize(TThread.CurrentThread, SampleBufferSync); //Resize the image so that the video is buffered in its original size Image1.Width := Image1.Bitmap.Width; Image1.Height := Image1.Bitmap.Height; end; procedure TForm1.SampleBufferSync; begin VideoCamera.SampleBufferToBitmap(Image1.Bitmap, true); end; end.
  6. DavidJr.

    TVideoCaptureDevice will not run in (Delphi 10.2.3)

    I have abandoned the FMX option. Thanks.
  7. DavidJr.

    TVideoCaptureDevice will not run in (Delphi 10.2.3)

    I have done everything. The camera permissions is open. In VCL I am using other libraries that work just fine. Its the FMX app that doesn't work.
  8. DavidJr.

    TVideoCaptureDevice will not run in (Delphi 10.2.3)

    The example did not work, The Camera is in a state of "Stopped" after calling "StartCapture"
  9. DavidJr.

    TVideoCaptureDevice will not run in (Delphi 10.2.3)

    I have absolutely done all of that. I am not even getting any errors in the IDE.
  10. Hi, On a fairly large sized application with a few threads doing most of the work the UI does have 2 timers for updating fields based on calls to Thread class properties, I get a almost consistent pauses in the UI (ie... progress bar updates, TRichEdit line adds and TLabel caption updates) unless my mouse pointer is moved over the window. This is on a PC with two monitors. Is there something I can call to keep the UI from pausing? I tried finding other posts that ask this before posting here. Thanks. David
  11. thats exactly what I did. thanks.
  12. DavidJr.

    TVideoCaptureDevice will not run in (Delphi 10.2.3)

    Sorry just my luck I'd leave out some information. This is a Windows 10 OS, NOT Android.
  13. thanks. I resolved that issue, I should have replied sooner. I have long running procedure holding up the UI those same procedures replied on UI values as well.
  14. that's an interesting idea. I want to add that it seems to be message related. So if I move the mouse outside the window and the procedure finishes the TTask.Wait() then it pauses after a long run... then I can move the mouse around (without clicking on another window) and it resumes and finishes like its supposed to. But adding in booleans to allow a triggered set of actions in the Timer handler to maybe create messages is worth a try. When I did strictly linux/unix programming I never had these issues, Windows is definitely a complex system.
  15. Also I do call CheckSynchronize from the main UI, there is no problem getting information from threads to main UI.
  16. yes, it would be a problem, but I am not doing that. I call a property and a "getter" method will return a value, and that all works fine. The issue is in the methods that reside in the UI thread that do work. Not everything is in a separate thread, but all the heavy work is in separate threads, but the act of pulling in tmp files is all in the main UI thread and the reason is its a legacy app that I have not the abilty to do a complete re-write. Now the procedure that is called by a timer event is a big one and so I must disable the timer until the procedure completes, the procedure does call other methods. I wished I could share the source but its big and a lot of unrelated code that works exactly as intended its only the stuff that's called in the UI. I know its preferred to post source code, but this code isn't something I own and its against the company policy.
  17. The actions in the timer do work, but methods running in UI thread are not finishing (writing to fields or increasing progressbar) unless my mouse is in the window.
  18. DavidJr.

    TSimpleEvent how to

    Hi, I am trying to understand TSimpleEvent (or TEvent) and complete documentation with examples doesn't seem to be so easy to find. I suspect that it can be used as a trigger more effectively than a boolean, but I am not so sure without a better understanding. I would like to create a one time trigger that is set as an event so a procedure can execute. The procedure unset it and set another Event to allow for a waitfor() like procedure to wait for the procedure to finish work. IS my understanding of a TSImpleEvent in that it can serve as a trigger correct? Also how is it turned on and off? I got the idea from Bechhoff's TwinCAT3 environment where there is a Trigger object that once its read its automatically turned off so to NOT allow a method called by the trigger to be called more than once. Thanks.
  19. DavidJr.

    TSimpleEvent how to

    This is helpful. Other than this page: https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SyncObjs.THandleObject.WaitFor , I did not see these pages until you provided links: https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SyncObjs.TEvent.SetEvent https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SyncObjs.TEvent.ResetEvent Thank you for the info.
  20. DavidJr.

    TSimpleEvent how to

    Yes. I saw those. But I do not know from those pages the proper way to use SetEvent or ResetEvent or any properites or other methods. No example code like you would expect from TTask and the like. More specifically What is SetEvent doing vs ResetEvent? Which thread has rights to these methods?
  21. I have a question regarding TThread class instances vs using TTasks. Is there a way to get 2 long running Tthread classes to run on separate CPU cores instead of using TTasks instances? I would like to have to threads run the entire time the app is open be ready to run some procedures. They do this just fine, however, I just read up on TTasks and Delphi Parallel Programming Library, and I understand that the benefit is an automatic optimization of tasks by balancing the CPU load of each core.. but all I want to do is ensure that each thread run on a different core from each other. Thanks.
  22. Ok, thats good to know. Maybe this is a really dumb question, but why isn't the TThread class instances handled the way TTask instances are from the beginning? I am assuming that Any TThread instance I create and execute will run on the same core as my mainform thread, is this true?
  23. Hi, I have an application that takes CAD model data and slices it until layers then posts these layers as binary data using Indy and IdMultipartForm (AddFile()). I am usually not allowed to ask for help outside the company because of the proprietary information, but I will do my best at giving as much information as I can. Most of the time this just works but occasionally I get the following: System.SysGetMem(Opt.out) System._GetMem(???) System._NewUnicodeString(1) System._UStrFromPWCharLen('','sA',1) System._UStrFromWChar(???,'s') IdGlobalProtocols.FindFirstNotOf(#9' ','slice',5,1) IdCoderHeader.DecodeHeader('slice') IdCoderHeader.EncodeHeader('slice','','B','UTF-8') IdMultipartFormData.TIdFormDataField.FormatHeader IdMultipartFormData.TIdFormDataField.GetFieldSize IdMultipartFormData.TIdMultiPartFormDataStream.CalculateSize IdMultipartFormData.TIdMultiPartFormDataStream.IdSeek(???,???) IdGlobal.TIdBaseStream.Seek(???,???) System.Classes.TStream.GetSize The application receives the data from a queue, processes it with 100% success, and then the file is written locally to a a disk, then I do the following: // EDITED: took out "BAD SECTIONS" in attempt to get a better response. function TMain.SaveTheSolvedSlice(FileName: String): Boolean; var MimeType, Response: String; jsonVal: TJSonValue; Stat, Size: String; SendParams: TIdMultiPartFormDataStream; TOPLSliceFile: TStream; //HTTPSendFile: TIdHTTP; begin Result := False; Response := 'NULL'; HTTPSendFile.Request.Clear; HTTPSendFile.ReadTimeout := 2000; HTTPSendFile.ConnectTimeout := 9000; SendParams := TIdMultiPartFormDataStream.Create; Application.ProcessMessages; try if(FileExists('tmp\out\'+FileName)) then begin MimeType := 'application/octet-stream'; While(GetFileSizeInBytes('tmp\out\'+FileName) < MinSliceSizeFromUnsolvedFile+1) Do Delay(10); //Params.AddFormField('_token', 'Myfb9OqYgDBwDws3zTL9QOs492XWfNtGLftUdNsH'); SendParams.AddFile('slice', 'tmp\out\'+FileName, MimeType).ContentTransfer:='binary'; Sleep(10); SendParams.Position := 0; try While(GetFileSizeInBytes('tmp\out\'+FileName) > SendParams.Size) Do Delay(10); finally end; StatusUpdate(Console, 'Attempting to post file '+'tmp\out\'+FileName+' (size: '+SendParams.Size.ToString+' bytes)'); Delay(10); Response := HTTPSendFile.Post(STORAGE_OUT_REPO, SendParams); Delay(5); if(Response <> 'NULL') then begin //{"Slice":{"Status":"ACCEPTED","FileName":"1_Some_Job_Filename.slc","Size":1812}} jsonVal := TJSonObject.ParseJSONValue(Response); Stat := jsonVal.GetValue<String>('Slice.Status'); Size := jsonVal.GetValue<String>('Slice.Size'); jsonVal.Free; StatusUpdate(Console, 'Toasted Slice (size: '+Size+') '+Stat.ToLower); if(Stat = 'ACCEPTED') then Result := True else if(Stat = 'ERROR') then Result := False else Result := False; end; end finally SendParams.Free; Response := 'NULL'; HTTPSendFile.Response.Clear; end; end; I do the comparison of size of original file to that of the Params, which I expect to be slightly larger, to ensure the file has finished writing to disk, then loaded as a File in TIdMultiPartFormDataStream before attempting to post back to API. I suspect that I am trying to get the the size of the Params object too soon, is that likely? Also I use the Indy IdHTTP as object that I dragged into the form, which works better than declaring a new instance and freeing it every time I process a new file. Also note: the method GetFileSizeInBytes() is a method I created a few years back based on example code and always works.
  24. So I verified that there are memory leaks which are listed in the screenshot attached. There are no others that come up with other than these and consistently reproducible when I use IdHTTP Post with use a TIdMultiPartFormDataStream instance local to the procedure. I tried both (not at the same time): SendParams.AddFile('slice', FullFilePath, MimeType).ContentTransfer:='binary'; SendParams.AddFormField('slice', MimeType, '', SolvedSliceStream, FileName).ContentTransfer := 'binary'; So I am going to use MadExcept with this project, but as I posted before is there an issue with the version (of Indy) that came with Delphi/RADStudio 10.2.3 (Tokyo) Enterprise? Or could the issue be with TStream type objects?
×