model

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 30, 2024 License: MIT Imports: 6 Imported by: 12

Documentation

Overview

Package model provides a wrapper around the Arche ECS world that helps with rapid prototyping and model development.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
)

func main() {
	// Create a new, seeded model.
	m := model.New().Seed(123)

	// Add systems.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	// Run the simulation.
	m.Run()
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Model

type Model struct {
	Systems           // Systems manager and scheduler
	World   ecs.World // The ECS world
	// contains filtered or unexported fields
}

Model is the top-level ECS entrypoint.

Model provides access to the ECS world, and manages the scheduling of System and UISystem instances via Systems. System instances are updated with a frequency given by TPS. UISystem instances are updated independently of normal systems, with a frequency given by FPS.

The Systems scheduler, the model's resource.Tick, resource.Termination and a central resource.Rand PRNG source can be accessed by systems as resources.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
)

func main() {
	// Create a new, seeded model.
	m := model.New().Seed(123)

	// Add systems.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	// Run the simulation.
	m.Run()
}
Output:

Example (ManualUpdate)
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
)

func main() {
	// Create a new, seeded model.
	m := model.New().Seed(123)

	// Add systems.
	m.AddSystem(&system.FixedTermination{
		Steps: 100,
	})

	// Run the simulation manually.
	m.Initialize()
	for m.Update() {
		m.UpdateUI()
	}
	m.Finalize()
}
Output:

func New

func New(config ...ecs.Config) *Model

New creates a new model.

func (*Model) Finalize added in v0.7.0

func (m *Model) Finalize()

Finalize the model.

func (*Model) Initialize added in v0.7.0

func (m *Model) Initialize()

Initialize the model.

func (*Model) Reset

func (m *Model) Reset()

Reset resets the world and removes all systems.

Can be used to run systematic simulations without the need to re-allocate memory for each run. Accelerates re-populating the world by a factor of 2-3.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
)

func main() {
	// Create a new model.
	m := model.New()

	// Do many model runs.
	for i := 0; i < 10; i++ {
		// Reset the model to clear entities, systems etc. before the run.
		m.Reset()

		// Seed the model for the run.
		m.Seed(uint64(i))

		// Add systems.
		m.AddSystem(&system.FixedTermination{
			Steps: 100,
		})

		// Run the simulation.
		m.Run()

	}
}
Output:

func (*Model) Run

func (m *Model) Run()

Run the model, updating systems and ui systems according to Model.TPS and Model.FPS, respectively. Initializes the model if it is not already initialized. Finalizes the model after the run.

Runs until Terminate in the resource resource.Termination is set to true (see resource.Termination).

To perform updates manually, see Model.Update and Model.UpdateUI, as well as Model.Initialize and Model.Finalize.

func (*Model) Seed

func (m *Model) Seed(seed ...uint64) *Model

Seed sets the random seed of the model's resource.Rand. Call without an argument to seed from the current time.

Systems should always use the Rand resource for PRNGs.

func (*Model) Update added in v0.7.0

func (m *Model) Update() bool

Update the model's systems. Return whether the run should continue.

Ignores Model.TPS.

Panics if Model.Initialize was not called.

func (*Model) UpdateUI added in v0.7.0

func (m *Model) UpdateUI()

UpdateUI the model's UI systems.

Ignores Model.FPS.

Panics if Model.Initialize was not called.

type System

type System interface {
	Initialize(w *ecs.World) // Initialize the system.
	Update(w *ecs.World)     // Update the system.
	Finalize(w *ecs.World)   // Finalize the system.
}

System is the interface for ECS systems.

See also UISystem for systems with an independent graphics step.

Example
package main

import (
	"fmt"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/resource"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche/ecs"
	"github.com/mlange-42/arche/generic"
)

// TestSystem is an example for implementing [System].
type TestSystem struct {
	timeRes generic.Resource[resource.Tick]
}

// Initialize the system.
func (s *TestSystem) Initialize(w *ecs.World) {
	s.timeRes = generic.NewResource[resource.Tick](w)
}

// Update the system.
func (s *TestSystem) Update(w *ecs.World) {
	time := s.timeRes.Get()
	fmt.Println(time.Tick)
}

// Finalize the system.
func (s *TestSystem) Finalize(w *ecs.World) {}

func main() {
	// Create a new model.
	m := model.New()

	// Add the test system.
	m.AddSystem(&TestSystem{})

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{Steps: 30})

	// Run the simulation.
	m.Run()
}
Output:

type Systems

