Vortex icon indicating copy to clipboard operation
Vortex copied to clipboard

Feature Request: Access to Emission and Live Particle Count

Open Rspoon3 opened this issue 11 months ago • 1 comments

Description

As a developer using Vortex, I would like to have access to the emissionCount and the number of currently active/live particles in a VortexSystem. This would allow for better control over the particle system lifecycle, such as:

  • Removing a view after all particles have been emitted.
  • Dynamically adjusting the system based on the number of emitted particles.
  • Implementing effects such as a firework where the birthrate increases over time to simulate acceleration.

Current Behavior

  • The emissionCount is tracked internally in VortexSystem, but it is not accessible for external observation.
  • The particles array exists but is also private, preventing developers from monitoring active particles.

Code Example

Below is a code block of current basic example of having fireworks shoot off faster and faster each second. With the proposed changed, a timer would not have to be used, and the emissionCount could be referenced instead.

struct FireworksShowView: View {
    @State private var rate = 2.0
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VortexView(.fireworks(emissionsLimit: 100, rate: rate)) {
            Circle()
                .fill(.white)
                .frame(width: 32)
                .blur(radius: 5)
                .blendMode(.plusLighter)
                .tag("circle")
                .ignoresSafeArea(edges: .top)
        }
        .navigationSubtitle("Demonstrates multi-stage effects")
        .onReceive(timer) { input in
            rate += 1
        }
    }
}

extension VortexSystem {
    public static func fireworks(emissionsLimit: Int, rate: Double) -> VortexSystem {
        let fireworks = VortexSystem.fireworks
        fireworks.emissionLimit = emissionsLimit
        fireworks.birthRate = rate
        return fireworks
    }
}

Rspoon3 avatar Feb 20 '25 14:02 Rspoon3

I've been able to achieve this by creating a PassthroughSubject<Int, Never>() and sending the value every time emissionCount didSet is fired. Unfortunately, changing VortextSystem to be an ObservableObject results in the following error because the particle calculations are done inside the CanvasView.

Publishing changes from within view updates is not allowed, this will cause undefined behavior.

public var emissionCountPassthroughSubject = PassthroughSubject<Int, Never>()
    public internal(set) var emissionCount = 0 {
        didSet {
            emissionCountPass.send(emissionCount)
        }
    }

Is there a better approach that could be taken? Ideally we should not have to create a PassthroughSubject for every value we would like to observe.

Rspoon3 avatar Feb 21 '25 23:02 Rspoon3