Inherits from NSObject
Conforms to OGWNotifierDelegate
Declared in OGWAspect.h

Overview

Aspects are code plugins for entities or the world. Each subclass of OGWAspect provides custom code and/or data that can be used while the aspect is added to an entity.

Subclassing Notes

Aspects are normally added automatically to each entity when the entity is assigned to a category. The OGWEntityCategory class contains a list of aspect classes to instantiate and add to each entity.

Aspects should therefore be developed to remain on an entity throughout its lifetime, rather than adding/removing entities as needed. This would not only be inefficient for performance but also changes the order in which aspects are updated, which is often important.

To temporarily disable an aspect, you can use the enabled property to program the aspect to stop updating or performing any other work (as needed) when it is not enabled. That way you can temporarily remove functionality without having to remove or replace an aspect.

Aspects should always subclass from OGWAspect. If you find the need to subclass from a more concrete aspect subclass, then while that is legal it may indicate a flaw in your class design. The indiciation being a lack of generalization or perhaps the aspect is doing too much already and should be broken down into multiple decoupled aspects, with the intended subclass now becoming one of the fragment aspects.

Conventions

World aspects should follow the OGWWorldAspect naming convention, whereas entity aspects simply omit the reference to entity: OGWAspect.

Aspects should not use custom initializers but use safe default values and expose all modifiable settings as properties. All aspects can be created through the aspectWithWorld: and aspectWithEntity: initializers.

In subclasses override the following methods to perform initialization and set default values, setup with and caching of other aspects, and performing cleanup work:

-(void) aspectDidInitialize
-(void) ownerDidAddAspect:(OGWAspect)addedAspect
-(void) ownerWillRemoveAspect:(OGWAspect
)removingAspect

Refering to other Aspects

When one aspect often needs another aspect, it can cache the reference locally but only in a __weak ivar/property to avoid potential memory leaks (retain cycles).

Alternatively one aspect can provide a delegate to receive events, either by adding a delegate property or by using the notifier which should be used when there may be more than one delegate interested in the aspect’s events.

In delegation it is customary to provide the sending aspect as the first parameter in every delegate method. That way the sender is clear and the receiver can access additional data from the sender as needed. Example aspect delegate methods:

-(void) aspect:(OGWContactAspect)aspect contactWithEntity:(OGWEntity)contact category:(const OGWEntityCategory)category;
-(BOOL) aspect:(OGWStateAspect
)aspect shouldChangeState:(GWState)newState currentState:(GWState)currentState reason:(GWReason)reason;
-(void) aspect:(OGWWorldGravityAspect*)aspect gravityDidChange:(GWVector)gravity;

Warning: If aspect A directly references aspect B while aspect B directly references aspect A you have a code smell. Typically one aspect provides the work needed by another aspect - two closely interacting aspects in a back-and-forth manner indicate that they are tightly coupled, and should either be merged into one or one abstracted to work without the other (tip: delegation).

Properties

enabled

The enabled state can be used by aspects as they see fit, it has no inherent function. Typically an aspect will use the enabled flag to stop update processing while it is not enabled.

@property BOOL enabled

Return Value

Whether the aspect is enabled.

Discussion

The enabled flag plays an important role because aspects are not supposed to be added/removed as needed, but instead most aspects are added the moment an entity is created and remain on the entity until the entity deallocates. The enabled flag thus can be used to control temporarily disabled aspects.

Declared In

OGWAspect.h

entity

The entity owning the aspect.

@property (weak, readonly) OGWEntity *entity

Return Value

The entity owning the aspect.

See Also

Declared In

OGWAspect.h

notifier

Some aspects use the notifier to send delegate messages to multiple delegate. Refer to the specific aspect’s documentation to learn whether it uses the multi-delegation notifier.

@property (readonly) OGWNotifier *notifier

Return Value

The notifier, or nil if the aspect does not support multi-delegation.

Declared In

OGWAspect.h

world

The world reference provides quick access to the entity’s world.

@property (weak, readonly) OGWWorld *world

Return Value

The entity’s world.

See Also

Declared In

OGWAspect.h

Class Methods

aspectWithEntity:

Creates a designated entity aspect.

+ (id)aspectWithEntity:(OGWEntity *)entity

Parameters

entity

The entity to which the aspect will be added.

Return Value

A new aspect.

Declared In

OGWAspect.h

aspectWithWorld:

Creates a designated world aspect. Normally aspects are added through their category.

+ (id)aspectWithWorld:(OGWWorld *)world

Parameters

world

The world to which the aspect will be added.

Return Value

A new aspect.

Declared In

OGWAspect.h

Instance Methods

aspectDidInitialize

Sent when the OGWAspect class ran its init method. You’re not supposed to override the usual init methods in an aspect class, so instead place any initialization code and setting default values to this method.

- (void)aspectDidInitialize

Discussion

Warning: This message is not supposed to be sent by user code. It is sent from OGWAspect.

Declared In

OGWAspect.h

createNotifierWithProtocol:

This will create a OGWNotifier object and initialize it with the given protocol. Aspect subclasses use this to allow sending delegate messages to multiple delegates via the OGWNotifier object. The protocol is used to ensure (to some extent) type safety of the delegates.

- (void)createNotifierWithProtocol:(Protocol *)protocol

Parameters

protocol

The protocol that delegates have to implement.

Discussion

Warning: This message is not supposed to be sent from another object to an aspect.

Declared In

OGWAspect.h

ownerDidAddAspect:

Sent when the aspect was added to its owner, which depending on the aspects intended use can either be the world or an entity.

- (void)ownerDidAddAspect:(OGWAspect *)addedAspect

Parameters

addedAspect

The aspect that was added.

Discussion

Typically aspects test either for addedAspect == self to perform further initialization when being added to an owner, and/or test for ‘[addedAspect isMemberOfClass:[OGWSomeOtherAspect class]]` to find a specific aspect that may be added only after this aspect has been added.

Warning: This message is not supposed to be sent by user code. It is sent from OGWAspect.

Declared In

OGWAspect.h

ownerWillRemoveAspect:

Sent before the aspect is removed from its owner, which depending on the aspects intended use can either be the world or an entity.

- (void)ownerWillRemoveAspect:(OGWAspect *)removingAspect

Parameters

removingAspect

The aspect that will be removed.

Discussion

Typically aspects test either for addedAspect == self or ‘[addedAspect isMemberOfClass:[OGWSomeOtherAspect class]]` to perform cleanup work for themselves or when another aspect they depend on is removed.

Warning: This message is not supposed to be sent by user code. It is sent from OGWAspect.

Declared In

OGWAspect.h