|
| 1 | +/** |
| 2 | + * useStaticSimulator Hook |
| 3 | + * Encapsulates Static vs Non-Static simulation logic (SRP) |
| 4 | + */ |
| 5 | + |
| 6 | +import { useState, useCallback } from 'react'; |
| 7 | +import type { IStaticState, IUseStaticSimulator, IObjectInstance } from '../types'; |
| 8 | +import { useModuleConsole } from '../contexts'; |
| 9 | + |
| 10 | +const createInitialState = (): IStaticState => ({ |
| 11 | + classDefinition: { |
| 12 | + name: 'Counter', |
| 13 | + members: [ |
| 14 | + { id: 'static-count', name: 'totalCount', isStatic: true, type: 'field', value: 0 }, |
| 15 | + { id: 'instance-id', name: 'instanceId', isStatic: false, type: 'field' }, |
| 16 | + { id: 'static-method', name: 'getTotalCount()', isStatic: true, type: 'method' }, |
| 17 | + { id: 'instance-method', name: 'getId()', isStatic: false, type: 'method' }, |
| 18 | + ], |
| 19 | + instanceCount: 0, |
| 20 | + }, |
| 21 | + instances: [], |
| 22 | + nextInstanceId: 1, |
| 23 | + staticFieldValue: 0, |
| 24 | + selectedView: 'memory', |
| 25 | +}); |
| 26 | + |
| 27 | +export function useStaticSimulator(): IUseStaticSimulator { |
| 28 | + const [state, setState] = useState<IStaticState>(createInitialState); |
| 29 | + const { log } = useModuleConsole('static'); |
| 30 | + |
| 31 | + const createInstance = useCallback(() => { |
| 32 | + setState((prev) => { |
| 33 | + const newId = prev.nextInstanceId; |
| 34 | + const newInstance: IObjectInstance = { |
| 35 | + id: newId, |
| 36 | + className: prev.classDefinition.name, |
| 37 | + instanceFields: [ |
| 38 | + { name: 'instanceId', value: newId }, |
| 39 | + ], |
| 40 | + }; |
| 41 | + |
| 42 | + log(`new Counter() → Instance #${newId} created in HEAP`, 'success'); |
| 43 | + log(`Counter.totalCount++ (static field incremented in Metaspace)`); |
| 44 | + |
| 45 | + return { |
| 46 | + ...prev, |
| 47 | + instances: [...prev.instances, newInstance], |
| 48 | + nextInstanceId: newId + 1, |
| 49 | + staticFieldValue: prev.staticFieldValue + 1, |
| 50 | + classDefinition: { |
| 51 | + ...prev.classDefinition, |
| 52 | + instanceCount: prev.classDefinition.instanceCount + 1, |
| 53 | + members: prev.classDefinition.members.map((m) => |
| 54 | + m.id === 'static-count' ? { ...m, value: prev.staticFieldValue + 1 } : m |
| 55 | + ), |
| 56 | + }, |
| 57 | + }; |
| 58 | + }); |
| 59 | + }, [log]); |
| 60 | + |
| 61 | + const updateStaticField = useCallback((value: number) => { |
| 62 | + setState((prev) => { |
| 63 | + log(`Counter.totalCount = ${value} (ALL instances see this change!)`, 'warn'); |
| 64 | + |
| 65 | + return { |
| 66 | + ...prev, |
| 67 | + staticFieldValue: value, |
| 68 | + classDefinition: { |
| 69 | + ...prev.classDefinition, |
| 70 | + members: prev.classDefinition.members.map((m) => |
| 71 | + m.id === 'static-count' ? { ...m, value } : m |
| 72 | + ), |
| 73 | + }, |
| 74 | + }; |
| 75 | + }); |
| 76 | + }, [log]); |
| 77 | + |
| 78 | + const updateInstanceField = useCallback((instanceId: number, value: number) => { |
| 79 | + setState((prev) => { |
| 80 | + log(`instance#${instanceId}.instanceId = ${value} (ONLY this instance changes)`); |
| 81 | + |
| 82 | + return { |
| 83 | + ...prev, |
| 84 | + instances: prev.instances.map((inst) => |
| 85 | + inst.id === instanceId |
| 86 | + ? { |
| 87 | + ...inst, |
| 88 | + instanceFields: inst.instanceFields.map((f) => |
| 89 | + f.name === 'instanceId' ? { ...f, value } : f |
| 90 | + ), |
| 91 | + } |
| 92 | + : inst |
| 93 | + ), |
| 94 | + }; |
| 95 | + }); |
| 96 | + }, [log]); |
| 97 | + |
| 98 | + const setView = useCallback((view: 'memory' | 'comparison') => { |
| 99 | + setState((prev) => ({ ...prev, selectedView: view })); |
| 100 | + }, []); |
| 101 | + |
| 102 | + const reset = useCallback(() => { |
| 103 | + setState(createInitialState()); |
| 104 | + log('Simulation reset. Class unloaded and reloaded.'); |
| 105 | + }, [log]); |
| 106 | + |
| 107 | + return { |
| 108 | + ...state, |
| 109 | + createInstance, |
| 110 | + updateStaticField, |
| 111 | + updateInstanceField, |
| 112 | + setView, |
| 113 | + reset, |
| 114 | + }; |
| 115 | +} |
0 commit comments