feat: using goroutines for every object.
This commit is contained in:
parent
6e76188bd8
commit
aa4bcc3f8d
12 changed files with 123 additions and 92 deletions
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
type Debug struct {
|
||||
gg.Visibility
|
||||
gg.Layer
|
||||
gg.Object
|
||||
}
|
||||
|
||||
func (d *Debug) Draw(c *Context) {
|
||||
|
|
|
@ -46,10 +46,10 @@ func main() {
|
|||
player = NewPlayer()
|
||||
tri = NewTri()
|
||||
|
||||
e.Add(&Debug{})
|
||||
e.Add(player)
|
||||
e.Add(rect)
|
||||
e.Add(tri)
|
||||
e.Spawn(&Debug{})
|
||||
e.Spawn(player)
|
||||
e.Spawn(rect)
|
||||
e.Spawn(tri)
|
||||
fmt.Println(rect.GetLayer(), player.GetLayer())
|
||||
|
||||
err = e.Run()
|
||||
|
|
|
@ -11,7 +11,6 @@ type Player struct {
|
|||
gg.Sprite
|
||||
MoveSpeed gg.Float
|
||||
ScaleSpeed gg.Float
|
||||
gg.Layer
|
||||
}
|
||||
|
||||
func NewPlayer() *Player {
|
||||
|
|
|
@ -4,7 +4,6 @@ import "vultras.su/core/gg"
|
|||
|
||||
type Rect struct {
|
||||
gg.DrawableRectangle
|
||||
gg.Layer
|
||||
}
|
||||
|
||||
func NewRect() *Rect {
|
||||
|
@ -17,6 +16,7 @@ func NewRect() *Rect {
|
|||
gg.MaxColorV,
|
||||
}
|
||||
ret.Layer = RectL
|
||||
ret.Visible = true
|
||||
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import "fmt"
|
|||
|
||||
type Tri struct {
|
||||
gg.DrawablePolygon
|
||||
gg.Layer
|
||||
Spawned bool
|
||||
}
|
||||
|
||||
func NewTri() *Tri {
|
||||
|
@ -34,6 +34,10 @@ func (t *Tri) Update(c *Context) {
|
|||
t.Color = gg.Rgba(1, 0, 1, 1)
|
||||
}
|
||||
|
||||
/*if t.Spawned {
|
||||
return
|
||||
}*/
|
||||
|
||||
d := +1.
|
||||
if c.IsPressed(gg.KeyShift) {
|
||||
d = -1.
|
||||
|
@ -55,15 +59,25 @@ func (t *Tri) Update(c *Context) {
|
|||
func (t *Tri) Event(c *Context) {
|
||||
switch e := c.Event.(type) {
|
||||
case *gg.KeyDown:
|
||||
if e.Key != gg.Key1 {
|
||||
break
|
||||
}
|
||||
if t.Connected() {
|
||||
fmt.Println("disconnecting:", tri.Transform)
|
||||
t.Disconnect()
|
||||
} else {
|
||||
t.Connect(player)
|
||||
fmt.Println("connecting:", tri.Transform)
|
||||
fmt.Println(e)
|
||||
switch e.Key {
|
||||
case gg.Key1 :
|
||||
if t.Connected() {
|
||||
fmt.Println("disconnecting:", tri.Transform)
|
||||
t.Disconnect()
|
||||
} else {
|
||||
t.Connect(player)
|
||||
fmt.Println("connecting:", tri.Transform)
|
||||
}
|
||||
case gg.Key2 :
|
||||
if t.Spawned {
|
||||
return
|
||||
}
|
||||
fmt.Println("shit")
|
||||
tt := *t
|
||||
tt.Spawned = true
|
||||
tt.Disconnect()
|
||||
c.Spawn(&tt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
context.go
11
context.go
|
@ -1,6 +1,17 @@
|
|||
package gg
|
||||
|
||||
type contextType int
|
||||
const (
|
||||
startContext contextType = iota
|
||||
updateContext
|
||||
eventContext
|
||||
drawContext
|
||||
deleteContext
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
typ contextType
|
||||
events []any
|
||||
*Engine
|
||||
*Image
|
||||
Event any
|
||||
|
|
108
engine.go
108
engine.go
|
@ -47,7 +47,7 @@ type Engine struct {
|
|||
// The main holder for objects.
|
||||
// Uses the map structure to quickly
|
||||
// delete and create new objects.
|
||||
Objects maps.Map[Object, struct{}]
|
||||
Objects maps.Map[Objecter, struct{}]
|
||||
|
||||
// The main camera to display in window.
|
||||
// If is set to nil then the engine will panic.
|
||||
|
@ -64,6 +64,7 @@ type Engine struct {
|
|||
wheel Vector
|
||||
cursorPos Vector
|
||||
outerEvents, handleEvents EventChan
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
type engine Engine
|
||||
|
@ -102,7 +103,7 @@ func NewEngine(
|
|||
ret.Camera = ret.NewCamera()
|
||||
ret.outerEvents = make(EventChan)
|
||||
ret.handleEvents = make(EventChan)
|
||||
ret.Objects = maps.NewOrdered[Object, struct{}]()
|
||||
ret.Objects = maps.NewOrdered[Objecter, struct{}]()
|
||||
ret.buttons = MouseButtonMap{}
|
||||
return ret
|
||||
}
|
||||
|
@ -125,42 +126,42 @@ func (e *Engine) EventInput() EventChan {
|
|||
|
||||
// Add new object considering what
|
||||
// interfaces it implements.
|
||||
func (e *Engine) Add(b any) error {
|
||||
object, _ := b.(Object)
|
||||
if e.Objects.Has(object) {
|
||||
func (e *Engine) Spawn(b Objecter) error {
|
||||
if e.Objects.Has(b) {
|
||||
return ObjectExistErr
|
||||
}
|
||||
/*o, ok := e.makeObject(b)
|
||||
if !ok {
|
||||
return ObjectNotImplementedErr
|
||||
}*/
|
||||
|
||||
starter, ok := b.(Starter)
|
||||
if ok {
|
||||
starter.Start(&Context{
|
||||
Engine: e,
|
||||
})
|
||||
}
|
||||
|
||||
e.Objects.Set(object, struct{}{})
|
||||
b.Start(&Context{Engine: e})
|
||||
obj := b.GetObject()
|
||||
obj.input = make(chan *Context)
|
||||
go func() {
|
||||
for c := range obj.input {
|
||||
switch c.typ {
|
||||
case updateContext:
|
||||
b.Update(c)
|
||||
case eventContext:
|
||||
for _, event := range c.events {
|
||||
b.Event(&Context{
|
||||
Engine: e,
|
||||
Event: event,
|
||||
})
|
||||
}
|
||||
}
|
||||
e.wg.Done()
|
||||
}
|
||||
}()
|
||||
e.Objects.Set(b, struct{}{})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete object from Engine.
|
||||
func (e *Engine) Del(b any) error {
|
||||
object, _ := b.(Object)
|
||||
if !e.Objects.Has(object) {
|
||||
func (e *Engine) Del(b Objecter) error {
|
||||
if !e.Objects.Has(b) {
|
||||
return ObjectNotExistErr
|
||||
}
|
||||
|
||||
deleter, ok := b.(Deleter)
|
||||
if ok {
|
||||
deleter.Delete(&Context{
|
||||
Engine: e,
|
||||
})
|
||||
}
|
||||
|
||||
b.Delete(&Context{Engine: e})
|
||||
e.Objects.Del(b)
|
||||
|
||||
return nil
|
||||
|
@ -210,24 +211,16 @@ func (e *Engine) AbsCursorPosition() Vector {
|
|||
}
|
||||
|
||||
func (e *engine) Update() error {
|
||||
var wg sync.WaitGroup
|
||||
eng := (*Engine)(e)
|
||||
|
||||
e.dt = time.Since(e.lastTime).Seconds()
|
||||
// Buffering the context for faster.
|
||||
c := &Context{Engine: eng, typ: updateContext}
|
||||
for object := range e.Objects.KeyChan() {
|
||||
updater, ok := object.(Updater)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
updater.Update(&Context{
|
||||
Engine: eng,
|
||||
})
|
||||
wg.Done()
|
||||
}()
|
||||
e.wg.Add(1)
|
||||
object.Input() <- c
|
||||
}
|
||||
wg.Wait()
|
||||
e.wg.Wait()
|
||||
|
||||
e.prevKeys = e.keys
|
||||
e.keys = inpututil.
|
||||
|
@ -289,22 +282,12 @@ func (e *engine) Update() error {
|
|||
// Providing the events to the objects.
|
||||
// Maybe should think of the better way,
|
||||
// but for it is simple enough.
|
||||
c = &Context{Engine: eng, typ: eventContext, events: events}
|
||||
for object := range e.Objects.KeyChan() {
|
||||
eventer, ok := object.(Eventer)
|
||||
if ok {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for _, event := range events {
|
||||
eventer.Event(&Context{
|
||||
Engine: eng,
|
||||
Event: event,
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
e.wg.Add(1)
|
||||
object.Input() <- c
|
||||
}
|
||||
wg.Wait()
|
||||
e.wg.Wait()
|
||||
|
||||
e.lastTime = time.Now()
|
||||
return nil
|
||||
|
@ -314,30 +297,27 @@ func (e *engine) Draw(i *ebiten.Image) {
|
|||
eng := (*Engine)(e)
|
||||
m := map[Layer][]Drawer{}
|
||||
for object := range eng.Objects.KeyChan() {
|
||||
drawer, ok := object.(Drawer)
|
||||
if !ok {
|
||||
// Skipping the ones we do not need to draw.
|
||||
if !object.IsVisible() {
|
||||
continue
|
||||
}
|
||||
|
||||
l := drawer.GetLayer()
|
||||
l := object.GetLayer()
|
||||
layer, ok := m[l]
|
||||
// Create new if has no the layer
|
||||
if !ok {
|
||||
m[l] = []Drawer{drawer}
|
||||
m[l] = []Drawer{object}
|
||||
continue
|
||||
}
|
||||
|
||||
m[l] = append(layer, drawer)
|
||||
m[l] = append(layer, object)
|
||||
}
|
||||
|
||||
// Drawing layers.
|
||||
layers := maps.NewSparse[Layer, []Drawer](nil, m)
|
||||
c := &Context{Engine: eng, typ: drawContext, Image: i}
|
||||
for layer := range layers.Chan() {
|
||||
for _, drawer := range layer {
|
||||
drawer.Draw(&Context{
|
||||
Engine: eng,
|
||||
Image: i,
|
||||
})
|
||||
drawer.Draw(c)
|
||||
}
|
||||
}
|
||||
// Empty the buff to generate it again.
|
||||
|
|
39
object.go
39
object.go
|
@ -1,11 +1,5 @@
|
|||
package gg
|
||||
|
||||
// Implementing the interface lets the object
|
||||
// to handle emited events.
|
||||
type Eventer interface {
|
||||
Event(*Context)
|
||||
}
|
||||
|
||||
// Implementing the interface type
|
||||
// will call the function OnStart
|
||||
// when first appear on scene BEFORE
|
||||
|
@ -22,6 +16,12 @@ type Updater interface {
|
|||
Update(*Context)
|
||||
}
|
||||
|
||||
// Implementing the interface lets the object
|
||||
// to handle emited events.
|
||||
type Eventer interface {
|
||||
Event(*Context)
|
||||
}
|
||||
|
||||
// Implementing the interface type
|
||||
// will call the function on deleting
|
||||
// the object.
|
||||
|
@ -51,6 +51,29 @@ type Drawer interface {
|
|||
IsVisible() bool
|
||||
}
|
||||
|
||||
// The type represents everything that can work inside engine.
|
||||
type Object any
|
||||
type Objecter interface {
|
||||
GetObject() *Object
|
||||
Input() chan *Context
|
||||
Starter
|
||||
Updater
|
||||
Eventer
|
||||
Drawer
|
||||
Deleter
|
||||
}
|
||||
|
||||
// The type for embedding into engine-in types.
|
||||
type Object struct {
|
||||
Layer
|
||||
Visibility
|
||||
input chan *Context
|
||||
}
|
||||
|
||||
func (o *Object) GetObject() *Object { return o }
|
||||
func (o *Object) Input() chan *Context { return o.input }
|
||||
|
||||
func (o *Object) Start(c *Context) {}
|
||||
func (o *Object) Update(c *Context) {}
|
||||
func (o *Object) Event(c *Context) {}
|
||||
func (o *Object) Draw(c *Context) {}
|
||||
func (o *Object) Delete(c *Context) {}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
// Grouped triangles type.
|
||||
type Polygon struct {
|
||||
Object
|
||||
Transform
|
||||
Triangles
|
||||
}
|
||||
|
|
1
rect.go
1
rect.go
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
// The type describes rectangle geometry.
|
||||
type Rectangle struct {
|
||||
Object
|
||||
Transform
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
)
|
||||
|
||||
type Sprite struct {
|
||||
Object
|
||||
Transform
|
||||
ShaderOptions
|
||||
Floating bool
|
||||
|
@ -52,7 +53,9 @@ func (s *Sprite) Rectangle() Rectangle {
|
|||
t.Around.X *= Float(w)
|
||||
t.Around.Y *= Float(h)
|
||||
|
||||
return Rectangle{t}
|
||||
return Rectangle{
|
||||
Transform: t,
|
||||
}
|
||||
}
|
||||
|
||||
// Get triangles of the rectangle that contains the sprite
|
||||
|
|
|
@ -92,7 +92,7 @@ func (v Vector) Norm() Vector {
|
|||
}
|
||||
|
||||
func (pts Points) Contained(c PointContainer) Points {
|
||||
ret := Points{}
|
||||
ret := make([]Point, 0, len(pts))
|
||||
|
||||
for _, pt := range pts {
|
||||
if c.ContainsPoint(pt) {
|
||||
|
|
Loading…
Reference in a new issue