@@ -10,6 +10,7 @@ import EditorWorker from "worker-loader?name=editor.worker.js!monaco-editor/esm/
10
10
import FengariWorker from "worker-loader?name=fengari.worker.js!./fengari.worker" ;
11
11
import TsWorker from "worker-loader?name=ts.worker.js!./ts.worker" ;
12
12
import "../../assets/styles/play.scss" ;
13
+ import { getInitialCode , updateCodeHistory } from "./code" ;
13
14
14
15
// TODO: Use TypeScript 3.8 type imports
15
16
type CustomTypeScriptWorker = import ( "./ts.worker" ) . CustomTypeScriptWorker ;
@@ -24,134 +25,87 @@ type CustomTypeScriptWorker = import("./ts.worker").CustomTypeScriptWorker;
24
25
} ,
25
26
} ;
26
27
27
- const container = document . getElementById ( "editor-ts" ) ;
28
- const outputTerminalHeader = document . getElementById ( "editor-output-terminal-header" ) ;
29
- const outputTerminalContent = document . getElementById ( "editor-output-terminal-content" ) ;
30
- const exampleLua = document . getElementById ( "editor- lua" ) ;
31
- const astLua = document . getElementById ( "editor-lua-ast" ) ;
28
+ renderjson . set_show_to_level ( 1 ) ;
29
+ renderjson . set_replacer ( ( key : string , value : any ) => {
30
+ if ( key === "kind" ) {
31
+ return lua . SyntaxKind [ value ] ;
32
+ }
32
33
33
- // Set tstl version
34
- outputTerminalHeader ! . textContent = `TypescriptToLua version ${ tstlVersion } ` ;
34
+ return value ;
35
+ } ) ;
35
36
36
- // Layout stuff
37
- const luaTabText = document . getElementById ( "lua-tab-text" ) as HTMLDivElement | null ;
38
- const luaTabAst = document . getElementById ( "lua-tab-ast" ) as HTMLDivElement | null ;
39
- if ( luaTabText && luaTabAst && exampleLua && astLua ) {
40
- const tabOnclick = ( ) => {
41
- luaTabText . classList . toggle ( "lua-tab-active" ) ;
42
- luaTabAst . classList . toggle ( "lua-tab-active" ) ;
43
- exampleLua . classList . toggle ( "editor-lua-active" ) ;
44
- astLua . classList . toggle ( "editor-lua-active" ) ;
45
- } ;
46
- luaTabText . onclick = tabOnclick ;
47
- luaTabAst . onclick = tabOnclick ;
48
- }
37
+ const tsEditorContainer = document . getElementById ( "editor-ts" ) ! ;
38
+ const luaEditorContainer = document . getElementById ( "editor-lua" ) ! ;
39
+ const luaAstContainer = document . getElementById ( "editor-lua-ast" ) ! ;
40
+ const outputTerminalContent = document . getElementById ( "editor-output-terminal-content" ) ! ;
49
41
50
- // Actual editor and transpilation
51
- let example = `/** @noSelfInFile */
42
+ // Set tstl version
43
+ const outputTerminalHeader = document . getElementById ( "editor-output-terminal-header" ) ! ;
44
+ outputTerminalHeader . textContent = `TypeScriptToLua version ${ tstlVersion } ` ;
52
45
53
- // Declare exposed API
54
- type Vector = [number, number, number];
46
+ // Layout stuff
47
+ const luaTabText = document . querySelector < HTMLDivElement > ( "#lua-tab-text" ) ! ;
48
+ const luaTabAst = document . querySelector < HTMLDivElement > ( "#lua-tab-ast" ) ! ;
49
+ const onTabClick = ( ) => {
50
+ luaTabText . classList . toggle ( "lua-tab-active" ) ;
51
+ luaTabAst . classList . toggle ( "lua-tab-active" ) ;
52
+ luaEditorContainer . classList . toggle ( "editor-lua-active" ) ;
53
+ luaAstContainer . classList . toggle ( "editor-lua-active" ) ;
54
+ } ;
55
55
56
- declare interface OnSpellStartEvent {
57
- caster: Unit;
58
- targetLocation: Vector;
59
- }
56
+ luaTabText . onclick = onTabClick ;
57
+ luaTabAst . onclick = onTabClick ;
60
58
61
- declare class Unit {
62
- getLevel(): number;
63
- isEnemy(other: Unit): boolean;
64
- kill(): void;
59
+ function setLuaAST ( ast : lua . Block ) {
60
+ luaAstContainer . innerText = "" ;
61
+ luaAstContainer . appendChild ( renderjson ( ast ) ) ;
65
62
}
66
63
67
- declare function print(...messages: any[]): void;
68
- declare function FindUnitsInRadius(location: Vector, radius: number): Unit[];
69
-
70
- // Use declared API in code
71
- function onSpellStart(event: OnSpellStartEvent): void {
72
- const units = FindUnitsInRadius(event.targetLocation, 500);
73
- const enemies = units.filter(unit => event.caster.isEnemy(unit));
74
-
75
- for (const unit of enemies) {
76
- print(unit, unit.getLevel());
77
- unit.kill();
78
- }
79
- }` ;
64
+ async function onCodeChanged ( ) {
65
+ const model = tsEditor . getModel ( ) ! ;
66
+ const getWorker = await monaco . languages . typescript . getTypeScriptWorker ( ) ;
67
+ const client : CustomTypeScriptWorker = await getWorker ( model . uri ) ;
80
68
81
- var queryStringSrcStart = window . location . hash . indexOf ( "#src=" ) ;
82
- if ( queryStringSrcStart == 0 ) {
83
- var encoded = window . location . hash . substring ( "#src=" . length ) ;
84
- example = decodeURIComponent ( encoded ) ;
69
+ const { code , ast } = await client . getTranspileOutput ( ) ;
70
+ luaEditor . setValue ( code ) ;
71
+ setLuaAST ( ast ) ;
72
+ fengariWorker . postMessage ( { luaStr : code } ) ;
85
73
}
86
74
87
- if ( container && exampleLua && astLua ) {
88
- renderjson . set_show_to_level ( 1 ) ;
89
- renderjson . set_replacer ( ( key : string , value : any ) => {
90
- if ( key === "kind" ) {
91
- return lua . SyntaxKind [ value ] ;
92
- }
93
-
94
- return value ;
95
- } ) ;
96
-
97
- async function compileLua ( ) {
98
- const model = tsEditor . getModel ( ) ! ;
99
- const getWorker = await monaco . languages . typescript . getTypeScriptWorker ( ) ;
100
- const client = ( await getWorker ( model . uri ) ) as CustomTypeScriptWorker ;
101
- const { code, ast } = await client . getTranspileOutput ( ) ;
102
-
103
- luaEditor . setValue ( code ) ;
104
- astLua ! . innerText = "" ;
105
- astLua ! . appendChild ( renderjson ( ast ) ) ;
106
- fengariWorker . postMessage ( { luaStr : code } ) ;
107
- }
75
+ const fengariWorker = new FengariWorker ( ) ;
76
+ fengariWorker . onmessage = event => {
77
+ outputTerminalContent . innerText = event . data . luaPrint ;
78
+ } ;
108
79
109
- let tsEditor = monaco . editor . create ( container , {
110
- value : example ,
111
- language : "typescript" ,
112
- minimap : { enabled : false } ,
113
- theme : "vs-dark" ,
114
- } ) ;
115
-
116
- let luaEditor = monaco . editor . create ( exampleLua , {
117
- value : "" ,
118
- language : "lua" ,
119
- minimap : { enabled : false } ,
120
- theme : "vs-dark" ,
121
- readOnly : true ,
122
- } ) ;
123
-
124
- window . onresize = ( ) => {
125
- tsEditor . layout ( ) ;
126
- luaEditor . layout ( ) ;
127
- } ;
128
-
129
- compileLua ( ) ;
130
-
131
- let timerVar : any ;
132
- let ignoreHashChange = false ;
133
-
134
- tsEditor . onDidChangeModelContent ( e => {
135
- clearInterval ( timerVar ) ;
136
- // Update transpile result only once per 250s
137
- timerVar = setTimeout ( ( ) => {
138
- compileLua ( ) ;
139
- window . location . replace ( "#src=" + encodeURIComponent ( tsEditor . getValue ( ) ) ) ;
140
- ignoreHashChange = true ;
141
- } , 250 ) ;
142
- } ) ;
143
-
144
- window . onhashchange = ( ) => {
145
- if ( ignoreHashChange ) {
146
- ignoreHashChange = false ;
147
- return ;
148
- }
149
- } ;
80
+ const tsEditor = monaco . editor . create ( tsEditorContainer , {
81
+ value : getInitialCode ( ) ,
82
+ language : "typescript" ,
83
+ minimap : { enabled : false } ,
84
+ theme : "vs-dark" ,
85
+ } ) ;
86
+
87
+ const luaEditor = monaco . editor . create ( luaEditorContainer , {
88
+ value : "" ,
89
+ language : "lua" ,
90
+ minimap : { enabled : false } ,
91
+ theme : "vs-dark" ,
92
+ readOnly : true ,
93
+ } ) ;
94
+
95
+ // More performant than `automaticLayout: true`, because container sizes can change only with window
96
+ window . onresize = ( ) => {
97
+ tsEditor . layout ( ) ;
98
+ luaEditor . layout ( ) ;
99
+ } ;
150
100
151
- const fengariWorker = new FengariWorker ( ) ;
152
- fengariWorker . onmessage = ( event : MessageEvent ) => {
153
- if ( outputTerminalContent ) {
154
- outputTerminalContent . innerText = event . data . luaPrint ;
155
- }
156
- } ;
157
- }
101
+ let contentChangeTimeout : any ;
102
+ tsEditor . onDidChangeModelContent ( e => {
103
+ clearTimeout ( contentChangeTimeout ) ;
104
+ // Update transpile result no more often than every 250ms
105
+ contentChangeTimeout = setTimeout ( ( ) => {
106
+ onCodeChanged ( ) ;
107
+ updateCodeHistory ( tsEditor . getValue ( ) ) ;
108
+ } , 250 ) ;
109
+ } ) ;
110
+
111
+ onCodeChanged ( ) ;
0 commit comments