mirror of
https://github.com/Noratrieb/viewstrap.git
synced 2026-01-14 16:45:10 +01:00
it... works?
This commit is contained in:
parent
211db3c768
commit
0b8bd50e7e
3 changed files with 181 additions and 38 deletions
|
|
@ -38,7 +38,7 @@
|
||||||
#inventory-wrapper {
|
#inventory-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
gap: 5px
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-compiler {
|
.item-compiler {
|
||||||
|
|
@ -58,6 +58,10 @@
|
||||||
background: grey;
|
background: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.crafting-slot-dragover {
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
|
||||||
.crafting-icon {
|
.crafting-icon {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 70px;
|
width: 70px;
|
||||||
|
|
@ -69,6 +73,10 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.crafting-progress-arrow {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.crafting-progress-arrow-running {
|
.crafting-progress-arrow-running {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
0deg,
|
0deg,
|
||||||
|
|
@ -98,6 +106,12 @@
|
||||||
background-position: 0% 82%;
|
background-position: 0% 82%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#error {
|
||||||
|
color: red;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -109,14 +123,16 @@
|
||||||
<div class="region">
|
<div class="region">
|
||||||
<h1>Crafting</h1>
|
<h1>Crafting</h1>
|
||||||
<div class="crafting-wrapper">
|
<div class="crafting-wrapper">
|
||||||
<div class="crafting-slot item center-inner"></div>
|
<div id="crafting-slot-1" class="crafting-slot item"></div>
|
||||||
<div class="crafting-icon center-inner">
|
<div class="crafting-icon center-inner">
|
||||||
<span class>➕</span>
|
<span class>➕</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="crafting-slot item center-inner"></div>
|
<div id="crafting-slot-2" class="crafting-slot item"></div>
|
||||||
<div
|
<div
|
||||||
id="crafting-progress-arrow"
|
id="crafting-progress-arrow"
|
||||||
class="crafting-progress-arrow-running__"
|
class="crafting-progress-arrow"
|
||||||
|
role="button"
|
||||||
|
onclick="compile()"
|
||||||
>
|
>
|
||||||
<svg class="crafting-progress-indicator" viewBox="0 0 100 100">
|
<svg class="crafting-progress-indicator" viewBox="0 0 100 100">
|
||||||
<!--
|
<!--
|
||||||
|
|
@ -140,13 +156,12 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="crafting-slot item center-inner"></div>
|
<div class="crafting-slot item center-inner"></div>
|
||||||
|
|
||||||
|
<div id="error"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="compile-action" disabled onclick="compile()">
|
|
||||||
build me a compiler
|
|
||||||
</button>
|
|
||||||
<button class="compile-action" disabled onclick="updateCompilers()">
|
<button class="compile-action" disabled onclick="updateCompilers()">
|
||||||
update compilers
|
update compilers
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -165,27 +180,75 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const errorElem = document.getElementById("error");
|
||||||
|
|
||||||
|
function setError(msg) {
|
||||||
|
error.innerText = msg;
|
||||||
|
}
|
||||||
|
function resetError() {
|
||||||
|
error.innerText = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderItem(item) {
|
||||||
|
const inner = document.createElement("div");
|
||||||
|
inner.innerText = item.name;
|
||||||
|
inner.classList.add("source-box-text");
|
||||||
|
const elem = document.createElement("div");
|
||||||
|
elem.classList.add(`item-${item.type}`);
|
||||||
|
elem.classList.add("center-inner");
|
||||||
|
elem.classList.add("item");
|
||||||
|
elem.item = item;
|
||||||
|
elem.appendChild(inner);
|
||||||
|
elem.draggable = true;
|
||||||
|
elem.addEventListener("dragstart", (event) => {
|
||||||
|
const dt = event.dataTransfer;
|
||||||
|
dt.setData("application/json", JSON.stringify(item));
|
||||||
|
dt.dropEffect = "move";
|
||||||
|
});
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupDragDropSlot(elem) {
|
||||||
|
elem.addEventListener("dragover", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
elem.classList.add("crafting-slot-dragover");
|
||||||
|
});
|
||||||
|
elem.addEventListener("dragleave", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
elem.classList.remove("crafting-slot-dragover");
|
||||||
|
});
|
||||||
|
elem.addEventListener("drop", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
resetError();
|
||||||
|
|
||||||
|
const data = JSON.parse(
|
||||||
|
event.dataTransfer.getData("application/json")
|
||||||
|
);
|
||||||
|
const item = new Item(data.name, data.type);
|
||||||
|
const itemElem = renderItem(item);
|
||||||
|
|
||||||
|
elem.innerHTML = "";
|
||||||
|
elem.appendChild(itemElem);
|
||||||
|
elem.classList.remove("crafting-slot-dragover");
|
||||||
|
elem.item = item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class Inventory {
|
class Inventory {
|
||||||
constructor(initialItems) {
|
constructor(initialItems) {
|
||||||
this.dom = document.getElementById("inventory-wrapper");
|
this.dom = document.getElementById("inventory-wrapper");
|
||||||
|
|
||||||
for (const item of initialItems) {
|
for (const item of initialItems) {
|
||||||
const elem = this.renderItem(item);
|
const elem = renderItem(item);
|
||||||
this.dom.appendChild(elem);
|
this.dom.appendChild(elem);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
renderItem(item) {
|
this.craftingSlot1 = document.getElementById("crafting-slot-1");
|
||||||
const inner = document.createElement("div");
|
this.craftingSlot2 = document.getElementById("crafting-slot-2");
|
||||||
inner.innerText = item.name;
|
|
||||||
inner.classList.add("source-box-text");
|
setupDragDropSlot(this.craftingSlot1);
|
||||||
const elem = document.createElement("div");
|
setupDragDropSlot(this.craftingSlot2);
|
||||||
elem.classList.add(`item-${item.type}`);
|
|
||||||
elem.classList.add("center-inner");
|
|
||||||
elem.classList.add("item");
|
|
||||||
elem.item = item;
|
|
||||||
elem.appendChild(inner);
|
|
||||||
return elem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items() {
|
items() {
|
||||||
|
|
@ -200,7 +263,7 @@
|
||||||
(inner) => inner.name == item.name && inner.type == item.type
|
(inner) => inner.name == item.name && inner.type == item.type
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const elem = this.renderItem(item);
|
const elem = renderItem(item);
|
||||||
this.dom.appendChild(elem);
|
this.dom.appendChild(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,6 +276,10 @@
|
||||||
|
|
||||||
const compileActions = document.querySelectorAll(".compile-action");
|
const compileActions = document.querySelectorAll(".compile-action");
|
||||||
|
|
||||||
|
const craftingProgressArrow = document.getElementById(
|
||||||
|
"crafting-progress-arrow"
|
||||||
|
);
|
||||||
|
|
||||||
const inventory = new Inventory([
|
const inventory = new Inventory([
|
||||||
new Item("compiler", "source"),
|
new Item("compiler", "source"),
|
||||||
new Item("library", "source"),
|
new Item("library", "source"),
|
||||||
|
|
@ -241,15 +308,67 @@
|
||||||
}
|
}
|
||||||
if ("AvailableCompilers" in msg) {
|
if ("AvailableCompilers" in msg) {
|
||||||
for (const compiler of msg.AvailableCompilers) {
|
for (const compiler of msg.AvailableCompilers) {
|
||||||
inventory.appendIfNotExists(new Item(`rustc ${compiler}`, "compiler"));
|
inventory.appendIfNotExists(
|
||||||
|
new Item(`rustc ${compiler}`, "compiler")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ("Done" in msg) {
|
||||||
|
craftingProgressArrow.classList.remove(
|
||||||
|
"crafting-progress-arrow-running"
|
||||||
|
);
|
||||||
|
const error = msg.Done ? "" : "an error occurred";
|
||||||
|
setError(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function compile() {
|
function compile() {
|
||||||
|
const arrowClasses = craftingProgressArrow.classList;
|
||||||
|
if (arrowClasses.contains("crafting-progress-arrow-running")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log("compiling");
|
console.log("compiling");
|
||||||
|
|
||||||
ws.send(JSON.stringify("Compile"));
|
resetError();
|
||||||
|
|
||||||
|
const item1 = inventory.craftingSlot1.item;
|
||||||
|
if (!item1) {
|
||||||
|
setError("left side must be filled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const item2 = inventory.craftingSlot2.item;
|
||||||
|
if (!item2) {
|
||||||
|
setError("right side must be filled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Items", item1, item2);
|
||||||
|
|
||||||
|
const action = [item1, item2].find((item) => item.type == "source");
|
||||||
|
if (!action) {
|
||||||
|
setError("must include a source in the crafting receipe");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const compiler = [item1, item2].find((item) => item.type == "compiler");
|
||||||
|
if (!compiler) {
|
||||||
|
setError("must include a compiler in the crafting receipe");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arrowClasses.add("crafting-progress-arrow-running");
|
||||||
|
|
||||||
|
const compilerName = compiler.name.split(" ")[1];
|
||||||
|
const actionName = {
|
||||||
|
library: "BuildLibrary",
|
||||||
|
compiler: "BuildCompiler",
|
||||||
|
}[action.name];
|
||||||
|
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
Compile: { compiler: compilerName, action: actionName },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
stdout.value = "";
|
stdout.value = "";
|
||||||
stderr.value = "";
|
stderr.value = "";
|
||||||
|
|
|
||||||
|
|
@ -3,23 +3,35 @@ use std::{path::Path, pin::Pin, process::Stdio};
|
||||||
use axum::extract::ws::{self, WebSocket};
|
use axum::extract::ws::{self, WebSocket};
|
||||||
use color_eyre::{eyre::Context, Result};
|
use color_eyre::{eyre::Context, Result};
|
||||||
use futures::{stream::SplitSink, SinkExt};
|
use futures::{stream::SplitSink, SinkExt};
|
||||||
use serde::Serialize;
|
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncRead, AsyncReadExt},
|
io::{AsyncRead, AsyncReadExt},
|
||||||
process::{Child, Command},
|
process::{Child, Command},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ServerMessage;
|
use crate::{Action, Compiler, ServerMessage};
|
||||||
|
|
||||||
pub async fn build_a_compiler(
|
pub async fn build_a_compiler(
|
||||||
output: &mut SplitSink<WebSocket, ws::Message>,
|
output: &mut SplitSink<WebSocket, ws::Message>,
|
||||||
entrypoint: &Path,
|
entrypoint: &Path,
|
||||||
|
compiler: Compiler,
|
||||||
|
action: Action,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let cwd = entrypoint.parent().unwrap();
|
let cwd = entrypoint.parent().unwrap();
|
||||||
|
|
||||||
|
let stage = match compiler {
|
||||||
|
Compiler::Bootstrap => "0",
|
||||||
|
Compiler::Dev => "1",
|
||||||
|
Compiler::Dist => "2",
|
||||||
|
};
|
||||||
|
|
||||||
|
let action = match action {
|
||||||
|
Action::BuildCompiler => "compiler",
|
||||||
|
Action::BuildLibrary => "library",
|
||||||
|
};
|
||||||
|
|
||||||
let mut cmd = Command::new(entrypoint);
|
let mut cmd = Command::new(entrypoint);
|
||||||
cmd.current_dir(cwd);
|
cmd.current_dir(cwd);
|
||||||
cmd.args(["build", "--stage", "1", "library"]);
|
cmd.args(["build", "--stage", stage, action]);
|
||||||
// cmd.arg("--help");
|
// cmd.arg("--help");
|
||||||
|
|
||||||
cmd.stdout(Stdio::piped());
|
cmd.stdout(Stdio::piped());
|
||||||
|
|
@ -37,13 +49,6 @@ pub async fn build_a_compiler(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
|
||||||
pub enum Compiler {
|
|
||||||
Bootstrap,
|
|
||||||
Dev,
|
|
||||||
Dist,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn list_compilers(entrypoint: &Path) -> Vec<Compiler> {
|
pub async fn list_compilers(entrypoint: &Path) -> Vec<Compiler> {
|
||||||
let mut compilers = vec![Compiler::Bootstrap];
|
let mut compilers = vec![Compiler::Bootstrap];
|
||||||
|
|
||||||
|
|
|
||||||
29
src/main.rs
29
src/main.rs
|
|
@ -12,7 +12,6 @@ use axum::{
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use bootstrap::Compiler;
|
|
||||||
use futures::{stream::StreamExt, SinkExt};
|
use futures::{stream::StreamExt, SinkExt};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tower_http::{
|
use tower_http::{
|
||||||
|
|
@ -96,11 +95,25 @@ enum ServerMessage<'a> {
|
||||||
Stdout(&'a str),
|
Stdout(&'a str),
|
||||||
Stderr(&'a str),
|
Stderr(&'a str),
|
||||||
AvailableCompilers(Vec<Compiler>),
|
AvailableCompilers(Vec<Compiler>),
|
||||||
|
Done(bool),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum Compiler {
|
||||||
|
Bootstrap,
|
||||||
|
Dev,
|
||||||
|
Dist,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
enum ClientMessage {
|
pub enum Action {
|
||||||
Compile,
|
BuildCompiler,
|
||||||
|
BuildLibrary,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub enum ClientMessage {
|
||||||
|
Compile { compiler: Compiler, action: Action },
|
||||||
ListCompilers,
|
ListCompilers,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,8 +161,14 @@ async fn handle_socket(mut socket: WebSocket, who: SocketAddr, entrypoint: PathB
|
||||||
let msg = serde_json::from_str::<ClientMessage>(&msg_str);
|
let msg = serde_json::from_str::<ClientMessage>(&msg_str);
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
Ok(ClientMessage::Compile) => {
|
Ok(ClientMessage::Compile { compiler, action }) => {
|
||||||
if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await {
|
let mut success = true;
|
||||||
|
if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint, compiler, action).await {
|
||||||
|
error!(%err);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = sender.send(ServerMessage::Done(success).into()).await {
|
||||||
error!(%err);
|
error!(%err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue