; CountParticlesAsync Example
; ---------------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

; GPU particles need the DX12 device - check before creating
If GPUParticlesSupported()=0 Then RuntimeError "GPU particles are unavailable."

camera=CreateCamera()
PositionEntity camera,0,1,-5
CameraClsColor camera,10,15,30

emitter=CreateGPUParticleEmitter(10000)
If emitter=0 Then RuntimeError ParticleError$()

; Preset 1 is a fire fountain
ParticlePreset emitter,1

; A fixed timer keeps the simulation stepping at 60 updates per second
timer=CreateTimer(60)
paused=False
exact_count=-1

While Not KeyDown(1)

    ; P pauses, Space adds a burst, R clears, E takes an exact (waiting) count
    If KeyHit(25)
        paused=Not paused
        PauseParticles emitter,paused
    EndIf
    If KeyHit(57) Then EmitParticles emitter,100
    If KeyHit(19) Then ClearParticles emitter
    If KeyHit(18) Then exact_count=CountParticles(emitter)

    ; Arrow keys move the camera
    If KeyDown(200) Then MoveEntity camera,0,0,0.1
    If KeyDown(208) Then MoveEntity camera,0,0,-0.1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    ticks=WaitTimer(timer)
    If ticks>15 Then ticks=15
    For tick=1 To ticks
        UpdateWorld
    Next

    RenderWorld

    ; The async count never waits: -1 means no completed readback yet
    live=CountParticlesAsync(emitter)
    live_text$="pending"
    If live>=0 Then live_text$=Str$(live)

    Color 255,255,255
    Text 0,0,"Arrow keys: camera   P: pause   Space: burst   R: clear   E: exact count   Esc: exit"
    Text 0,20,"CountParticlesAsync(emitter) = "+live_text$+"   paused: "+paused
    Text 0,40,"Last exact CountParticles sample (may wait): "+exact_count

    Flip

Wend

FreeTimer timer
FreeEntity emitter

End
