-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.go
110 lines (88 loc) · 2.37 KB
/
controller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package game
import (
"time"
"github.com/mokiat/lacking/app"
"github.com/mokiat/lacking/debug/metric"
"github.com/mokiat/lacking/game/asset"
"github.com/mokiat/lacking/game/ecs"
"github.com/mokiat/lacking/game/graphics"
"github.com/mokiat/lacking/game/physics"
"github.com/mokiat/lacking/util/async"
)
func NewController(registry asset.Registry, shaders graphics.ShaderCollection) *Controller {
return &Controller{
registry: registry,
shaders: shaders,
}
}
var _ app.Controller = (*Controller)(nil)
type Controller struct {
app.NopController
registry asset.Registry
shaders graphics.ShaderCollection
gfxEngine *graphics.Engine
ecsEngine *ecs.Engine
physicsEngine *physics.Engine
window app.Window
ioWorker *async.Worker
engine *Engine
viewport graphics.Viewport
}
func (c *Controller) Engine() *Engine {
return c.engine
}
func (c *Controller) OnCreate(window app.Window) {
c.window = window
c.gfxEngine = graphics.NewEngine(window.RenderAPI(), c.shaders)
c.ecsEngine = ecs.NewEngine()
c.physicsEngine = physics.NewEngine(16 * time.Millisecond)
c.ioWorker = async.NewWorker(16)
go c.ioWorker.ProcessAll()
c.engine = NewEngine(
WithGFXWorker(c.gfxWorkerAdapter()),
WithIOWorker(c.ioWorkerAdapter()),
WithRegistry(c.registry),
WithGraphics(c.gfxEngine),
WithECS(c.ecsEngine),
WithPhysics(c.physicsEngine),
)
c.engine.Create()
width, height := window.Size()
c.OnResize(window, width, height)
}
func (c *Controller) OnDestroy(window app.Window) {
c.engine.Destroy()
c.ioWorker.Shutdown()
}
func (c *Controller) OnFramebufferResize(window app.Window, width, height int) {
c.viewport = graphics.NewViewport(0, 0, width, height)
}
func (c *Controller) OnRender(window app.Window) {
defer metric.BeginRegion("game").End()
c.engine.Update()
c.engine.Render(c.viewport)
window.Invalidate() // force redraw
}
func (c *Controller) schedule(fn func()) {
c.window.Schedule(fn)
}
func (c *Controller) gfxWorkerAdapter() Worker {
return WorkerFunc(func(fn func() error) Operation {
operation := NewOperation()
c.schedule(func() {
operation.Complete(fn())
})
return operation
})
}
func (c *Controller) ioWorkerAdapter() Worker {
return WorkerFunc(func(fn func() error) Operation {
operation := NewOperation()
c.ioWorker.Schedule(func() error {
err := fn()
operation.Complete(err)
return err
})
return operation
})
}