Update Database

Database is more usable now.
All pages have been updated to use the database, and share an application configuration.
Page Stack has been removed, no more pages hanging around in memory. Replaced with a 'Router' which uses an Enum to determine which page should be displayed, destroys the old page and initializes the new page all in one go. No more push, pop, rollback, etc. No more holding instances of pages.
Logger has been updated with proper timestamps and sorting now works as expected."
This commit is contained in:
NeilClack
2026-03-23 15:02:07 -05:00
parent f8fbfb721d
commit 17c088cc2f
28 changed files with 537 additions and 2276 deletions
+23 -30
View File
@@ -4,7 +4,6 @@ package mixer
import (
"errors"
"fmt"
"strconv"
"sync"
"github.com/veandco/go-sdl2/mix"
@@ -30,16 +29,20 @@ var (
defaultChannels = 2
defaultChunkSize = 1024
defaultAllow = sdl.AUDIO_ALLOW_ANY_CHANGE
refreshCacheCallback func()
)
// Init initializes SDL audio + SDL_mixer. Safe to call multiple times.
func Init(wantedDevice string) error {
func Init(cfg *db.AppConfig, onUpdate func()) error {
mu.Lock()
defer mu.Unlock()
if inited {
return nil
}
refreshCacheCallback = onUpdate
// Let SDL choose the best audio driver for the system
// Remove hardcoded ALSA preference to support PulseAudio, PipeWire, etc.
// Users can set SDL_AUDIODRIVER environment variable if needed
@@ -49,31 +52,21 @@ func Init(wantedDevice string) error {
}
// WAV-only does not require mix.Init(); add when you support OGG/MP3/etc.
if err := openDeviceLocked(wantedDevice); err != nil {
if err := openDeviceLocked(cfg.SelectedAudioDevice); err != nil {
// Clean up the subsystem on failure so callers can retry later.
sdl.QuitSubSystem(sdl.INIT_AUDIO)
return err
}
// Check if the volume is stored in the config; if not, default to max.
storedVolume, err := db.GetConfigValue("last_volume")
if err != nil {
return fmt.Errorf("retrieving last_volume from config: %w", err)
}
lastVolume, err := strconv.Atoi(storedVolume)
if err != nil {
return fmt.Errorf("parsing last_volume %q: %w", storedVolume, err)
}
if lastVolume < 0 {
lastVolume = int(mix.MAX_VOLUME)
currentVolume = lastVolume
if err := db.SetConfigValue("last_volume", strconv.Itoa(lastVolume)); err != nil {
}
} else {
currentVolume = lastVolume
}
// TODO: Check if this logic is still needed; move to application
// if lastVolume < 0 {
// lastVolume = int(mix.MAX_VOLUME)
// currentVolume = lastVolume
// if err := db.SetConfigValue("last_volume", strconv.Itoa(lastVolume)); err != nil {
// }
// } else {
// currentVolume = lastVolume
// }
// mix.VolumeMusic(currentVolume)
@@ -107,8 +100,8 @@ func openDeviceLocked(name string) error {
// Play loads a WAV (as music) and plays it. If loopForever is true, loops forever.
// If something is already playing, it stops and replaces it.
func Play(path string, loopForever bool) error {
if !db.AudioEnabled() {
func Play(path string, loopForever bool, cfg *db.AppConfig) error {
if !cfg.AudioEnabled {
return nil
}
@@ -159,8 +152,8 @@ func Play(path string, loopForever bool) error {
// Stop stops playback. If fadeMs > 0, fades out asynchronously; otherwise halts immediately.
// It also frees the currently loaded music (so a new Play will reload).
func Stop(fadeMs int) {
if !db.AudioEnabled() {
func Stop(fadeMs int, cfg *db.AppConfig) {
if !cfg.AudioEnabled {
return
}
@@ -184,8 +177,8 @@ func Stop(fadeMs int) {
}
// SetVolume128 sets music volume using SDL_mixer’s 0..128 scale.
func SetVolume128(increment int) {
if !db.AudioEnabled() {
func SetVolume128(increment int, cfg *db.AppConfig) {
if !cfg.AudioEnabled {
return
}
@@ -201,8 +194,8 @@ func SetVolume128(increment int) {
}
// Store in config
if err := db.SetConfigValue("last_volume", strconv.Itoa(currentVolume)); err != nil {
}
cfg.LastVolume = currentVolume
refreshCacheCallback()
// Apply to SDL_mixer
if inited && deviceOpen {