-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement entity types and controller
Signed-off-by: Christian Stewart <[email protected]>
- Loading branch information
Showing
12 changed files
with
467 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package entitygraph_controller | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/aperturerobotics/entitygraph/entity" | ||
|
||
"github.com/aperturerobotics/controllerbus/directive" | ||
) | ||
|
||
// entityObserver is an entity observer. | ||
type entityObserver struct { | ||
// c is the controller | ||
c *Controller | ||
} | ||
|
||
// newEntityObserver constructs a new entityObserver | ||
func newEntityObserver(c *Controller) *entityObserver { | ||
return &entityObserver{c: c} | ||
} | ||
|
||
// Resolve resolves the values, emitting them to the handler. | ||
// The resolver may be canceled and restarted multiple times. | ||
// Any fatal error resolving the value is returned. | ||
// The resolver will not be retried after returning an error. | ||
// Values will be maintained from the previous call. | ||
func (e *entityObserver) Resolve(ctx context.Context, handler directive.ResolverHandler) error { | ||
// Register the observer with the system and get the initial set | ||
var valueIDS []uint32 | ||
var valueMtx sync.Mutex | ||
var disposed bool | ||
addVal := func(ent entity.Entity) { | ||
if disposed { | ||
return | ||
} | ||
|
||
id, ok := handler.AddValue(ent) | ||
if ok { | ||
valueIDS = append(valueIDS, id) | ||
} | ||
} | ||
|
||
valueMtx.Lock() | ||
initialSet := e.c.registerObserver(e, func(ent entity.Entity) { | ||
valueMtx.Lock() | ||
defer valueMtx.Unlock() | ||
addVal(ent) | ||
}) | ||
for _, is := range initialSet { | ||
addVal(is) | ||
} | ||
valueMtx.Unlock() | ||
|
||
defer func() { | ||
valueMtx.Lock() | ||
disposed = true | ||
vids := valueIDS | ||
valueIDS = nil | ||
valueMtx.Unlock() | ||
|
||
e.c.clearObserver(e) | ||
for _, valID := range vids { | ||
_, _ = handler.RemoveValue(valID) | ||
} | ||
}() | ||
|
||
<-ctx.Err() | ||
return nil | ||
} | ||
|
||
// _ is a type assertion | ||
var _ directive.Resolver = ((*entityObserver)(nil)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package entitygraph_controller | ||
|
||
import ( | ||
"github.com/aperturerobotics/entitygraph/entity" | ||
"github.com/aperturerobotics/entitygraph/store" | ||
) | ||
|
||
// storeHandler handles collect events. | ||
type storeHandler struct { | ||
// c is the controller | ||
c *Controller | ||
} | ||
|
||
// newStoreHandler constructs a new storeHandler. | ||
func newStoreHandler(c *Controller) *storeHandler { | ||
return &storeHandler{c: c} | ||
} | ||
|
||
// HandleEntityAdded handles a new entity being added to the store. | ||
func (h *storeHandler) HandleEntityAdded(ent entity.Entity) { | ||
// TODO: emit to directive | ||
} | ||
|
||
// HandleEntityRemoved handles a entity being removed from the store. | ||
func (h *storeHandler) HandleEntityRemoved(ent entity.Entity) { | ||
// TODO: emit to directive | ||
} | ||
|
||
// _ is a type assertion | ||
var _ store.Handler = ((*storeHandler)(nil)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package entitygraph | ||
|
||
import ( | ||
"github.com/aperturerobotics/controllerbus/directive" | ||
) | ||
|
||
// observeEntityGraph implements ObserveEntityGraph | ||
type observeEntityGraph struct{} | ||
|
||
// ObserveEntityGraphDirective is a marker function. | ||
func (g *observeEntityGraph) ObserveEntityGraphDirective() { | ||
// noop | ||
} | ||
|
||
// NewObserveEntityGraph constructs a new ObserveEntityGraph directive. | ||
func NewObserveEntityGraph() ObserveEntityGraph { | ||
return &observeEntityGraph{} | ||
} | ||
|
||
// Validate validates the directive. | ||
// This is a cursory validation to see if the values "look correct." | ||
func (g *observeEntityGraph) Validate() error { | ||
return nil | ||
} | ||
|
||
// GetValueOptions returns options relating to value handling. | ||
func (g *observeEntityGraph) GetValueOptions() directive.ValueOptions { | ||
return directive.ValueOptions{} | ||
} | ||
|
||
// IsEquivalent checks if the other directive is equivalent. If two | ||
// directives are equivalent, and the new directive does not superceed the | ||
// old, then the new directive will be merged (de-duplicated) into the old. | ||
func (g *observeEntityGraph) IsEquivalent(other directive.Directive) bool { | ||
_, ok := other.(ObserveEntityGraph) | ||
return ok | ||
} | ||
|
||
// Superceeds checks if the directive overrides another. | ||
// The other directive will be canceled if superceded. | ||
func (g *observeEntityGraph) Superceeds(other directive.Directive) bool { | ||
return false | ||
} | ||
|
||
// _ is a type assertion | ||
var _ ObserveEntityGraph = ((*observeEntityGraph)(nil)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package entity | ||
|
||
// Entity is a string-ID identified node in the entity graph. | ||
type Entity interface { | ||
// GetEntityID returns the entity identifier. | ||
GetEntityID() string | ||
// GetEntityTypeName returns the entity type name. | ||
GetEntityTypeName() string | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package entity | ||
|
||
// Ref is a reference to another entity. | ||
type Ref interface { | ||
// GetEntityRefId returns the referenced entity ID. | ||
GetEntityRefId() string | ||
// GetEntityRefTypeName returns the referenced entity type name. | ||
GetEntityRefTypeName() string | ||
} | ||
|
||
// entityRef implements Ref | ||
type entityRef struct { | ||
refID string | ||
refTypeName string | ||
} | ||
|
||
// NewEntityRef builds a new EntityRef with an entity handle. | ||
func NewEntityRef(ent Entity) Ref { | ||
return NewEntityRefWithID(ent.GetEntityID(), ent.GetEntityTypeName()) | ||
} | ||
|
||
// NewEntityRefWithID builds a new EntityRef with an id and type name. | ||
func NewEntityRefWithID(refID, refTypeName string) Ref { | ||
return &entityRef{refID: refID, refTypeName: refTypeName} | ||
} | ||
|
||
// GetEntityRefId returns the referenced entity ID. | ||
func (e *entityRef) GetEntityRefId() string { | ||
return e.refID | ||
} | ||
|
||
// GetEntityRefTypeName returns the referenced entity type name. | ||
func (e *entityRef) GetEntityRefTypeName() string { | ||
return e.refTypeName | ||
} | ||
|
||
// _ is a type assertion | ||
var _ Ref = ((*entityRef)(nil)) |
Oops, something went wrong.