Skip to content

Commit ac1680e

Browse files
author
Yutaka "FMS_Cat" Obuchi
authored
Merge pull request #98 from FMS-Cat/feat-gui-
feature (gui): add stats inspector
2 parents 216fe4c + ad408ed commit ac1680e

File tree

6 files changed

+183
-1
lines changed

6 files changed

+183
-1
lines changed

packages/automaton-with-gui/src/view/components/Header.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,17 @@ const Header = ( { className }: HeaderProps ): JSX.Element => {
321321
active={ ( settingsMode === 'general' ? 1 : 0 ) as any as boolean } // fuck
322322
data-stalker="General Settings"
323323
/>
324+
<Button
325+
as={ Icons.Scale }
326+
onClick={ () => {
327+
dispatch( {
328+
type: 'Settings/ChangeMode',
329+
mode: settingsMode === 'stats' ? 'none' : 'stats'
330+
} );
331+
} }
332+
active={ ( settingsMode === 'stats' ? 1 : 0 ) as any as boolean } // fuck
333+
data-stalker="Project Stats"
334+
/>
324335
<Button as={ Icons.Save }
325336
onClick={ handleSave }
326337
onContextMenu={ handleSaveContextMenu }

packages/automaton-with-gui/src/view/components/Inspector.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { InspectorCurveNode } from './InspectorCurveNode';
77
import { InspectorGeneral } from './InspectorGeneral';
88
import { InspectorLabel } from './InspectorLabel';
99
import { InspectorSnapping } from './InspectorSnapping';
10+
import { InspectorStats } from './InspectorStats';
1011
import { Metrics } from '../constants/Metrics';
1112
import { Scrollable } from './Scrollable';
1213
import { objectMapSize, objectMapValues } from '../utils/objectMap';
@@ -67,6 +68,8 @@ const Inspector = ( { className }: {
6768
content = <InspectorBeat />;
6869
} else if ( settingsMode === 'general' ) {
6970
content = <InspectorGeneral />;
71+
} else if ( settingsMode === 'stats' ) {
72+
content = <InspectorStats />;
7073
} else if ( mode === 'curve' ) {
7174
if ( selectedCurve != null ) {
7275
if ( stateSelectedNodes.length === 1 ) {
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import { Colors } from '../constants/Colors';
2+
import { InspectorHeader } from './InspectorHeader';
3+
import { InspectorHr } from './InspectorHr';
4+
import { InspectorItem } from './InspectorItem';
5+
import { minimizeData } from '../../minimizeData';
6+
import { useSelector } from '../states/store';
7+
import React, { useCallback, useState } from 'react';
8+
import styled from 'styled-components';
9+
10+
// == styles =======================================================================================
11+
const Value = styled.div`
12+
margin: 0.15rem;
13+
font-size: 0.7rem;
14+
line-height: 1em;
15+
`;
16+
17+
const CalculateButton = styled.div`
18+
margin: 4px auto 0;
19+
font-size: 0.8rem;
20+
line-height: 1.2rem;
21+
width: 128px;
22+
text-align: center;
23+
background: ${ Colors.back3 };
24+
cursor: pointer;
25+
26+
&:hover {
27+
background: ${ Colors.back4 };
28+
}
29+
30+
&:active {
31+
background: ${ Colors.back1 };
32+
}
33+
`;
34+
35+
// == element ======================================================================================
36+
export interface InspectorStatsProps {
37+
className?: string;
38+
}
39+
40+
const InspectorStats = (): JSX.Element | null => {
41+
const [ filesize, setFilesize ] = useState<number | null>( null );
42+
const [ filesizeMin, setFilesizeMin ] = useState<number | null>( null );
43+
44+
const {
45+
automaton,
46+
channelsCount,
47+
channelItemsCount,
48+
curvesCount,
49+
curvesLength,
50+
fxDefsCount,
51+
} = useSelector( ( state ) => ( {
52+
automaton: state.automaton.instance,
53+
channelsCount: Object.keys( state.automaton.channels ).length,
54+
channelItemsCount: Object.values( state.automaton.channels ).reduce(
55+
( prev, channel ) => prev + Object.keys( channel.items ).length,
56+
0,
57+
),
58+
curvesCount: Object.keys( state.automaton.curves ).length,
59+
curvesLength: Object.values( state.automaton.curves ).reduce(
60+
( prev, curve ) => prev + curve.length,
61+
0,
62+
),
63+
fxDefsCount: Object.keys( state.automaton.fxDefinitions ).length,
64+
} ) );
65+
66+
const handleCalculateFilesize = useCallback(
67+
() => {
68+
if ( !automaton ) { return; }
69+
70+
const serialized = automaton.serialize();
71+
setFilesize( JSON.stringify( serialized ).length );
72+
const minimizeOptions = {
73+
precisionTime: automaton.guiSettings.minimizedPrecisionTime,
74+
precisionValue: automaton.guiSettings.minimizedPrecisionValue
75+
};
76+
const minimized = minimizeData( serialized, minimizeOptions );
77+
setFilesizeMin( JSON.stringify( minimized ).length );
78+
},
79+
[ automaton ]
80+
);
81+
82+
return ( automaton && <>
83+
<InspectorHeader text="Project Stats" />
84+
85+
<InspectorHr />
86+
87+
<InspectorItem
88+
name="Channels"
89+
description="Channels exists in this project."
90+
>
91+
<Value>
92+
{ channelsCount.toLocaleString() }
93+
</Value>
94+
</InspectorItem>
95+
96+
<InspectorItem
97+
name="Channel Items"
98+
description="Items of channels exists in this project."
99+
>
100+
<Value>
101+
{ channelItemsCount.toLocaleString() }
102+
</Value>
103+
</InspectorItem>
104+
105+
<InspectorItem
106+
name="Curves"
107+
description="Curves exists in this project."
108+
>
109+
<Value>
110+
{ curvesCount.toLocaleString() }
111+
</Value>
112+
</InspectorItem>
113+
114+
<InspectorItem
115+
name="Curves Length"
116+
description="Total length of curves."
117+
>
118+
<Value>
119+
{ `${ curvesLength.toLocaleString() } sec` }
120+
</Value>
121+
</InspectorItem>
122+
123+
<InspectorItem
124+
name="Fx Definitions"
125+
description="Fx definitions loaded in this project."
126+
>
127+
<Value>
128+
{ fxDefsCount.toLocaleString() }
129+
</Value>
130+
</InspectorItem>
131+
132+
<InspectorHr />
133+
134+
<InspectorItem
135+
name="Filesize"
136+
description="The size of its serialized data."
137+
>
138+
<Value>
139+
{ filesize ? `${ filesize.toLocaleString() } bytes` : '----' }
140+
</Value>
141+
</InspectorItem>
142+
143+
<InspectorItem
144+
name="Filesize (min)"
145+
description="The size of its minimized serialized data."
146+
>
147+
<Value>
148+
{ filesizeMin ? `${ filesizeMin.toLocaleString() } bytes` : '----' }
149+
</Value>
150+
</InspectorItem>
151+
152+
<CalculateButton
153+
data-stalker="Calculate the size of its serialized data."
154+
onClick={ handleCalculateFilesize }
155+
>
156+
Calculate Filesize
157+
</CalculateButton>
158+
</> ) ?? null;
159+
};
160+
161+
export { InspectorStats };

packages/automaton-with-gui/src/view/icons/Icons.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Plus from './plus.svg';
1414
import Power from './power.svg';
1515
import Redo from './redo.svg';
1616
import Save from './save.svg';
17+
import Scale from './scale.svg';
1718
import Snap from './snap.svg';
1819
import Undo from './undo.svg';
1920
import Warning from './warning.svg';
@@ -35,6 +36,7 @@ export const Icons = {
3536
Power,
3637
Redo,
3738
Save,
39+
Scale,
3840
Snap,
3941
Undo,
4042
Warning,
Lines changed: 5 additions & 0 deletions
Loading

packages/automaton-with-gui/src/view/states/Settings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Reducer } from 'redux';
22
import { produce } from 'immer';
33

44
// == state ========================================================================================
5-
type SettingsMode = 'none' | 'snapping' | 'beat' | 'general';
5+
type SettingsMode = 'none' | 'snapping' | 'beat' | 'general' | 'stats';
66

77
export interface State {
88
mode: SettingsMode;

0 commit comments

Comments
 (0)