Package-level declarations

Overview

This package contains reusable utilities that support configuration handling, logging, and audio management. The central feature is a ConfigLoader class that automates the creation and loading of configuration files in .properties format, allowing each subsystem to define its own configuration model by implementing the Config interface. This ensures that each module can provide default configuration values while still allowing users to override them through editable files.

Key Components

  • ConfigLoader<U : Config> — Generic configuration loader

    • Reads a properties file from a provided path.

    • If the file does not exist, creates the directory/file; writes default entries obtained from factory(emptyMap()).getDefaultConfigFileEntries() and stores the file.

    • Converts the loaded properties to Map<String, String> and invokes factory(configMap) to build the concrete configuration.

  • Config — Interface for configuration implementations

    • Contract that requires exposing getDefaultConfigFileEntries(): Map<String, String> with the default values to write when the file does not exist.

  • Environment — Centralized constants

    • Defines constants: CONFIG_FOLDER, CORE_CONFIG_FILE, CLI_CONFIG_FILE, APP_CONFIG_FILE. The default directory is config and the default files are reversi-core.properties, reversi-cli.properties, and reversi-app.properties.

  • PlainFormatter — Log message formatter for clean, readable console output

  • StdOutConsoleHandler — Console handler that writes to standard output

  • Tracker — Tracking and analytics utilities for monitoring application behavior

  • Utils — General utility functions and extension methods

Responsibilities

  • Provide a simple and consistent mechanism to load/manage configuration files.

  • Ensure missing configuration files are created with default entries.

  • Expose reusable environment constants for other modules to locate configuration files.

  • Provide logging infrastructure with customizable formatters and handlers.

  • Supply utility functions used across multiple modules.

  • Manage audio playback and sound effects.

Notes

  • Modules such as reversi-core, reversi-cli, and reversi-app should provide an implementation of Config and pass a factory to ConfigLoader.

  • The default configuration file is plain text in Java Properties format, as this facilitates manual editing and debugging.

Types

Link copied to clipboard
interface Config

Contract for configuration objects that provide key-value configuration properties.

Link copied to clipboard
class ConfigLoader<U : Config>(val path: String, val factory: (Map<String, String>) -> U)

Loads and manages configuration from Java properties files.

Link copied to clipboard
class DevTracker(var config: TrackerConfig = TrackerConfig())

Development tracker for monitoring application behavior.

Link copied to clipboard

Export format options for tracking data.

Link copied to clipboard

A plain formatter for logging that outputs the log level, source method name, and message.

Link copied to clipboard

Custom logging handler that outputs formatted log records to standard output with ANSI color codes. Different log levels are displayed in different colors for better readability.

Link copied to clipboard
data class TrackerConfig(val enabled: Boolean = true, val maxEventsPerContext: Int = 1000, val autoSave: Boolean = false, val stackTraceDepth: Int = 4)

Configuration for the DevTracker.

Link copied to clipboard
data class TrackingEvent(val timestamp: LocalDateTime, val type: TrackingType, val context: String, val category: Any? = null, val details: String = "", val threadId: Long = Thread.currentThread().threadId())

Data class representing a single tracking event.

Link copied to clipboard
data class TrackingStats(val context: String, val eventCount: AtomicInteger = AtomicInteger(0), val pageEnters: AtomicInteger = AtomicInteger(0), val viewModelCreations: AtomicInteger = AtomicInteger(0), val classCreations: AtomicInteger = AtomicInteger(0), val recompositions: AtomicInteger = AtomicInteger(0), val functionCalls: AtomicInteger = AtomicInteger(0), val effectStarts: AtomicInteger = AtomicInteger(0), val effectStops: AtomicInteger = AtomicInteger(0), var firstOccurrence: LocalDateTime? = null, var lastOccurrence: LocalDateTime? = null)

Data class representing statistics for a specific tracked context.

Link copied to clipboard

Enum representing the types of tracking events that can be recorded.

Properties

Link copied to clipboard
const val BASE_FOLDER: String

Base data directory for configuration and logs.

Link copied to clipboard

CLI module configuration file path (reversi-cli.properties).

Link copied to clipboard

Configuration directory path containing all application configuration files.

Link copied to clipboard

Core module configuration file path (reversi-core.properties).

Link copied to clipboard

Global logger instance configured with console handler and plain formatter.

Link copied to clipboard

Per-run logs folder derived from current date (e.g., data/logs/log-YYYY-MM-DD-N).

Link copied to clipboard

Global development tracker instance for monitoring application behavior.

Functions

Link copied to clipboard
internal fun buildOrigin(className: String?, methodName: String?): String
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
private fun listResourceFiles(path: String): List<String>

Lists all files in a resource directory, works both in IDE and JAR.

Link copied to clipboard

Loads a resource file from the classpath. Only use this if you really need a File object. For most cases, use getResource() directly.

Link copied to clipboard
fun <T> loadResourcesFromFolder(folder: String, transform: (fileName: String, url: URL) -> T?): List<T>

Generic function to load resources from a folder and transform them. Handles both IDE and JAR execution transparently.

Link copied to clipboard
fun makePathString(vararg parts: String): String

Makes a path string by joining the given parts with the base game folder.

Link copied to clipboard

Sets the logger to log to a file with a name based on the current date. If a file with the same name already exists, a counter is added to the name.