175 lines
3.6 KiB
Swift
175 lines
3.6 KiB
Swift
import CSDL2
|
|
import FirebladeECS
|
|
|
|
if SDL_Init(SDL_INIT_VIDEO) != 0 {
|
|
fatalError("could not init video")
|
|
}
|
|
let width: Int32 = 640
|
|
let height: Int32 = 480
|
|
let hWin = SDL_CreateWindow("Fireblade ECS demo", 100, 100, width, height, SDL_WINDOW_SHOWN.rawValue)
|
|
if hWin == nil {
|
|
SDL_Quit()
|
|
fatalError("could not crate window")
|
|
}
|
|
|
|
func randNorm() -> Double {
|
|
return Double(arc4random()) / Double(UInt32.max)
|
|
}
|
|
|
|
// won't produce pure black
|
|
func randColor() -> UInt8 {
|
|
return UInt8(randNorm() * 254) + 1
|
|
}
|
|
|
|
let nexus = Nexus()
|
|
|
|
class Position: Component {
|
|
var x: Int32 = width/2
|
|
var y: Int32 = height/2
|
|
}
|
|
class Color: Component {
|
|
var r: UInt8 = randColor()
|
|
var g: UInt8 = randColor()
|
|
var b: UInt8 = randColor()
|
|
}
|
|
|
|
func createScene() {
|
|
|
|
let numEntities: Int = 10_000
|
|
|
|
for i in 0..<numEntities {
|
|
let e = nexus.create(entity: "\(i)")
|
|
e.assign(Position())
|
|
e.assign(Color())
|
|
}
|
|
}
|
|
|
|
class PositionSystem {
|
|
let family = nexus.family(requiresAll: [Position.self], excludesAll: [])
|
|
var acceleration: Double = 4.0
|
|
func update() {
|
|
family.iterate(components: Position.self) { [unowned self](_, pos) in
|
|
|
|
let deltaX: Double = self.acceleration*((randNorm() * 2) - 1)
|
|
let deltaY: Double = self.acceleration*((randNorm() * 2) - 1)
|
|
var x = pos!.x + Int32(deltaX)
|
|
var y = pos!.y + Int32(deltaY)
|
|
|
|
if x < 0 || x > width {
|
|
x = -x
|
|
}
|
|
if y < 0 || y > height {
|
|
y = -y
|
|
}
|
|
|
|
pos!.x = x
|
|
pos!.y = y
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class PositionResetSystem {
|
|
let family = nexus.family(requiresAll: [Position.self], excludesAll: [])
|
|
|
|
func update() {
|
|
family.iterate(components: Position.self) { (_, pos) in
|
|
pos!.x = width/2
|
|
pos!.y = height/2
|
|
}
|
|
}
|
|
}
|
|
|
|
class ColorSystem {
|
|
let family = nexus.family(requiresAll: [Color.self], excludesAll: [])
|
|
|
|
func update() {
|
|
family.iterate(components: Color.self) { (_, color) in
|
|
|
|
color!.r = randColor()
|
|
color!.g = randColor()
|
|
color!.b = randColor()
|
|
}
|
|
}
|
|
}
|
|
|
|
class RenderSystem {
|
|
let hRenderer: OpaquePointer?
|
|
let family = nexus.family(requiresAll: [Position.self, Color.self], excludesAll: [])
|
|
|
|
init(hWin: OpaquePointer?) {
|
|
hRenderer = SDL_CreateRenderer(hWin, -1, SDL_RENDERER_ACCELERATED.rawValue)
|
|
if hRenderer == nil {
|
|
SDL_DestroyWindow(hWin)
|
|
SDL_Quit()
|
|
fatalError("could not create renderer")
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
SDL_DestroyRenderer(hRenderer)
|
|
}
|
|
|
|
func render() {
|
|
|
|
SDL_SetRenderDrawColor( hRenderer, 0, 0, 0, 255 ) // black
|
|
SDL_RenderClear(hRenderer) // clear screen
|
|
|
|
family.iterate(components: Position.self, Color.self) { [unowned self] (_, pos, color) in
|
|
var rect = SDL_Rect(x: pos!.x, y: pos!.y, w: 2, h: 2)
|
|
|
|
SDL_SetRenderDrawColor(self.hRenderer, color!.r, color!.g, color!.b, 255)
|
|
SDL_RenderFillRect(self.hRenderer, &rect)
|
|
}
|
|
|
|
SDL_RenderPresent(hRenderer)
|
|
}
|
|
}
|
|
let positionSystem = PositionSystem()
|
|
let positionResetSystem = PositionResetSystem()
|
|
let renderSystem = RenderSystem(hWin: hWin)
|
|
let colorSystem = ColorSystem()
|
|
|
|
createScene()
|
|
|
|
var event: SDL_Event = SDL_Event()
|
|
var quit: Bool = false
|
|
while quit == false {
|
|
while SDL_PollEvent(&event) == 1 {
|
|
switch SDL_EventType(rawValue: event.type) {
|
|
case SDL_QUIT:
|
|
quit = true
|
|
break
|
|
case SDL_KEYDOWN:
|
|
switch Int(event.key.keysym.sym) {
|
|
case SDLK_ESCAPE:
|
|
quit = true
|
|
break
|
|
case SDLK_c:
|
|
colorSystem.update()
|
|
case SDLK_r:
|
|
positionResetSystem.update()
|
|
case SDLK_s:
|
|
positionSystem.acceleration = 0.0
|
|
case SDLK_PLUS:
|
|
positionSystem.acceleration += 0.1
|
|
case SDLK_MINUS:
|
|
positionSystem.acceleration -= 0.1
|
|
case SDLK_SPACE:
|
|
positionSystem.acceleration = 4.0
|
|
default:
|
|
break
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
positionSystem.update()
|
|
|
|
renderSystem.render()
|
|
}
|
|
|
|
SDL_DestroyWindow(hWin)
|
|
SDL_Quit()
|