first commit

This commit is contained in:
2025-07-05 02:34:28 +02:00
commit 423b02a195
11 changed files with 2240 additions and 0 deletions

156
src/Storage.ts Normal file
View File

@ -0,0 +1,156 @@
interface SavedShader {
id: string;
name: string;
code: string;
created: number;
lastUsed: number;
}
interface AppSettings {
resolution: number;
fps: number;
lastShaderCode: string;
}
export class Storage {
private static readonly SHADERS_KEY = 'bitfielder_shaders';
private static readonly SETTINGS_KEY = 'bitfielder_settings';
static saveShader(name: string, code: string): SavedShader {
const shaders = this.getShaders();
const id = this.generateId();
const timestamp = Date.now();
const shader: SavedShader = {
id,
name: name.trim() || `Shader ${shaders.length + 1}`,
code,
created: timestamp,
lastUsed: timestamp
};
shaders.push(shader);
this.setShaders(shaders);
return shader;
}
static getShaders(): SavedShader[] {
try {
const stored = localStorage.getItem(this.SHADERS_KEY);
return stored ? JSON.parse(stored) : [];
} catch (error) {
console.error('Failed to load shaders:', error);
return [];
}
}
static deleteShader(id: string): void {
const shaders = this.getShaders().filter(s => s.id !== id);
this.setShaders(shaders);
}
static updateShaderUsage(id: string): void {
const shaders = this.getShaders();
const shader = shaders.find(s => s.id === id);
if (shader) {
shader.lastUsed = Date.now();
this.setShaders(shaders);
}
}
static renameShader(id: string, newName: string): void {
const shaders = this.getShaders();
const shader = shaders.find(s => s.id === id);
if (shader) {
shader.name = newName.trim() || shader.name;
this.setShaders(shaders);
}
}
private static setShaders(shaders: SavedShader[]): void {
try {
// Keep only the 50 most recent shaders
const sortedShaders = shaders
.sort((a, b) => b.lastUsed - a.lastUsed)
.slice(0, 50);
localStorage.setItem(this.SHADERS_KEY, JSON.stringify(sortedShaders));
} catch (error) {
console.error('Failed to save shaders:', error);
}
}
static saveSettings(settings: Partial<AppSettings>): void {
try {
const current = this.getSettings();
const updated = { ...current, ...settings };
localStorage.setItem(this.SETTINGS_KEY, JSON.stringify(updated));
} catch (error) {
console.error('Failed to save settings:', error);
}
}
static getSettings(): AppSettings {
try {
const stored = localStorage.getItem(this.SETTINGS_KEY);
const defaults: AppSettings = {
resolution: 1,
fps: 30,
lastShaderCode: 'x^y'
};
return stored ? { ...defaults, ...JSON.parse(stored) } : defaults;
} catch (error) {
console.error('Failed to load settings:', error);
return {
resolution: 1,
fps: 30,
lastShaderCode: 'x^y'
};
}
}
static clearAll(): void {
try {
localStorage.removeItem(this.SHADERS_KEY);
localStorage.removeItem(this.SETTINGS_KEY);
} catch (error) {
console.error('Failed to clear storage:', error);
}
}
private static generateId(): string {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
static exportShaders(): string {
const shaders = this.getShaders();
return JSON.stringify(shaders, null, 2);
}
static importShaders(jsonData: string): boolean {
try {
const imported = JSON.parse(jsonData) as SavedShader[];
if (!Array.isArray(imported)) {
return false;
}
// Validate structure
const valid = imported.every(shader =>
shader.id && shader.name && shader.code &&
typeof shader.created === 'number' &&
typeof shader.lastUsed === 'number'
);
if (!valid) {
return false;
}
const existing = this.getShaders();
const merged = [...existing, ...imported];
this.setShaders(merged);
return true;
} catch (error) {
console.error('Failed to import shaders:', error);
return false;
}
}
}