Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
partitioner.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef PARTITIONER_H
20 #define PARTITIONER_H
21 
22 #include <memory>
23 #include <set>
24 #include <map>
25 #include <vector>
26 
27 #include "generic/property.h"
28 #include "generic/managed.h"
29 #include "renderers/renderer.h"
30 #include "types.h"
31 #include "interfaces.h"
32 #include "nodes/stage_node.h"
33 
34 namespace smlt {
35 
36 class SubActor;
37 
38 enum WriteOperation {
39  WRITE_OPERATION_ADD,
40  WRITE_OPERATION_UPDATE,
41  WRITE_OPERATION_REMOVE,
42  WRITE_OPERATION_MAX
43 };
44 
45 struct StagedWrite {
46  WriteOperation operation;
47  StageNodeType stage_node_type;
48  AABB new_bounds;
49 };
50 
51 #define MAX_STAGED_WRITES 256
52 
54  public RefCounted<Partitioner> {
55 
56 public:
57  Partitioner(Stage* ss):
58  stage_(ss) {}
59 
60  void add_particle_system(ParticleSystemID particle_system_id);
61  void update_particle_system(ParticleSystemID particle_system_id, const AABB& bounds);
62  void remove_particle_system(ParticleSystemID particle_system_id);
63 
64  void add_geom(GeomID geom_id);
65  void remove_geom(GeomID geom_id);
66 
67  void add_actor(ActorID actor_id);
68  void update_actor(ActorID actor_id, const AABB& bounds);
69  void remove_actor(ActorID actor_id);
70 
71  void add_light(LightID light_id);
72  void update_light(LightID light_id, const AABB& bounds);
73  void remove_light(LightID light_id);
74 
75  void add_mesh_instancer(MeshInstancerID mesh_instancer_id);
76  void update_mesh_instancer(MeshInstancerID mesh_instancer_id, const AABB& bounds);
77  void remove_mesh_instancer(MeshInstancerID mesh_instancer_id);
78 
79  void _apply_writes();
80 
81  virtual void lights_and_geometry_visible_from(
82  CameraID camera_id,
83  std::vector<LightID>& lights_out,
84  std::vector<StageNode*>& geom_out
85  ) = 0;
86 
87  virtual MeshID debug_mesh_id() { return MeshID(); }
88 protected:
89  Stage* get_stage() const { return stage_; }
90 
91  virtual void apply_staged_write(const UniqueIDKey& key, const StagedWrite& write) = 0;
92 
93  template<typename ID>
94  void stage_write(const ID& id, const StagedWrite& op) {
95  auto key = make_unique_id_key(id);
96  auto& value = staged_writes_[key];
97  value.slot[op.operation] = op;
98 
99  if(!(value.bits & (1 << WRITE_OPERATION_ADD)) && op.operation == WRITE_OPERATION_REMOVE) {
100  /* If no write op has happened, and this was a remove operation, we store
101  * that this was the first operation of the two */
102  value.bits |= (1 << WRITE_OPERATION_MAX);
103  }
104 
105  value.bits |= (1 << op.operation);
106 
107  /* Apply staged writes immediately to prevent the size spiralling */
108  if(staged_writes_.size() >= MAX_STAGED_WRITES) {
109  _apply_writes();
110  }
111  }
112 
113 private:
114  Stage* stage_;
115 
116  thread::Mutex staging_lock_;
117 
118  struct WriteSlots {
119  StagedWrite slot[WRITE_OPERATION_MAX];
120  uint8_t bits = 0;
121  };
122 
123  std::map<UniqueIDKey, WriteSlots> staged_writes_;
124 
125 protected:
126  Property<decltype(&Partitioner::stage_)> stage = { this, &Partitioner::stage_ };
127 
128 };
129 
130 }
131 
132 namespace std {
133  DEFINE_ENUM_HASH(smlt::WriteOperation);
134 }
135 
136 #endif // PARTITIONER_H
smlt::Property
Definition: property.h:202
smlt::StagedWrite
Definition: partitioner.h:45
smlt::Stage
Definition: stage.h:92
smlt::Partitioner
Definition: partitioner.h:54
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::UniqueID< ParticleSystemPtr >
smlt::AABB
Definition: aabb.h:22
std
Extensions to the C++ standard library.
Definition: unique_id.h:200
smlt::thread::Mutex
Definition: mutex.h:25