-
Content Count
281 -
Joined
-
Last visited
-
Days Won
31
Posts posted by vfbb
-
-
The binary tree is essential in programming, especially when you want to insert, remove, search and maintain an ordered list at the same time, with an excellent performance. I use it, but on a day-to-day basis we don’t use it that much because generally what we need is just a simple sorting, example List.Sort, or a list with a fast search, example TDictionary, or inserting, removing and sorting small lists (for example example lists with less than 200 items).
The ordering of delphi uses QuickSort which has the same complexity / performance as adding + ordering a binary tree O (N * (Log N)). Just like the dictionary has similar performance in the search.
But as I said, when you want to add, remove, search quickly and sort the same list, you better use a binary tree.
Delphi does have support for this in TList<T>, you don't need to create a class or make implementations as alcinoe did, you just need to use for example TList<Integer>, and use List.BinarySearch to add, remove or search. Note: To add you will use BinarySearch because although it returns False, which is what it should return when it cannot be found, it also returns the Index, which is where this item should be, so you will insert the item in the position of that index that BinarySearch returned. That way you will already insert sorted, the list will always be sorted, that is, any operation like this will be very fast, because it uses BinarySearch which has the complexity O (Log N), so your list will be a Binary Tree. 😉
-
1
-
-
2 hours ago, Fintan said:10.4 does not appear to be recognising the Browsing Path.
For instance, in 10.4 I have to add units within $(BDS)\SOURCE\RTL\SYS to the uses clause, whereas in previous versions (coming from 10.2) that was not required.
Is this a known issue?
The browsing path works fine. It just not work when the Code Insight is completing in background, then the Ctrl + Click may not work. But while this, you can simple click in the unit name in uses, and press Ctrl + Enter.
-
I never tested it, but if you open the System.StartUpCopy.pas you will see that in Windows, always when your program run, it will try to copy files from ExtractFilePath(ParamStr(0)) + '\StartUp\' to TPath.GetHomePath (in windows it is AppData\Roaming\).
So, you can try to put in Deployment remote path: .\StartUp\yourapp\database.sqlite3
And to load the database in runtime you can try to use TPath.GetHomePath + '\yourapp\database.sqlite3'
-
1
-
-
One more issue: memory leak using inline variables (just arc types, like strings, arrays and interfaces) + anonymous method. Ex:
procedure TForm1.FormCreate(Sender: TObject); begin var S: string := 'Test leak'; TThread.Queue(nil, procedure() begin Showmessage(S); end); end;
The report:
-
It may not be your problem but I have to inform there is a very common bug with the iOS in 10.3 (not sure in 10.4), that the break points marked is pointing to an wrong line (usually 4~5 lines before or after) from the break point marked by you. It is very common for me to mark within the scope of a method but internally delphi marked on another line that is outside the scope of the method, and when you compile your breakpoint is marked as invalid. In this case I put several breakpoints in sequence, close to the method I want.
-
@MikeMon I forgot that in Delphi Rio there was a bug in the android permissions and I noticed that it is still in Delphi Sydney. You have to fix the FMX.Platform.Android.pas
procedure TFMXNativeActivityListener.onRequestPermissionsResult(ARequestCode: Integer; APermissions: TJavaObjectArray<JString>; AGrantResults: TJavaArray<Integer>); // ----------------------------------------------------------------------------- // [iPub - github.com/viniciusfbb] - 28/05/2020 - Delphi 10.4 // The delphi messages system isn't thread-safe and this request result can be // called in background threads {$IFDEF DELPHI_FIXES} // ------------------------------------------------------- begin TThread.Queue(nil, procedure() var MsgData: TPermissionsRequestResultData; Msg: TPermissionsRequestResultMessage; begin MsgData.RequestCode := ARequestCode; MsgData.Permissions := APermissions; MsgData.GrantResults := AGrantResults; Msg := TPermissionsRequestResultMessage.Create(MsgData); TMessageManager.DefaultManager.SendMessage(nil, Msg); end); {$ELSE} // --------------------------------------------------------------------- var MsgData: TPermissionsRequestResultData; Msg: TPermissionsRequestResultMessage; begin MsgData.RequestCode := ARequestCode; MsgData.Permissions := APermissions; MsgData.GrantResults := AGrantResults; Msg := TPermissionsRequestResultMessage.Create(MsgData); TMessageManager.DefaultManager.SendMessage(nil, Msg); {$ENDIF} // -------------------------------------------------------------------- end;
-
1
-
-
The Apple will remove the apps without storyboard or will not allow new updates without storyboard?
-
@MikeMon Today I don't have an android device to check it, but first I would check 2 things in andoird:
1) the Porject Options > Uses Permission > Camera = true.
2) Test if the "TFormMain.AccessCameraPermissionRequestResult" is executing in the main thread with LIsMainThread := TThread.Current.ThreadID = MainThreadID;
About Delphi 10.3.3 I do not use anymore and the code of iOS that I posted will work only in 10.4 because the iOSapi.AVFoundation.pas of the 10.3.3 not have the apis of media permission.
-
The most common component of the city Recife-Brazil in the internet.
@Mike Lustosa Would be better if you create a second readme in english
-
Mike, the "PermissionsService .RequestPermissions" works only in Android, in others platforms it have not been implemented, will simple skip.
The code I gave you will work perfectly, but I think you are having trouble adapting it. So I simplified things for you:
{$IFDEF iOS} type TipPermissionStatusProc = reference to procedure(AStatus: TPermissionStatus); { TipiOSUtils } TipiOSUtils = class private type { IipRequestCameraPermissionDelegate } IipRequestCameraPermissionDelegate = interface(IipInterface) procedure RequestAccessResult(AAuthorized: Boolean); end; { TipRequestCameraPermissionDelegate } TipRequestCameraPermissionDelegate = class(TipInterfacedObject, IipRequestCameraPermissionDelegate) private FStatusProc: TipPermissionStatusProc; public constructor Create(AStatusProc: TipPermissionStatusProc); procedure RequestAccessResult(AAuthorized: Boolean); end; end; uses System.Classes, FMX.Dialogs, iOSapi.AVFoundation; { TipiOSUtils.TipRequestCameraPermissionDelegate } constructor TipiOSUtils.TipRequestCameraPermissionDelegate.Create( AStatusProc: TipPermissionStatusProc); begin inherited Create; FStatusProc := AStatusProc; end; procedure TipiOSUtils.TipRequestCameraPermissionDelegate.requestAccessResult( AAuthorized: Boolean); begin if AAuthorized then FStatusProc(TPermissionStatus.Granted) else FStatusProc(TPermissionStatus.Denied); end; { TipiOSUtils } class procedure TipiOSUtils.RequestAccessResult(AAuthorized: Boolean); begin TThread.Queue(nil, procedure() var LRequestCameraPermissionDelegate: IipRequestCameraPermissionDelegate; begin LRequestCameraPermissionDelegate := FRequestCameraPermissionDelegate; FRequestCameraPermissionDelegate := nil; if Assigned(LRequestCameraPermissionDelegate) then LRequestCameraPermissionDelegate.RequestAccessResult(AAuthorized); end); end; procedure TipiOSUtils.RequestCameraPermission(AStatusProc: TipPermissionStatusProc); begin case TAVCaptureDevice.OCClass.authorizationStatusForMediaType(AVMediaTypeVideo) of AVAuthorizationStatusNotDetermined: begin FRequestCameraPermissionDelegate := TipRequestCameraPermissionDelegate.Create(AStatusProc); TAVCaptureDevice.OCClass.requestAccessForMediaType(AVMediaTypeVideo, RequestAccessResult); end; AVAuthorizationStatusDenied: AStatusProc(TPermissionStatus.Denied); AVAuthorizationStatusAuthorized: AStatusProc(TPermissionStatus.Granted); AVAuthorizationStatusRestricted: AStatusProc(TPermissionStatus.PermanentlyDenied); else AStatusProc(TPermissionStatus.Denied); end; end; {$ENDIF}
And to use, replace your TFormMain.FormActivate by this:
{$IFDEF iOS} var LiOSUtils: TipiOSUtils.Create; {$ENDIF} procedure TFormMain.FormActivate(Sender: TObject); begin {$IFDEF ANDROID} FPermissionCamera := JStringToString(TJManifest_permission.JavaClass.CAMERA); PermissionsService.RequestPermissions([FPermissionCamera], AccessCameraPermissionRequestResult, DisplayRationale); {$ELSEIF defined(iOS)} LiOSUtils: TipiOSUtils.Create; LiOSUtils.RequestCameraPermission( procedure(AStatus: TPermissionStatus) begin if AStatus = TPermissionStatus.Granted then CreateCamera() else Showmessage('You need to enable the Camera permission in system Settings. Please go to the Settings > MyApp > enable Camera.'); end); {$ENDIF} end;
Note: To test the permission you need to unistall your app before compile.
-
What I doing? If the status is not determined (first time) I request the access (you can request just if the status is not determined). If is denied I simple show a message informing to go to the Settings and enable the permission manually (all aps do this, example: Telegram).
-
Mike, but the ZXing don't ask the permission. You need to do this by your self. I don't know why it is working for you in 10.3, probably the TCamera did it internally.
I can't send you my entire code, but you will understand how it works by seeing part of the code:
TipiOSUtils = class(TipFMXUtils, IipiOSUtils) private type { IipRequestCameraPermissionDelegate } IipRequestCameraPermissionDelegate = interface(IipInterface) procedure RequestAccessResult(AAuthorized: Boolean); end; { TipRequestCameraPermissionDelegate } TipRequestCameraPermissionDelegate = class(TipInterfacedObject, IipRequestCameraPermissionDelegate) private FStatusProc: TipPermissionStatusProc; public constructor Create(AStatusProc: TipPermissionStatusProc); procedure RequestAccessResult(AAuthorized: Boolean); end; {$IFDEF DELPHI_FIXES} private class var FCurrentAlert: UIAlertController; FRequestCameraPermissionDelegate: IipRequestCameraPermissionDelegate; class procedure AlertCancel(AAction: UIAlertAction); class procedure AlertSettings(AAction: UIAlertAction); class procedure RequestAccessResult(AAuthorized: Boolean); {$ENDIF} // .... {$IFDEF DELPHI_FIXES} class procedure TipiOSUtils.AlertCancel(AAction: UIAlertAction); var LRequestCameraPermissionDelegate: IipRequestCameraPermissionDelegate; begin LRequestCameraPermissionDelegate := FRequestCameraPermissionDelegate; FRequestCameraPermissionDelegate := nil; if Assigned(LRequestCameraPermissionDelegate) then LRequestCameraPermissionDelegate.RequestAccessResult(False); end; class procedure TipiOSUtils.AlertSettings(AAction: UIAlertAction); var LRequestCameraPermissionDelegate: IipRequestCameraPermissionDelegate; begin GiOSUtils.OpenAppSettings; LRequestCameraPermissionDelegate := FRequestCameraPermissionDelegate; FRequestCameraPermissionDelegate := nil; if Assigned(LRequestCameraPermissionDelegate) then LRequestCameraPermissionDelegate.RequestAccessResult(False); end; {$ENDIF} {$IFDEF DELPHI_FIXES} class procedure TipiOSUtils.RequestAccessResult(AAuthorized: Boolean); begin TipTask.Queue( procedure() var LRequestCameraPermissionDelegate: IipRequestCameraPermissionDelegate; begin LRequestCameraPermissionDelegate := FRequestCameraPermissionDelegate; FRequestCameraPermissionDelegate := nil; if Assigned(LRequestCameraPermissionDelegate) then LRequestCameraPermissionDelegate.RequestAccessResult(AAuthorized); end); end; {$ENDIF} procedure TipiOSUtils.RequestCameraPermission(const ADescription: string; AStatusProc: TipPermissionStatusProc); {$IFDEF DELPHI_FIXES} var LCancelAction: UIAlertAction; LWindow: UIWindow; {$ENDIF} begin if not Assigned(AStatusProc) then Exit; {$IFDEF DELPHI_FIXES} case TAVCaptureDevice.OCClass.authorizationStatusForMediaType(AVMediaTypeVideo) of AVAuthorizationStatusNotDetermined: begin FRequestCameraPermissionDelegate := TipRequestCameraPermissionDelegate.Create(AStatusProc); TAVCaptureDevice.OCClass.requestAccessForMediaType(AVMediaTypeVideo, RequestAccessResult); end; AVAuthorizationStatusDenied: begin LWindow := TiOSHelper.SharedApplication.keyWindow; if (LWindow = nil) or (LWindow.rootViewController = nil) then begin AStatusProc(TPermissionStatus.Denied); Exit; end; FRequestCameraPermissionDelegate := TipRequestCameraPermissionDelegate.Create(AStatusProc); FCurrentAlert := TUIAlertController.Wrap(TUIAlertController.OCClass.alertControllerWithTitle( StrToNSStr(FMXLanguage.GetPermissionTitle), StrToNSStr(ADescription + #13#10 + FMXLanguage.GetiOSPermissionMessageText), UIAlertControllerStyleAlert )); FCurrentAlert.addAction(TUIAlertAction.Wrap(TUIAlertAction.OCClass.actionWithTitle(StrToNSStr(FMXLanguage.GetPermissionSettingsButtonText), UIAlertActionStyleDefault, AlertSettings))); LCancelAction := TUIAlertAction.Wrap(TUIAlertAction.OCClass.actionWithTitle(StrToNSStr(FMXLanguage.GetPermissionCancelButtonText), UIAlertActionStyleCancel, AlertCancel)); FCurrentAlert.addAction(LCancelAction); FCurrentAlert.setPreferredAction(LCancelAction); LWindow.rootViewController.presentViewController(FCurrentAlert, True, nil); end; AVAuthorizationStatusAuthorized: AStatusProc(TPermissionStatus.Granted); AVAuthorizationStatusRestricted: AStatusProc(TPermissionStatus.PermanentlyDenied); else AStatusProc(TPermissionStatus.Denied); end; {$ELSE} AStatusProc(TPermissionStatus.Denied); {$ENDIF} end;
-
7 minutes ago, MikeMon said:Hi. Thank you for your answer. The code working on Delphi 10.3.3 is crashing on Delphi 10.4. Btw, if the user hasn't given permission to access the camera yet, he/she will be asked to give one. That works quite fine on Delphi 10.3.3.
Ok, but the permission will be show just at first time. If your user negate the permission once, he will need to give the permission manually at the Settings of the iOS. In iOS go to the Settings > Your App > enable Camera, and try again
-
Mike, if your notebook/desktop have a webcam test in windows. Your problem on mobile can be related to the permission to have access to the camera and not in relation to the ZXing code. Here I use it only in windows, and with Delphi 10.4 is working fine.
-
1 hour ago, vfbb said:The TWebBrowser.Create is crashing in the iOS. To test just add a TWebBrowser to the form and compile.
The exception is raising in the FMX.WebBrowser.Delegate.iOS.pas in TNativeWebViewHelper.CreateAndInitWebView. Did anyone get a workaround?
I found the workaround! Add the WebKit framework to your iOS SDK and update the local file cache. After, in the unit source\rtl\ios\iOSapi.WebKit.pas in the line:
var WebKitModule: THandle; {$ENDIF}
Change to
var WebKitModule: THandle; {$ELSE} {$IF NOT DECLARED(_PU)} const {$IFDEF UNDERSCOREIMPORTNAME} _PU = '_'; {$ELSE} _PU = ''; {$ENDIF} {$EXTERNALSYM _PU} {$ENDIF} procedure EmbedFramework; cdecl; external libWebKit name _PU + 'OBJC_CLASS$_WKWebView'; {$ENDIF}
-
1
-
-
The TWebBrowser.Create is crashing in the iOS. To test just add a TWebBrowser to the form and compile.
The exception is raising in the FMX.WebBrowser.Delegate.iOS.pas in TNativeWebViewHelper.CreateAndInitWebView. Did anyone get a workaround?
-
4 minutes ago, MikeMon said:Hi @vfbb. Option 4 yes. Option 3 isn't working. The default Delphi launch screen images are added no matter what.
No, it is correct. The name in that file is not the name your image in your computer, but the name of the image in the remote device.
As I told you, just delete your app, restart your phone, open a blank project, change it by options and compile and you will see that is working.
-
14 minutes ago, MikeMon said:3.) I edited the LaunchScreen.storyboard and Assets files in LaunchScreen.TemplateiOS (actually only the Contents.json file in the Assets\LaunchScreenImage.imageset folder) as needed by replacing the default FM launch icons with mine.
4.) Made sure that my launch screen images to be deployed are in the "Project | Deployment".
The options of the delphi 10.4 is working perfectly for this, you don't have to add it manually to the deploy project and you don't need to change the storyboard files either. You can test with a new project.
-
I found the problem and this is not a delphi bug. The problem is with the iOS cache, the app don't update new launchscreen / icon, even you uninstall and install your app. The solution is:
1) Uninstall the app
2) Power down the device
3) Power up the device
4) Install the app
-
1
-
-
Is anyone managing to use the storyboard launch screen? Here it is only working with the original delphi color and image. When I try to change the background color or the image in the project options, it has no effect.
-
Just a information: The ZXing is a crossplatform solution, and is simple to implement, but is not the best choose. In Android I prefer the GoogleVision and in iOS I prefer use the apis of the AVFoundation, you will even avoid using TCamera, because it is very slow, very.
-
2
-
-
https://github.com/Spelt/ZXing.Delphi
It is compatible with 10.4 (although the readmeinforms support for delphi 10.3.3)
I have to inform you that there are some leaks in the spelt code, nothing that you cannot solve.
-
1
-
-
I don't know if this is happening only to me, but it is already the second computer that I install Delphi 10.4 and the same problem occurs. I retry with the patch1 and again the problem occur:
Compilations of a simple blank package do not work for Linux64 and OSX64.
Workaround: You will need to add the following directories to Library Path:
Linux64
C:\Program Files (x86)\Embarcadero\Studio\21.0\binlinux64
OSX64
C:\Program Files (x86)\Embarcadero\Studio\21.0\binosx64
-
6 minutes ago, Stefan Glienke said:I don't understand the original problem - please describe exactly the data in a complete but small enough sample and the way you want it to be organized/shown.
Yes, we need to know the original problem.
@PolywickStudio
Another consideration, I believe that your performance problem does not involve this search, because a loop of 60,000 items comparing integers is 0 milliseconds.
Does anyone use Binary Search Tree?
in Algorithms, Data Structures and Class Design
Posted
The best strategy should be analyzed for each case, but I can tell you that 99% of the time the implementation of binary tree using a simple ordered list will be much faster than creating objects for nodes, because you need to balance the tree all over moment, while the simulation of the binary tree in a simple ordered list you don't have to balance anything (although the List.Insert or List.Delete can call a very large Move, the CPUs are already optimized for that and it will be much faster that go through node by node balancing the tree to maintain the ideal number of levels of a binary tree which is Log N in base 2, besides the costs of creating the objects of the nodes).