[Bf-blender-cvs] [41cbcf96e9a] functions: try a different approach to connect state to solvers

Jacques Lucke noreply at git.blender.org
Fri Jun 7 12:34:34 CEST 2019


Commit: 41cbcf96e9a278eb36a9402c4271929fad9db23e
Author: Jacques Lucke
Date:   Fri Jun 7 12:00:02 2019 +0200
Branches: functions
https://developer.blender.org/rB41cbcf96e9a278eb36a9402c4271929fad9db23e

try a different approach to connect state to solvers

===================================================================

M	source/blender/modifiers/intern/MOD_nodeparticles.c
M	source/blender/simulations/BParticles.h
M	source/blender/simulations/playground.cpp

===================================================================

diff --git a/source/blender/modifiers/intern/MOD_nodeparticles.c b/source/blender/modifiers/intern/MOD_nodeparticles.c
index 07cf80c0a03..fc9e2c02a64 100644
--- a/source/blender/modifiers/intern/MOD_nodeparticles.c
+++ b/source/blender/modifiers/intern/MOD_nodeparticles.c
@@ -114,7 +114,7 @@ static Mesh *applyModifier(ModifierData *md,
     runtime->description = new_description;
     runtime->solver = new_solver;
 
-    BParticles_state_step(runtime->state);
+    BParticles_state_step(runtime->solver, runtime->state);
   }
   else {
     BParticles_state_free(runtime->state);
@@ -127,11 +127,11 @@ static Mesh *applyModifier(ModifierData *md,
   }
   runtime->last_simulated_frame = current_frame;
 
-  uint point_amount = BParticles_state_particle_count(runtime->state);
+  uint point_amount = BParticles_state_particle_count(runtime->solver, runtime->state);
   Mesh *mesh = BKE_mesh_new_nomain(point_amount, 0, 0, 0, 0);
 
   float(*positions)[3] = MEM_malloc_arrayN(point_amount, sizeof(float[3]), __func__);
-  BParticles_state_get_positions(runtime->state, positions);
+  BParticles_state_get_positions(runtime->solver, runtime->state, positions);
 
   for (uint i = 0; i < point_amount; i++) {
     copy_v3_v3(mesh->mvert[i].co, positions[i]);
diff --git a/source/blender/simulations/BParticles.h b/source/blender/simulations/BParticles.h
index ff69983d502..c4a893e627d 100644
--- a/source/blender/simulations/BParticles.h
+++ b/source/blender/simulations/BParticles.h
@@ -20,11 +20,13 @@ void BParticles_solver_free(BParticlesSolver solver);
 
 BParticlesState BParticles_state_init(BParticlesSolver solver);
 void BParticles_state_adapt(BParticlesSolver new_solver, BParticlesState *state_to_adapt);
-void BParticles_state_step(BParticlesState state);
+void BParticles_state_step(BParticlesSolver solver, BParticlesState state);
 void BParticles_state_free(BParticlesState state);
 
-uint BParticles_state_particle_count(BParticlesState state);
-void BParticles_state_get_positions(BParticlesState state, float (*dst)[3]);
+uint BParticles_state_particle_count(BParticlesSolver solver, BParticlesState state);
+void BParticles_state_get_positions(BParticlesSolver solver,
+                                    BParticlesState state,
+                                    float (*dst)[3]);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/simulations/playground.cpp b/source/blender/simulations/playground.cpp
index 4f99e448d39..0d674e3e2a7 100644
--- a/source/blender/simulations/playground.cpp
+++ b/source/blender/simulations/playground.cpp
@@ -19,7 +19,8 @@ namespace BParticles {
 
 class Description;
 class Solver;
-class State;
+class WrappedState;
+class StateBase;
 
 class Description {
  public:
@@ -30,14 +31,50 @@ class Solver {
  public:
   virtual ~Solver();
 
-  virtual void step(State *state) const = 0;
+  virtual WrappedState *init() = 0;
+  virtual void step(WrappedState &wrapped_state) = 0;
+
+  virtual uint particle_amount(WrappedState &wrapped_state) = 0;
+  virtual void get_positions(WrappedState &wrapped_state, float (*dst)[3]) = 0;
 };
 
-class State {
+class StateBase {
  public:
-  virtual ~State();
+  virtual ~StateBase();
+};
+
+class WrappedState final {
+ private:
+  Solver *m_solver;
+  std::unique_ptr<StateBase> m_state;
+
+ public:
+  WrappedState(Solver *solver, std::unique_ptr<StateBase> state)
+      : m_solver(solver), m_state(std::move(state))
+  {
+    BLI_assert(solver);
+    BLI_assert(m_state.get() != NULL);
+  }
 
-  virtual Solver *solver() const = 0;
+  WrappedState(WrappedState &other) = delete;
+  WrappedState(WrappedState &&other) = delete;
+  WrappedState &operator=(WrappedState &other) = delete;
+  WrappedState &operator=(WrappedState &&other) = delete;
+
+  Solver &solver() const
+  {
+    BLI_assert(m_solver);
+    return *m_solver;
+  }
+
+  template<typename T> T &state() const
+  {
+    T *state = dynamic_cast<T *>(m_state.get());
+    BLI_assert(state);
+    return *state;
+  }
+
+  friend void ::BParticles_state_adapt(BParticlesSolver, BParticlesState *);
 };
 
 Description::~Description()
@@ -46,7 +83,8 @@ Description::~Description()
 Solver::~Solver()
 {
 }
-State::~State()
+
+StateBase::~StateBase()
 {
 }
 
@@ -58,11 +96,12 @@ struct Vector {
 
 using BParticles::Description;
 using BParticles::Solver;
-using BParticles::State;
+using BParticles::StateBase;
+using BParticles::WrappedState;
 
 WRAPPERS(BParticles::Description *, BParticlesDescription);
 WRAPPERS(BParticles::Solver *, BParticlesSolver);
-WRAPPERS(BParticles::State *, BParticlesState);
+WRAPPERS(BParticles::WrappedState *, BParticlesState);
 
 BParticlesDescription BParticles_playground_description()
 {
@@ -73,44 +112,44 @@ void BParticles_description_free(BParticlesDescription description_c)
   delete unwrap(description_c);
 }
 
-class SimpleState : public State {
+class SimpleSolver : public Solver {
  private:
-  SmallVector<Vector> m_positions;
+  Description *m_description;
 
- public:
-  Solver *m_solver;
+  struct MyState : StateBase {
+    SmallVector<Vector> positions;
+  };
 
-  SimpleState(Solver *solver) : m_solver(solver)
+ public:
+  SimpleSolver(Description *description) : m_description(description)
   {
   }
 
-  Solver *solver() const override
+  WrappedState *init() override
   {
-    return m_solver;
+    MyState *state = new MyState();
+    return new WrappedState(this, std::unique_ptr<MyState>(state));
   }
 
-  SmallVector<Vector> &positions()
+  void step(WrappedState &wrapped_state) override
   {
-    return m_positions;
+    MyState &state = wrapped_state.state<MyState>();
+    for (Vector &position : state.positions) {
+      position.x += 0.1f;
+    }
+    state.positions.append({0, 0, 1});
   }
-};
 
-class SimpleSolver : public Solver {
- private:
-  Description *m_description;
-
- public:
-  SimpleSolver(Description *description) : m_description(description)
+  uint particle_amount(WrappedState &wrapped_state) override
   {
+    MyState &state = wrapped_state.state<MyState>();
+    return state.positions.size();
   }
 
-  void step(State *state_) const override
+  void get_positions(WrappedState &wrapped_state, float (*dst)[3]) override
   {
-    SimpleState *state = (SimpleState *)state_;
-    for (Vector &position : state->positions()) {
-      position.x += 0.1f;
-    }
-    state->positions().append({0, 0, 1});
+    MyState &state = wrapped_state.state<MyState>();
+    memcpy(dst, state.positions.begin(), state.positions.size() * sizeof(Vector));
   }
 };
 
@@ -125,31 +164,39 @@ void BParticles_solver_free(BParticlesSolver solver_c)
 
 BParticlesState BParticles_state_init(BParticlesSolver solver_c)
 {
-  return wrap(new SimpleState(unwrap(solver_c)));
+  Solver *solver = unwrap(solver_c);
+  return wrap(solver->init());
 }
 void BParticles_state_adapt(BParticlesSolver new_solver_c, BParticlesState *state_to_adapt_c)
 {
-  SimpleState *state = (SimpleState *)unwrap(*state_to_adapt_c);
-  state->m_solver = unwrap(new_solver_c);
+  Solver *new_solver = unwrap(new_solver_c);
+  WrappedState *wrapped_state = unwrap(*state_to_adapt_c);
+  wrapped_state->m_solver = new_solver;
 }
-void BParticles_state_step(BParticlesState state_c)
+void BParticles_state_step(BParticlesSolver solver_c, BParticlesState state_c)
 {
-  State *state = unwrap(state_c);
-  Solver *solver = state->solver();
-  solver->step(state);
+  Solver *solver = unwrap(solver_c);
+  WrappedState *wrapped_state = unwrap(state_c);
+
+  BLI_assert(solver == &wrapped_state->solver());
+  solver->step(*wrapped_state);
 }
 void BParticles_state_free(BParticlesState state_c)
 {
   delete unwrap(state_c);
 }
 
-uint BParticles_state_particle_count(BParticlesState state_c)
+uint BParticles_state_particle_count(BParticlesSolver solver_c, BParticlesState state_c)
 {
-  SimpleState *state = (SimpleState *)unwrap(state_c);
-  return state->positions().size();
+  Solver *solver = unwrap(solver_c);
+  WrappedState *wrapped_state = unwrap(state_c);
+  return solver->particle_amount(*wrapped_state);
 }
-void BParticles_state_get_positions(BParticlesState state_c, float (*dst)[3])
+void BParticles_state_get_positions(BParticlesSolver solver_c,
+                                    BParticlesState state_c,
+                                    float (*dst)[3])
 {
-  SimpleState *state = (SimpleState *)unwrap(state_c);
-  memcpy(dst, state->positions().begin(), state->positions().size() * sizeof(Vector));
+  Solver *solver = unwrap(solver_c);
+  WrappedState *wrapped_state = unwrap(state_c);
+  solver->get_positions(*wrapped_state, dst);
 }



More information about the Bf-blender-cvs mailing list