Refactor asset management and event handling; enhance state management with middleware support and transaction capabilities
parent
6f602375d1
commit
7ed68c79c8
@ -1,5 +1,21 @@
|
||||
{
|
||||
"name": "I love X (default)",
|
||||
"assetsDir": "../assets/default",
|
||||
"tickRate": 2
|
||||
"theme": "default",
|
||||
"themeName": "I Love X",
|
||||
"assetsBasePath": "./assets/default/",
|
||||
"modules": [
|
||||
{"name": "intro", "configFile": "intro/config.json"},
|
||||
{"name": "finale", "configFile": "finale/config.json"}
|
||||
],
|
||||
"ui": {
|
||||
"colors": {
|
||||
"primary": "#FF0000",
|
||||
"secondary": "#00FF00",
|
||||
"background": "#000000",
|
||||
"text": "#FFFFFF"
|
||||
},
|
||||
"fonts": {
|
||||
"heading": "Arial",
|
||||
"body": "Arial"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,67 @@
|
||||
class EventBus {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
this.listeners = new Map();
|
||||
this.history = [];
|
||||
this.maxHistory = 100;
|
||||
}
|
||||
|
||||
on(event, callback) {
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
on(event, callback, context = null) {
|
||||
if (!this.listeners.has(event)) {
|
||||
this.listeners.set(event, []);
|
||||
}
|
||||
this.listeners[event].push(callback);
|
||||
this.listeners.get(event).push({ callback, context });
|
||||
return () => this.off(event, callback, context);
|
||||
}
|
||||
|
||||
emit(event, data) {
|
||||
if (this.listeners[event]) {
|
||||
this.listeners[event].forEach(cb => cb(data));
|
||||
once(event, callback, context = null) {
|
||||
const remove = this.on(event, (...args) => {
|
||||
remove();
|
||||
callback.apply(context, args);
|
||||
}, context);
|
||||
return remove;
|
||||
}
|
||||
|
||||
off(event, callback, context = null) {
|
||||
if (!this.listeners.has(event)) return;
|
||||
|
||||
const listeners = this.listeners.get(event);
|
||||
this.listeners.set(event, listeners.filter(listener =>
|
||||
listener.callback !== callback || listener.context !== context
|
||||
));
|
||||
}
|
||||
|
||||
emit(event, ...args) {
|
||||
this.logEvent(event, args);
|
||||
|
||||
if (this.listeners.has(event)) {
|
||||
this.listeners.get(event).forEach(listener => {
|
||||
try {
|
||||
listener.callback.apply(listener.context, args);
|
||||
} catch (error) {
|
||||
console.error(`Error in event listener for ${event}:`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
logEvent(event, args) {
|
||||
this.history.push({
|
||||
timestamp: Date.now(),
|
||||
event,
|
||||
args
|
||||
});
|
||||
|
||||
if (this.history.length > this.maxHistory) {
|
||||
this.history.shift();
|
||||
}
|
||||
}
|
||||
|
||||
getEventHistory() {
|
||||
return [...this.history];
|
||||
}
|
||||
|
||||
clearHistory() {
|
||||
this.history = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
class GameModule {
|
||||
constructor(engine, config) {
|
||||
this.engine = engine;
|
||||
this.config = config;
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
init() {
|
||||
console.log(`[${this.constructor.name}] Initializing...`);
|
||||
}
|
||||
|
||||
start() {
|
||||
console.log(`[${this.constructor.name}] Starting...`);
|
||||
this.isActive = true;
|
||||
}
|
||||
|
||||
pause() {
|
||||
console.log(`[${this.constructor.name}] Pausing...`);
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
resume() {
|
||||
console.log(`[${this.constructor.name}] Resuming...`);
|
||||
this.isActive = true;
|
||||
}
|
||||
|
||||
stop() {
|
||||
console.log(`[${this.constructor.name}] Stopping...`);
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
getScore() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.isActive) {
|
||||
// Module-specific update logic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GameModule;
|
@ -0,0 +1,96 @@
|
||||
class StateManager {
|
||||
constructor(eventBus) {
|
||||
this.eventBus = eventBus;
|
||||
this.state = new Map();
|
||||
this.history = [];
|
||||
this.maxHistory = 100;
|
||||
this.middleware = [];
|
||||
}
|
||||
|
||||
// State getters en setters met middleware support
|
||||
get(key) {
|
||||
return this.state.get(key);
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
const oldValue = this.state.get(key);
|
||||
|
||||
// Run middleware
|
||||
const middlewareChain = Promise.resolve({ key, value, oldValue })
|
||||
.then(context =>
|
||||
this.middleware.reduce(
|
||||
(promise, middleware) => promise.then(middleware),
|
||||
Promise.resolve(context)
|
||||
)
|
||||
);
|
||||
|
||||
middlewareChain
|
||||
.then(context => {
|
||||
this.state.set(context.key, context.value);
|
||||
this.logStateChange(context.key, context.oldValue, context.value);
|
||||
this.eventBus.emit('state:changed', {
|
||||
key: context.key,
|
||||
oldValue: context.oldValue,
|
||||
newValue: context.value
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('State update failed:', error);
|
||||
this.eventBus.emit('state:error', { key, error });
|
||||
});
|
||||
}
|
||||
|
||||
// Middleware toevoegen voor state manipulatie
|
||||
addMiddleware(middleware) {
|
||||
this.middleware.push(middleware);
|
||||
}
|
||||
|
||||
// State geschiedenis
|
||||
logStateChange(key, oldValue, newValue) {
|
||||
this.history.push({
|
||||
timestamp: Date.now(),
|
||||
key,
|
||||
oldValue,
|
||||
newValue
|
||||
});
|
||||
|
||||
if (this.history.length > this.maxHistory) {
|
||||
this.history.shift();
|
||||
}
|
||||
}
|
||||
|
||||
getHistory() {
|
||||
return [...this.history];
|
||||
}
|
||||
|
||||
// Snapshot en herstel functionaliteit
|
||||
createSnapshot() {
|
||||
return {
|
||||
timestamp: Date.now(),
|
||||
state: new Map(this.state)
|
||||
};
|
||||
}
|
||||
|
||||
restoreSnapshot(snapshot) {
|
||||
this.state = new Map(snapshot.state);
|
||||
this.eventBus.emit('state:restored', snapshot);
|
||||
}
|
||||
|
||||
// Bulk updates met transactie support
|
||||
transaction(updates) {
|
||||
const snapshot = this.createSnapshot();
|
||||
|
||||
try {
|
||||
updates.forEach(({ key, value }) => {
|
||||
this.set(key, value);
|
||||
});
|
||||
this.eventBus.emit('transaction:complete', updates);
|
||||
} catch (error) {
|
||||
this.restoreSnapshot(snapshot);
|
||||
this.eventBus.emit('transaction:failed', { error, updates });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StateManager;
|
@ -1,23 +1,37 @@
|
||||
class IntroScreen {
|
||||
constructor(engine) {
|
||||
this.engine = engine;
|
||||
const GameModule = require('../../core/game-module');
|
||||
|
||||
class IntroModule extends GameModule {
|
||||
constructor(engine, config) {
|
||||
super(engine, config);
|
||||
this.state = 'welcome';
|
||||
}
|
||||
|
||||
init() {
|
||||
// Intro screen is now handled by renderer process (HTML/CSS)
|
||||
super.init();
|
||||
this.engine.events.emit('intro:ready');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init(engine) {
|
||||
console.log('[module:intro] Initializing...');
|
||||
const intro = new IntroScreen(engine);
|
||||
intro.init();
|
||||
start() {
|
||||
super.start();
|
||||
console.log('Welkom bij', this.config.themeName);
|
||||
|
||||
engine.events.on('intro:complete', () => {
|
||||
console.log('[module:intro] Complete');
|
||||
});
|
||||
// Start intro sequence
|
||||
setTimeout(() => {
|
||||
this.state = 'ready';
|
||||
this.engine.events.emit('intro:ready_for_input');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
handleInput(key) {
|
||||
if (this.state === 'ready' && key === 'Space') {
|
||||
this.complete();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
complete() {
|
||||
this.stop();
|
||||
this.engine.events.emit('intro:complete');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IntroModule;
|
||||
|
Loading…
Reference in new issue