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