stacker_liew
-
Content Count
106 -
Joined
-
Last visited
-
Days Won
1
Posts posted by stacker_liew
-
-
I use ChatGPT convert a JavaScript script to Delphi (Firemonkey) unit, it seems have error, can anyone check for it.
unit LakeEffect; interface uses System.Types, System.Classes, FMX.Controls, FMX.Graphics, FMX.Types, FMX.Objects; type TLakeEffect = class(TImage) private FSpeed: Single; FScale: Single; FWaves: Integer; FImage: Boolean; FCanvas: TCanvas; FFrames: TArray<TBitmap>; FFrame: Integer; FMaxFrames: Integer; FOffset: Single; FImgLoaded: Boolean; procedure CreateFrames; procedure LoadImage(Sender: TObject); procedure TimerTick(Sender: TObject); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; property Speed: Single read FSpeed write FSpeed; property Scale: Single read FScale write FScale; property Waves: Integer read FWaves write FWaves; property Image: Boolean read FImage write FImage; end; implementation uses System.Math; constructor TLakeEffect.Create(AOwner: TComponent); begin inherited Create(AOwner); FSpeed := 1; FScale := 1; FWaves := 10; FImage := True; FCanvas := TCanvas.Create; FFrames := nil; FFrame := 0; FMaxFrames := 0; FOffset := 0; FImgLoaded := False; end; destructor TLakeEffect.Destroy; begin FCanvas.Free; inherited Destroy; end; procedure TLakeEffect.CreateFrames; var Img: TBitmap; Ca: TBitmap; Id: TBitmapData; Odd: TBitmapData; W, H, DW, DH: Integer; Pixel, J, Displacement, M, N, Sign: Integer; X, Y: Integer; begin Img := TBitmap.Create; try Img.LoadFromFile('path_to_image.jpg'); // 請替換為你的圖像路徑 Ca := TBitmap.Create(Img.Width, Img.Height * 2); Ca.Canvas.BeginScene; Ca.Canvas.DrawBitmap(Img, TRectF.Create(0, 0, Img.Width, Img.Height), TRectF.Create(0, 0, Ca.Width, Ca.Height), 1); Ca.Canvas.Scale := PointF(1, -1); Ca.Canvas.DrawBitmap(Img, TRectF.Create(0, -Img.Height * 2, Img.Width, 0), TRectF.Create(0, -Ca.Height, Ca.Width, 0), 1); Ca.Canvas.EndScene; FCanvas.Assign(Ca.Canvas); W := Ca.Width; H := Ca.Height; DW := W; DH := H div 2; Img.Map(TMapAccess.Read, Id); try Odd.SetSize(W, H); Odd.Map(TMapAccess.Write, Id.PixelFormat); for Y := 0 to DH - 1 do begin for X := 0 to DW - 1 do begin Displacement := Trunc(FScale * 10 * (Sin(DH / (Y / FWaves)) + (-FOffset))); J := ((Displacement + Y) * W + X + Displacement) * 4; if J < 0 then begin Pixel := Pixel + 4; Continue; end; M := J mod (W * 4); N := Trunc(FScale * 10 * (Y / FWaves)); if (M < N) or (M > (W * 4) - N) then begin Sign := IfThen(Y < W / 2, 1, -1); Odd.SetPixel(X, Y, Odd.GetPixel(X, Displacement + Y) * Sign); Continue; end; if Id.GetAlpha(J) <> 0 then begin Odd.SetPixel(X, Y, Id.GetPixel(J)); end else begin Odd.SetPixel(X, Y, Odd.GetPixel(X, Y - W div 2)); end; end; end; FOffset := FOffset + FSpeed; FFrame := FFrame + 1; FFrames := FFrames + [Odd.Clone]; if FOffset > FSpeed * (6 / FSpeed) then begin FOffset := 0; FMaxFrames := FFrame - 1; FFrame := 0; Exit; end; if FOffset <= FSpeed * (6 / FSpeed) then begin CreateFrames; end; finally Img.Unmap(Id); Odd.Unmap; end; finally Ca.Free; Img.Free; end; end; procedure TLakeEffect.LoadImage(Sender: TObject); begin FImgLoaded := True; FCanvas.BeginScene; FCanvas.DrawBitmap(FFrames[FFrame], TRectF.Create(0, FCanvas.Height / 2, FCanvas.Width, FCanvas.Height), TRectF.Create(0, FCanvas.Height / 2, FCanvas.Width, FCanvas.Height), 1); FCanvas.EndScene; FFrame := FFrame + 1; if FFrame > FMaxFrames then begin FFrame := 0; end; end; procedure TLakeEffect.TimerTick(Sender: TObject); begin if FImgLoaded then begin FCanvas.BeginScene; if not FImage then begin FCanvas.DrawBitmap(FFrames[FFrame], TRectF.Create(0, 0, FCanvas.Width, FCanvas.Height div 2), TRectF.Create(0, 0, FCanvas.Width, FCanvas.Height div 2), 1); end else begin FCanvas.DrawBitmap(FFrames[FFrame], TRectF.Create(0, FCanvas.Height div 2, FCanvas.Width, FCanvas.Height), TRectF.Create(0, FCanvas.Height div 2, FCanvas.Width, FCanvas.Height), 1); end; FCanvas.EndScene; FFrame := FFrame + 1; if FFrame > FMaxFrames then begin FFrame := 0; end; end; end; end.
-
14 minutes ago, programmerdelphi2k said:@stacker_liew I dont have StandFrame to use, then I just remove it!
try change the color at "procedure TTetris.DefaultCanvas(Canvas: TCanvas);" --> Canvas.Fill.Color := TAlphaColorRec.Blue; // CurrentColor; "
function TTetris.GetCurrentSprite: TSprite; begin Result := AllSpriteKind[Random(6)]; CurrentColor := Random($FFFFFF); // black over black is = black end;
Thanks
-
I use ChatGPT to convert a Vcl Tetris to FMX Version, compile is ok, but no screen, any one can help?FMXTetris.7z
-
Use fingerprint {is deprecated, so untick will be ok}
-
Project->Options->User Permission->Use biometric, Use fingerprint {must tick}
-
I know what happen, I forget to tick two permissions in project option.
-
17 minutes ago, programmerdelphi2k said:@stacker_liew I just to say: it works for me in Android 11 / RAD 11.3 FMX 64bits project!
I'm using Android 12, it skip the Request Permission section.
RAD 11.3.1 FMX 64 bits.
-
-
2 hours ago, programmerdelphi2k said:you need this to "work": tested in Android 11 (API 30)... (using default targetSdkVersion = 32 by Delphi)
PermissionBiometric: TArray<string>; //... OnCreate Form: -------------- PermissionBiometric := ['android.permission.USE_BIOMETRIC']; // , 'android.permission.USE_FINGERPRINT']; // mandatory BiometricAuth1.PromptDescription := 'my description'; // mandatory BiometricAuth1.PromptTitle := 'my title'; // mandatory BiometricAuth1.BiometricStrengths := [ TBiometricStrength.DeviceCredential { , others... }]; // mandatory //... procedure TForm1.BiometricPermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray); begin // 2 permissions involved: USE_BIOMETRIC + USE_FINGERPRINT if (Length(AGrantResults) = 1 {2}) and (AGrantResults[0] = TPermissionStatus.Granted) then // and (AGrantResults[1] = TPermissionStatus.Granted) then BiometricAuth1.Authenticate; //... end; //... procedure TForm1.Button1Click(Sender: TObject); begin PermissionsService.RequestPermissions( { } PermissionBiometric, { } BiometricPermissionRequestResult, { } DisplayRationale); end; // ... procedure TForm1.BiometricAuth1AuthenticateFail(Sender: TObject; const FailReason: TBiometricFailReason; const ResultMessage: string); begin TDialogService.ShowMessage('Failed!'); end; procedure TForm1.BiometricAuth1AuthenticateSuccess(Sender: TObject); begin TDialogService.ShowMessage('Successed!'); end;
I followed your instruction, still won't work. Here is the source.
-
31 minutes ago, stacker_liew said:Wait...I create another one which without third party component.
This is the new one without third party components.
-
1 minute ago, Dave Nottage said:No error messages? Can you provide a reproducible example that does not have dependencies on TFrameStand or other 3rd party code?
Wait...I create another one which without third party component.
-
1 minute ago, Dave Nottage said:You'll need to me more specific about what "won't work" means. Please also note that only Android 10 or higher is supported
It should display the request permission dialog, but it won't. I'm using Android 12.
-
4 minutes ago, stacker_liew said:OK, thanks.
I checked the Biometric Authorization Service, still won't work.
-
1 minute ago, Dave Nottage said:You do not have the Biometric Authorization Service option checked in the Entitlement List in Project Options
OK, thanks.
-
-
Any samples?
-
6 hours ago, Rollo62 said:Interesting, what exactly you mean by “reapply” ?
Did you just reload the style file into the StyleBook ?
Maybe the StyleBook contained an older *.style file version, from an older IDE version, that could explain the differences.
I never checked for changes in style files from IDE version to version, but perhaps I should do that.
No, just change the main form's StyleBook's properties to nil, and reassign it again. And it works, I don't know why.
- 1
-
I managed to resolve this by reapply TStyleBook, and the memory leak just disappear, it's weird.
- 1
-
-
It looks like normal for loop is faster than TParallel.For here.
-
5 hours ago, Dalija Prasnikar said:Those two methods you have don't do the same thing. If you take a look to the result of the calculation, you will see that results are different.
First method will increment sum 1000000 times and second will increment temporary value 1000000 times and then add that temporary result to the total sum 1000 times. So the second method runs more operations and that is why it runs slower.
If you correct the code to calculate exactly the same sum in the second method, you will see that this one will run faster.
for ThreadedI := 0 to Pred(1000) do begin Inc(ISum); end;
Number of tasks running in both cases will be the same, but the second method has the advantage because the temporary calculation is not using interlocked operation which is costly, and only uses it to add that temporary sum to the final result. Overall, Parallel.For code will run interlocked operation 1000000 times, and task based method only 1000 times.
I see, thanks, now the TTask version elapsed time change to 3ms.
-
I have two program, one is using TParallel, the other is using TTask, both do the same thing, but TParallel version is far more fast than TTask version, does it true?
Here is TParallel Version, Elapsed Time 10ms:
procedure TSingleThreadTestForm.SingleThreadTestClickToStartThreadButtonClick(Sender: TObject); var SumValue: Int64; TempStopWatch: TStopWatch; begin SumValue := 0; TempStopWatch := TStopWatch.Create; TempStopWatch.Start; (Sender as TButton).Enabled := False; try TParallel.For(1000, 0, Pred(1000000), procedure(I: Int64) begin TInterlocked.Increment(SumValue); end); TempStopWatch.Stop; finally (Sender as TButton).Enabled := True; SingleThreadTestResultLabel.Caption := 'Process Result: ' + SumValue.ToString; SingleThreadTestElapsedTimeLabel.Caption := 'Elapsed Time: ' + TempStopWatch.ElapsedMilliseconds.ToString + ' ms'; end; end;
Here is TTask Version, Elasped Time 50ms:
procedure TMultiThreadTestForm.MultiThreadTestClickToStartThreadButtonClick(Sender: TObject); var I, SumValue: Int64; Tasks: TArray<ITask>; TempStopWatch: TStopWatch; begin SumValue := 0; TempStopWatch := TStopWatch.Create; TempStopWatch.Start; SetLength(Tasks, 1000); (Sender as TButton).Enabled := False; try for I := 0 to Pred(Length(Tasks)) do begin Tasks[I] := TTask.Create( procedure() var ThreadedI: Integer; ISum: Integer; begin ISum := 0; for ThreadedI := 0 to Pred(1000000) do begin Inc(ISum); end; TInterlocked.Add(SumValue, ISum); end); end; for I := 0 to Pred(Length(Tasks)) do Tasks[I].Start; // Start Created Thread TTask.WaitForAll(Tasks); TempStopWatch.Stop; finally (Sender as TButton).Enabled := True; MultiThreadTestResultLabel.Caption := 'Process Result: ' + SumValue.ToString; MultiThreadTestElapsedTimeLabel.Caption := 'Elapsed Time: ' + TempStopWatch.ElapsedMilliseconds.ToString + ' ms'; end; end;
-
What is the meaning of 2 in here?
TParallel.For(2,1,Max,procedure(I:Int64) begin if IsPrime(I) then TInterlocked.Increment(Tot); end);
-
On 1/18/2023 at 6:37 PM, stacker_liew said:But it's ok in the first frame but not in the second frame.
Finally I managed to solve this problem, by using different FrameStand for different Frame.
- 1
Delphi TOIOBE index lifted in May 2022?
in RTL and Delphi Object Pascal
Posted
Although ASM is very important in programming language, but no productivity at all, especially in risc environment.