refactor: remove cached AppConfig pointer and read configuration directly from DB
Replace in-memory atomic AppConfig caching with direct DB queries via db.GetConfig across application and page layers. This simplifies state management and ensures all components always operate on the latest persisted configuration. Key changes: - Remove Application.Config atomic cache and refreshCache mechanism - Eliminate PageCtx.CfgPtr and pass DB handle instead - Replace all cfg reads with db.GetConfig(app.DB) - Update mixer, audio, UI pages, and initialization paths accordingly - Explicitly set AppConfig table name to avoid GORM pluralization issues - Reduce DB connection pooling (SetMaxIdleConns(1)) - Standardize application font to SpaceMonoNerdFont-Regular - Lower default audio volume (1.0 → 0.2) - Add Unicode checkmark glyph to font map Behavioral impact: - Configuration is no longer cached in memory - Every config access now hits the DB (more consistent, slightly more overhead)
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
@@ -51,7 +50,6 @@ type Application struct {
|
||||
pendingAction func()
|
||||
running bool
|
||||
DB *gorm.DB
|
||||
Config atomic.Pointer[db.AppConfig]
|
||||
PageRouter *page.Router
|
||||
state State
|
||||
}
|
||||
@@ -112,7 +110,7 @@ func Run() {
|
||||
|
||||
// Populate the initial Config cache OR create defaults
|
||||
firstRun := false
|
||||
result = DB.First(&initialConfig)
|
||||
result = DB.Unscoped().First(&initialConfig)
|
||||
if result.Error != nil {
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
logger.Info("First run detected: Creating default configuration...")
|
||||
@@ -148,8 +146,6 @@ func Run() {
|
||||
app.state = FIRST_RUN
|
||||
}
|
||||
|
||||
app.refreshCache()
|
||||
|
||||
w, h := app.initializeSDLAndOpenGL()
|
||||
defer app.cleanup()
|
||||
|
||||
@@ -159,12 +155,10 @@ func Run() {
|
||||
downloadProgressChan := make(chan download.DownloadStatus, 1000)
|
||||
|
||||
app.PageRouter = page.NewRouter(page.PageCtx{
|
||||
CfgPtr: app.Config.Load(),
|
||||
DbPtr: app.DB,
|
||||
W: w,
|
||||
H: h,
|
||||
MessageChannel: downloadProgressChan,
|
||||
RefreshConfig: app.refreshCache,
|
||||
})
|
||||
|
||||
// Sync the proclamations from the API to the Database
|
||||
@@ -188,7 +182,12 @@ func Run() {
|
||||
"PinealGland.wav",
|
||||
}
|
||||
|
||||
go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(app.PageRouter.Context.CfgPtr.AssetsDir, "audio"))
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(config.AssetsDir, "audio"))
|
||||
|
||||
app.runEventLoop()
|
||||
}
|
||||
@@ -221,7 +220,12 @@ func (app *Application) checkState() {
|
||||
}
|
||||
|
||||
// Then check for an email address
|
||||
if app.Config.Load().EmailAddress == "" {
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if config.EmailAddress == "" {
|
||||
if app.state != NEEDS_EMAIL_ADDRESS {
|
||||
app.PageRouter.NavigateTo(page.EMAIL_ADDRESS)
|
||||
app.state = NEEDS_EMAIL_ADDRESS
|
||||
@@ -230,7 +234,11 @@ func (app *Application) checkState() {
|
||||
}
|
||||
|
||||
// Then check for a license key
|
||||
if app.Config.Load().LicenseKey == "" {
|
||||
config, err = db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if config.LicenseKey == "" {
|
||||
if app.state != NEEDS_LICENSE_KEY {
|
||||
app.PageRouter.NavigateTo(page.LICENSE_KEY)
|
||||
app.state = NEEDS_LICENSE_KEY
|
||||
@@ -242,14 +250,6 @@ func (app *Application) checkState() {
|
||||
app.PageRouter.NavigateTo(page.HOME)
|
||||
}
|
||||
|
||||
func (app *Application) refreshCache() {
|
||||
var freshConfig db.AppConfig
|
||||
if result := app.DB.First(&freshConfig); result.Error != nil {
|
||||
logger.Error("failed to fetch configuration from the database: %v", result.Error)
|
||||
}
|
||||
app.Config.Store(&freshConfig)
|
||||
}
|
||||
|
||||
func (app *Application) initializeSDLAndOpenGL() (W, H int32) {
|
||||
logger.Info("Initializing SDL")
|
||||
if err := sdl.Init(sdl.INIT_VIDEO | sdl.INIT_AUDIO); err != nil {
|
||||
@@ -324,29 +324,38 @@ func (app *Application) initializeSDLAndOpenGL() (W, H int32) {
|
||||
|
||||
func (app *Application) initializeManagers() {
|
||||
logger.Info("Initializing ShaderManager")
|
||||
shaderDir := filepath.Join(app.Config.Load().AssetsDir, "shaders")
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
shaderDir := filepath.Join(config.AssetsDir, "shaders")
|
||||
logger.Info("Loading shaders from %s", shaderDir)
|
||||
if err := shaderManager.InitShaderManager(shaderDir); err != nil {
|
||||
logger.Fatal("ShaderManager initialization failed: %v", err)
|
||||
}
|
||||
|
||||
logger.Info("Initializing FontManager")
|
||||
if err := fontManager.InitFontManager(app.Config.Load()); err != nil {
|
||||
if err := fontManager.InitFontManager(config); err != nil {
|
||||
logger.Fatal("FontManager initialization failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *Application) initializeAudio() {
|
||||
logger.Info("Initializing audio")
|
||||
|
||||
if err := mixer.Init(app.Config.Load(), app.refreshCache); err != nil {
|
||||
logger.Error("Unable to initialize audio device '%s': %v", app.Config.Load().SelectedAudioDevice, err)
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := mixer.Init(config, app.refreshCache); err != nil {
|
||||
logger.Error("Unable to initialize audio device '%s': %v", config.SelectedAudioDevice, err)
|
||||
logger.Error("Audio will be unavailable until a device is configured")
|
||||
} else {
|
||||
logger.Info("Audio initialized with device: '%s'", app.Config.Load().SelectedAudioDevice)
|
||||
logger.Info("Audio initialized with device: '%s'", config.SelectedAudioDevice)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *Application) refreshCache() {}
|
||||
|
||||
func (app *Application) cleanup() {
|
||||
logger.Info("Cleaning up")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user