2024-08-28 20:42:52 +01:00
|
|
|
signature FILE_THREAD =
|
|
|
|
|
sig
|
2024-08-29 05:38:58 +01:00
|
|
|
val run: FileMessage.t Mailbox.mbox * InputMessage.t Mailbox.mbox -> unit
|
2024-08-28 20:42:52 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
structure FileThread :> FILE_THREAD =
|
|
|
|
|
struct
|
|
|
|
|
open FileMessage
|
2024-08-29 05:38:58 +01:00
|
|
|
open InputMessage
|
2024-08-28 20:42:52 +01:00
|
|
|
|
2024-08-29 09:55:08 +01:00
|
|
|
datatype parse_result = OK of AppType.triangle list | PARSE_ERROR
|
2024-08-29 04:39:23 +01:00
|
|
|
|
2024-12-29 20:18:29 +00:00
|
|
|
val structureName = "Green"
|
|
|
|
|
val filename = "green.dsc"
|
|
|
|
|
val exportFilename = "green.sml"
|
2024-08-30 02:22:02 +01:00
|
|
|
|
2024-08-30 03:46:05 +01:00
|
|
|
fun ndcToLerpX num =
|
|
|
|
|
let
|
|
|
|
|
val num = (num + 1.0) / 2.0
|
|
|
|
|
val num = Real32.toString num
|
2024-09-25 08:08:15 +01:00
|
|
|
val num =
|
2024-08-30 11:13:08 +01:00
|
|
|
(* Problem: It seems that Real32.toString may sometimes return a string
|
|
|
|
|
* that is recognised as an integer, like "1" instead of "1.0".
|
|
|
|
|
* If that happens, we just add a ".0" to the end
|
|
|
|
|
* so it's recognised as a real. *)
|
2024-09-25 08:08:15 +01:00
|
|
|
if String.isSubstring "." num then num
|
2024-08-30 11:13:08 +01:00
|
|
|
else num ^ ".0"
|
2024-08-30 03:46:05 +01:00
|
|
|
in
|
2024-09-25 08:08:15 +01:00
|
|
|
" (((startX * (1.0 - " ^ num ^ ")) + (endX * " ^ num
|
|
|
|
|
^ ")) / windowWidth) - 1.0"
|
2024-08-30 03:46:05 +01:00
|
|
|
end
|
2024-08-30 02:22:02 +01:00
|
|
|
|
2024-08-30 03:46:05 +01:00
|
|
|
fun ndcToLerpY num =
|
2024-08-30 02:22:02 +01:00
|
|
|
let
|
|
|
|
|
val num = (num + 1.0) / 2.0
|
|
|
|
|
val num = Real32.toString num
|
2024-09-25 08:08:15 +01:00
|
|
|
val num = if String.isSubstring "." num then num else num ^ ".0"
|
2024-08-30 02:22:02 +01:00
|
|
|
in
|
2024-09-25 08:08:15 +01:00
|
|
|
" (((startY * (1.0 - " ^ num ^ ")) + (endY * " ^ num
|
|
|
|
|
^ ")) / windowHeight) - 1.0"
|
2024-08-30 02:22:02 +01:00
|
|
|
end
|
|
|
|
|
|
2024-12-29 20:18:29 +00:00
|
|
|
fun colToString col =
|
|
|
|
|
let val col = Real32.toString col
|
|
|
|
|
in if String.isSubstring "." col then col else col ^ ".0"
|
|
|
|
|
end
|
|
|
|
|
|
2024-08-30 02:22:02 +01:00
|
|
|
fun helpExportTriangles (io, triangles) =
|
|
|
|
|
case triangles of
|
2024-12-29 20:18:29 +00:00
|
|
|
{x1, y1, x2, y2, x3, y3, r, g, b} :: tl =>
|
2024-08-30 02:22:02 +01:00
|
|
|
let
|
2024-08-30 03:46:05 +01:00
|
|
|
val x1 = ndcToLerpX x1
|
|
|
|
|
val x2 = ndcToLerpX x2
|
|
|
|
|
val x3 = ndcToLerpX x3
|
2024-08-30 02:22:02 +01:00
|
|
|
|
2024-08-30 03:46:05 +01:00
|
|
|
val y1 = ndcToLerpY y1
|
|
|
|
|
val y2 = ndcToLerpY y2
|
|
|
|
|
val y3 = ndcToLerpY y3
|
2024-08-30 02:22:02 +01:00
|
|
|
|
2024-12-29 20:18:29 +00:00
|
|
|
val r = colToString r
|
|
|
|
|
val g = colToString g
|
|
|
|
|
val b = colToString b
|
|
|
|
|
|
2024-08-30 02:22:02 +01:00
|
|
|
val line = String.concat
|
2024-09-25 08:08:15 +01:00
|
|
|
[ x1
|
|
|
|
|
, ",\n"
|
|
|
|
|
, y1
|
2025-02-18 11:53:28 +00:00
|
|
|
, ",\n"
|
|
|
|
|
, r
|
|
|
|
|
, ",\n"
|
|
|
|
|
, g
|
|
|
|
|
, ",\n"
|
|
|
|
|
, b
|
|
|
|
|
, ",\n"
|
2024-09-25 08:08:15 +01:00
|
|
|
, x2
|
|
|
|
|
, ",\n"
|
|
|
|
|
, y2
|
2025-02-18 11:53:28 +00:00
|
|
|
, ",\n"
|
|
|
|
|
, r
|
|
|
|
|
, ",\n"
|
|
|
|
|
, g
|
|
|
|
|
, ",\n"
|
|
|
|
|
, b
|
|
|
|
|
, ",\n"
|
2024-09-25 08:08:15 +01:00
|
|
|
, x3
|
|
|
|
|
, ",\n"
|
|
|
|
|
, y3
|
2025-02-18 11:53:28 +00:00
|
|
|
, ",\n"
|
2024-12-29 20:18:29 +00:00
|
|
|
, r
|
2025-02-18 11:53:28 +00:00
|
|
|
, ",\n"
|
2024-12-29 20:18:29 +00:00
|
|
|
, g
|
2025-02-18 11:53:28 +00:00
|
|
|
, ",\n"
|
2024-12-29 20:18:29 +00:00
|
|
|
, b
|
2024-09-25 08:08:15 +01:00
|
|
|
, case tl of
|
2024-12-29 20:18:29 +00:00
|
|
|
[] => "\n"
|
|
|
|
|
| _ => ",\n"
|
2024-08-30 02:22:02 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
val _ = TextIO.output (io, line)
|
|
|
|
|
in
|
|
|
|
|
helpExportTriangles (io, tl)
|
|
|
|
|
end
|
|
|
|
|
| [] => ()
|
|
|
|
|
|
|
|
|
|
fun exportTriangles triangles =
|
|
|
|
|
let
|
|
|
|
|
val io = TextIO.openOut exportFilename
|
|
|
|
|
|
|
|
|
|
val fileStartString =
|
|
|
|
|
String.concat ["structure ", structureName, " =\nstruct\n"]
|
|
|
|
|
val _ = TextIO.output (io, fileStartString)
|
|
|
|
|
|
|
|
|
|
val functionStartString =
|
2025-02-18 11:53:28 +00:00
|
|
|
" fun lerp (startX, startY, drawWidth, drawHeight, windowWidth, windowHeight) : Real32.real vector =\n\
|
2024-08-30 02:22:02 +01:00
|
|
|
\ let\n\
|
2024-08-30 05:20:56 +01:00
|
|
|
\ val endY = windowHeight - startY\n\
|
2024-08-30 09:15:33 +01:00
|
|
|
\ val startY = windowHeight - (startY + drawHeight)\n\
|
2024-08-30 02:22:02 +01:00
|
|
|
\ val endX = startX + drawWidth\n\
|
2024-08-30 03:46:05 +01:00
|
|
|
\ val windowHeight = windowHeight / 2.0\n\
|
|
|
|
|
\ val windowWidth = windowWidth / 2.0\n\
|
2024-08-30 02:22:02 +01:00
|
|
|
\ in\n\
|
|
|
|
|
\ #["
|
|
|
|
|
val _ = TextIO.output (io, functionStartString)
|
|
|
|
|
|
|
|
|
|
val _ = helpExportTriangles (io, triangles)
|
|
|
|
|
|
|
|
|
|
val _ = TextIO.output (io, " ]\n end\nend")
|
|
|
|
|
val _ = TextIO.closeOut io
|
|
|
|
|
in
|
|
|
|
|
()
|
|
|
|
|
end
|
2024-08-29 04:39:23 +01:00
|
|
|
|
2024-08-29 05:21:04 +01:00
|
|
|
fun parse (io, acc) =
|
2024-08-29 04:39:23 +01:00
|
|
|
case TextIO.inputLine io of
|
|
|
|
|
SOME line =>
|
2024-08-29 05:21:04 +01:00
|
|
|
let
|
2024-08-29 09:55:08 +01:00
|
|
|
val line = ParseFile.parseLine line
|
2024-08-29 05:21:04 +01:00
|
|
|
in
|
|
|
|
|
(case line of
|
|
|
|
|
SOME tri => parse (io, tri :: acc)
|
|
|
|
|
| NONE => PARSE_ERROR)
|
|
|
|
|
end
|
2024-08-29 04:39:23 +01:00
|
|
|
| NONE => let val triangles = List.rev acc in OK triangles end
|
|
|
|
|
|
2024-09-29 22:26:07 +01:00
|
|
|
fun loadTriangles (path, inputMailbox) =
|
2024-08-29 05:21:04 +01:00
|
|
|
let
|
2024-09-29 22:26:07 +01:00
|
|
|
val io = TextIO.openIn path
|
2024-08-29 05:21:04 +01:00
|
|
|
val triangles = parse (io, [])
|
|
|
|
|
val _ = TextIO.closeIn io
|
2024-08-29 05:38:58 +01:00
|
|
|
|
2024-08-29 09:55:08 +01:00
|
|
|
val inputMsg =
|
2024-08-29 05:38:58 +01:00
|
|
|
case triangles of
|
|
|
|
|
OK triangles => USE_TRIANGLES triangles
|
2024-12-29 20:18:29 +00:00
|
|
|
| PARSE_ERROR =>
|
|
|
|
|
let val _ = print "parse error\n"
|
|
|
|
|
in TRIANGLES_LOAD_ERROR
|
|
|
|
|
end
|
2024-08-29 05:21:04 +01:00
|
|
|
in
|
2024-08-29 05:38:58 +01:00
|
|
|
Mailbox.send (inputMailbox, inputMsg)
|
2024-08-29 04:39:23 +01:00
|
|
|
end
|
|
|
|
|
|
2024-08-29 00:05:30 +01:00
|
|
|
fun helpSaveTriangles (triangles, io) =
|
|
|
|
|
case triangles of
|
2024-12-29 20:18:29 +00:00
|
|
|
{x1, y1, x2, y2, x3, y3, r, g, b} :: tl =>
|
2024-08-29 00:05:30 +01:00
|
|
|
let
|
|
|
|
|
val triString = String.concat
|
2024-09-25 08:08:15 +01:00
|
|
|
[ "x "
|
|
|
|
|
, Real32.toString x1
|
|
|
|
|
, " y "
|
|
|
|
|
, Real32.toString y1
|
|
|
|
|
|
|
|
|
|
, " x "
|
|
|
|
|
, Real32.toString x2
|
|
|
|
|
, " y "
|
|
|
|
|
, Real32.toString y2
|
|
|
|
|
|
|
|
|
|
, " x "
|
|
|
|
|
, Real32.toString x3
|
|
|
|
|
, " y "
|
|
|
|
|
, Real32.toString y3
|
2024-12-29 20:18:29 +00:00
|
|
|
|
|
|
|
|
, " r "
|
|
|
|
|
, Real32.toString r
|
|
|
|
|
, " g "
|
|
|
|
|
, Real32.toString g
|
|
|
|
|
, " b "
|
|
|
|
|
, Real32.toString b
|
|
|
|
|
|
2024-08-29 00:05:30 +01:00
|
|
|
, "\n"
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
val _ = TextIO.output (io, triString)
|
|
|
|
|
in
|
|
|
|
|
helpSaveTriangles (tl, io)
|
|
|
|
|
end
|
|
|
|
|
| [] => ()
|
|
|
|
|
|
|
|
|
|
fun saveTriangles triangles =
|
2024-08-29 00:43:51 +01:00
|
|
|
let
|
|
|
|
|
val io = TextIO.openOut filename
|
|
|
|
|
val _ = helpSaveTriangles (triangles, io)
|
|
|
|
|
val _ = TextIO.closeOut io
|
|
|
|
|
in
|
|
|
|
|
()
|
2024-08-29 00:05:30 +01:00
|
|
|
end
|
|
|
|
|
|
2024-09-29 22:26:07 +01:00
|
|
|
fun getDirList (dir, acc, rootPath) =
|
2024-09-25 08:08:15 +01:00
|
|
|
case OS.FileSys.readDir dir of
|
|
|
|
|
SOME path =>
|
2024-09-29 22:26:07 +01:00
|
|
|
let
|
|
|
|
|
val folderPath = String.concat [rootPath, "/", path]
|
|
|
|
|
in
|
|
|
|
|
if OS.FileSys.isDir folderPath then
|
|
|
|
|
getDirList (dir, AppType.IS_FOLDER path :: acc, rootPath)
|
|
|
|
|
else if OS.FileSys.isLink folderPath then
|
|
|
|
|
getDirList (dir, acc, rootPath)
|
|
|
|
|
else
|
|
|
|
|
getDirList (dir, AppType.IS_FILE path :: acc, rootPath)
|
|
|
|
|
end
|
2024-09-25 08:08:15 +01:00
|
|
|
| NONE => let val acc = List.rev acc in Vector.fromList acc end
|
|
|
|
|
|
|
|
|
|
fun loadFiles (path, inputMailbox) =
|
|
|
|
|
let
|
|
|
|
|
val path = if String.size path = 0 then OS.FileSys.getDir () else path
|
|
|
|
|
val dir = OS.FileSys.openDir path
|
2024-09-29 22:26:07 +01:00
|
|
|
val dirList = getDirList (dir, [], path)
|
2024-09-25 08:08:15 +01:00
|
|
|
val _ = OS.FileSys.closeDir dir
|
2024-09-27 10:06:21 +01:00
|
|
|
val inputMsg = FILE_BROWSER_AND_PATH {fileBrowser = dirList, path = path}
|
2024-09-25 08:08:15 +01:00
|
|
|
in
|
2024-09-27 10:06:21 +01:00
|
|
|
Mailbox.send (inputMailbox, inputMsg)
|
2024-09-25 08:08:15 +01:00
|
|
|
end
|
|
|
|
|
|
2024-09-29 22:26:07 +01:00
|
|
|
fun selectPath (path, inputMailbox) =
|
|
|
|
|
if OS.FileSys.isDir path then loadFiles (path, inputMailbox)
|
|
|
|
|
else loadTriangles (path, inputMailbox)
|
|
|
|
|
|
2024-08-29 05:38:58 +01:00
|
|
|
fun run (fileMailbox, inputMailbox) =
|
2024-08-28 20:42:52 +01:00
|
|
|
let
|
|
|
|
|
val _ =
|
|
|
|
|
case Mailbox.recv fileMailbox of
|
2024-08-29 00:05:30 +01:00
|
|
|
SAVE_TRIANGLES triangles => saveTriangles triangles
|
2024-09-29 22:26:07 +01:00
|
|
|
| LOAD_TRIANGLES => loadTriangles (filename, inputMailbox)
|
2024-08-30 02:34:24 +01:00
|
|
|
| EXPORT_TRIANGLES triangles => exportTriangles triangles
|
2024-09-25 08:08:15 +01:00
|
|
|
| LOAD_FILES path => loadFiles (path, inputMailbox)
|
2024-09-29 22:26:07 +01:00
|
|
|
| SELECT_PATH path => selectPath (path, inputMailbox)
|
2024-08-28 20:42:52 +01:00
|
|
|
in
|
2024-08-29 05:38:58 +01:00
|
|
|
run (fileMailbox, inputMailbox)
|
2024-08-28 20:42:52 +01:00
|
|
|
end
|
|
|
|
|
end
|