Game Development Reference
In-Depth Information
a crash whenever the component destructor tried to access the actor. The actor gets
destroyed when all strong references are released, which means all weak references
are immediately made invalid. The result is that the component
'
s weak reference to
the actor is no longer valid and can
t be used. Since both references need to be strong
references, the circular reference chain has to be explicitly broken. The Destroy()
function takes care of this by explicitly clearing out the component map.
The Update() function is called every time the game updates. You
'
'
ll see how this
works in Chapter 7,
Controlling the Main Loop,
when you learn about the main
game loop.
GetComponent() is a template function that enables you to get any component by
passing in the component ID. It takes care of the smart pointer casting and returns a
weak reference to the component, which allows the caller to safely store this pointer
while still allowing the component to be destroyed. Just be sure to check the validity
of the pointer before using it.
Looking back at the class declaration, you might notice something a bit odd. There
are no virtual functions whatsoever, because this class is not meant to be subclassed.
All the variation comes from the components you attach to this actor. That
'
s called
composition, which is in action here (see Chapter 3).
Another key thing to notice is that the Actor class does absolutely nothing by itself.
Its entire purpose in life is to manage and maintain components. An actor without
components is just an empty box.
Simple Functions Can Be More Expensive Than You Think
The GetComponent() function is extremely simple
s
typically very small and returns a value. By itself, this is certainly fast enough, but
this function has the possibility of being called hundreds or even thousands of times
eachframe.It
it just searches a map that
'
s important to make sure that functions like this are lightning fast. The
previous implementation is the simplest way but not the fastest.
'
On The Sims Medieval, our component maps for actors are laid out in a
contiguous block of memory and are accessed by offset. When a system asks
for a component,
s a simple pointer add to find the correct component.
Another solution could be to cache certain components. One project I worked
on had a transform component that was so commonly accessed, we just had a
pointer to it directly on the Actor class.
it
'
'
Here
s a look at the ActorComponent base class:
class ActorComponent
{
friend class ActorFactory;
 
Search WWH ::




Custom Search