tguerin / newton

An Easy To Use Particle Emitter
https://newton.7omtech.fr
MIT License
22 stars 7 forks source link

NewtonState.removeEffect removes wrong effects #24

Closed KriseevM closed 1 month ago

KriseevM commented 1 month ago

I have this almost minimal example code:

import 'package:flutter/material.dart';
import 'package:newton_particles/newton_particles.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  final newtonKey = GlobalKey<NewtonState>();
  Offset nextOrigin = const Offset(20, 20);
  List<Effect<AnimatedParticle>> e = [];
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            Expanded(
              child: Newton(
                key: newtonKey,
              ),
            ),
            TextButton(
                onPressed: () {
                  e.add(
                    ExplodeEffect(
                      particleConfiguration: ParticleConfiguration(
                          shape: CircleShape(), size: const Size(5, 5)),
                      effectConfiguration:
                          EffectConfiguration(origin: nextOrigin),
                    ),
                  );
                  newtonKey.currentState?.addEffect(e.last);
                  var nextRow = nextOrigin.dx > 120;
                  nextOrigin = Offset(
                    nextRow ? 20 : nextOrigin.dx + 20,
                    nextRow ? nextOrigin.dy + 20 : nextOrigin.dy,
                  );
                },
                child: const Text('Add')),
            TextButton(
              onPressed: () {
                newtonKey.currentState?.removeEffect(e.last);
                e.removeLast();
              },
              child: const Text('Remove'),
            ),
          ],
        ),
      ),
    );
  }
}

From what I understand, each click on Add button will add new effect and click on the Remove button should remove the last effect. In fact it removes all effects. I believe this is a bug.

I looked into code and I think it is caused by names collision since effect is both removeEffect's and lambda expression's parameter and in lambda expression it checks if effect's rootEffect is this same effect instead of what was given to removeEffect

removeEffect(Effect effect) {
  setState(() {
    _activeEffects.removeWhere((effect) => effect.rootEffect == effect);
    _pendingActiveEffects
        .removeWhere((effect) => effect.rootEffect == effect);
  });
}