type Systems struct {
	// Ticks per second for normal systems.
	// Values <= 0 (the default) mean as fast as possible.
	TPS float64
	// Frames per second for UI systems.
	// A zero/unset value defaults to 30 FPS. Values < 0 sync FPS with TPS.
	// With fast movement, a value of 60 may be required for fluent graphics.
	FPS float64
	// Whether the simulation is currently paused.
	// When paused, only UI updates but no normal updates are performed.
	Paused bool
	// contains filtered or unexported fields
}

Systems manages and schedules ECS System and UISystem instances.

System instances are updated with a frequency given by TPS (ticks per second). UISystem instances are updated independently of normal systems, with a frequency given by FPS (frames per second).

Systems is an embed in Model and it's methods are usually only used through a Model instance. By also being a resource of each Model, however, systems can access it and e.g. remove themselves from a model.

Example
package main

import (
	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche/ecs"
)

func main() {
	// Create a new model.
	m := model.New()

	// The model contains Systems as an embed, TPS and FPS are accessible through the model directly.
	m.TPS = 1000
	m.FPS = 60

	// Create a system
	sys := system.FixedTermination{
		Steps: 10,
	}

	// Add the system the usual way, through the model.
	// The model contains Systems as an embed, so actually [Systems.AddSystem] is called.
	m.AddSystem(&sys)

	// Inside systems, [Systems] can be accessed as a resource.
	systems := ecs.GetResource[model.Systems](&m.World)

	// Pause the simulation, e.g. based on user input.
	systems.Paused = true

	// Remove the system using the resource.
	systems.RemoveSystem(&sys)
}
Output:

func (*Systems) AddSystem

func (s *Systems) AddSystem(sys System)

AddSystem adds a System to the model.

Panics if the system is also a UISystem. To add systems that implement both System and UISystem, use Systems.AddUISystem

func (*Systems) AddUISystem

func (s *Systems) AddUISystem(sys UISystem)

AddUISystem adds an UISystem to the model.

Adds the UISystem also as a normal System if it implements the interface.

func (*Systems) RemoveSystem

func (s *Systems) RemoveSystem(sys System)

RemoveSystem removes a system from the model.

Systems can also be removed during a model run. However, this will take effect only after the end of the full model step.

func (*Systems) RemoveUISystem

func (s *Systems) RemoveUISystem(sys UISystem)

RemoveUISystem removes an UI system from the model.

Systems can also be removed during a model run. However, this will take effect only after the end of the full model step.

func (*Systems) Systems added in v0.4.0

func (s *Systems) Systems() []System

Systems returns the normal/non-UI systems.

func (*Systems) UISystems added in v0.4.0

func (s *Systems) UISystems() []UISystem

UISystems returns the UI systems.

type UISystem

type UISystem interface {
	InitializeUI(w *ecs.World) // InitializeUI the system.
	UpdateUI(w *ecs.World)     // UpdateUI/update the system.
	PostUpdateUI(w *ecs.World) // PostUpdateUI does the final part of updating, e.g. update the GL window.
	FinalizeUI(w *ecs.World)   // FinalizeUI the system.
}

UISystem is the interface for ECS systems that display UI in an independent graphics step.

See also System for normal systems.

Example
package main

import (
	"fmt"

	"github.com/mlange-42/arche-model/model"
	"github.com/mlange-42/arche-model/resource"
	"github.com/mlange-42/arche-model/system"
	"github.com/mlange-42/arche/ecs"
	"github.com/mlange-42/arche/generic"
)

// TestUISystem is an example for implementing [UISystem].
type TestUISystem struct {
	timeRes generic.Resource[resource.Tick]
}

// Initialize the system.
func (s *TestUISystem) InitializeUI(w *ecs.World) {
	s.timeRes = generic.NewResource[resource.Tick](w)
}

// Update the system.
func (s *TestUISystem) UpdateUI(w *ecs.World) {
	time := s.timeRes.Get()
	fmt.Println(time.Tick)
}

// PostUpdate the system.
func (s *TestUISystem) PostUpdateUI(w *ecs.World) {}

// Finalize the system.
func (s *TestUISystem) FinalizeUI(w *ecs.World) {}

func main() {
	// Create a new model.
	m := model.New()

	// Add the test ui system.
	m.AddUISystem(&TestUISystem{})

	// Add a termination system that ends the simulation.
	m.AddSystem(&system.FixedTermination{Steps: 30})

	// Run the simulation.
	m.Run()
}
Output:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL