Jump to content

stacker_liew

Members
  • Content Count

    106
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by stacker_liew


  1. On 5/15/2022 at 4:03 PM, Rinzwind said:

    ASM on position 8. Sure.

    "The number of hits determines the ratings of a language." How asm ends up on position 8? 
     

    their list of included pages are too weird. Sharepoint.com ? Just redirects to ms.

     

    i first had the impression Tiobe stood for the number of queries in a month about a certain language, but apparently that's not the case. Pointless.

    Although ASM is very important in programming language, but no productivity at all, especially in risc environment.


  2. 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.

     


  3. 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;

    image.thumb.png.8b173fdcfe167244974aa3486dfdc7e0.png

     

    Thanks


  4. 2 hours ago, programmerdelphi2k said:

    @stacker_liew

     

    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.

     


  5. 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.


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

    • Like 1

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


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

     

×