some more changes

This commit is contained in:
Michael Zhang 2023-12-29 17:36:27 -05:00
parent bbdeea5031
commit 6050903c09
55 changed files with 1394 additions and 5468 deletions

1
.npmrc
View file

@ -1 +0,0 @@
engine-strict=true

75
Cargo.lock generated
View file

@ -734,8 +734,18 @@ version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
dependencies = [
"darling_core",
"darling_macro",
"darling_core 0.13.4",
"darling_macro 0.13.4",
]
[[package]]
name = "darling"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
dependencies = [
"darling_core 0.14.4",
"darling_macro 0.14.4",
]
[[package]]
@ -752,13 +762,38 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "darling_core"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 1.0.109",
]
[[package]]
name = "darling_macro"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [
"darling_core",
"darling_core 0.13.4",
"quote",
"syn 1.0.109",
]
[[package]]
name = "darling_macro"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
dependencies = [
"darling_core 0.14.4",
"quote",
"syn 1.0.109",
]
@ -800,6 +835,37 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "derive_builder"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
dependencies = [
"darling 0.14.4",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "derive_builder_macro"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
dependencies = [
"derive_builder_core",
"syn 1.0.109",
]
[[package]]
name = "derive_more"
version = "0.99.17"
@ -3957,7 +4023,7 @@ version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
dependencies = [
"darling",
"darling 0.13.4",
"proc-macro2",
"quote",
"syn 1.0.109",
@ -4738,6 +4804,7 @@ name = "triangle"
version = "0.1.0"
dependencies = [
"anyhow",
"derive_builder",
"triangle-sys",
]

View file

@ -1,2 +1,3 @@
workspace.members = ["backend", "prisma-cli", "triangle", "triangle-sys"]
workspace.resolver = "2"
workspace.default-members = ["backend"]

View file

@ -3,8 +3,6 @@ name = "backend"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.76"
axum = { version = "0.7.2", features = ["http2"] }

View file

@ -12,7 +12,7 @@ async fn main() -> Result<()> {
let app = Router::new().route("/", get(|| async { "Hello, World!" }));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
let listener = tokio::net::TcpListener::bind("0.0.0.0:1440").await?;
axum::serve(listener, app).await?;
Ok(())

17
biome.json Normal file
View file

@ -0,0 +1,17 @@
{
"$schema": "https://biomejs.dev/schemas/1.4.1/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentWidth": 2,
"indentStyle": "space"
}
}

View file

@ -1,17 +0,0 @@
{
"name": "your-project-name",
"sources": [
{
"dir": "rescript",
"subdirs": true
}
],
"package-specs": [
{
"module": "es6",
"in-source": true
}
],
"suffix": ".bs.js",
"bs-dependencies": []
}

18
frontend/.eslintrc.cjs Normal file
View file

@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}

24
frontend/.gitignore vendored Normal file
View file

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

30
frontend/README.md Normal file
View file

@ -0,0 +1,30 @@
# React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
- Configure the top-level `parserOptions` property like this:
```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list

13
frontend/index.html Normal file
View file

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

37
frontend/package.json Normal file
View file

@ -0,0 +1,37 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@blueprintjs/core": "^5.7.2",
"@blueprintjs/icons": "^5.5.0",
"@blueprintjs/table": "^5.0.20",
"@react-three/fiber": "^8.15.12",
"@types/three": "^0.160.0",
"normalize.css": "^8.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.1",
"three": "^0.160.0"
},
"devDependencies": {
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^8.55.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"sass": "^1.69.6",
"typescript": "^5.2.2",
"vite": "^5.0.8"
}
}

File diff suppressed because it is too large Load diff

1
frontend/public/vite.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

15
frontend/src/App.css Normal file
View file

@ -0,0 +1,15 @@
html,body,#root {
width: 100%;
height: 100%;
}
#root {
display: flex;
flex-direction: column;
}
#root > main {
flex-shrink: 1;
min-height: 0;
flex-grow: 1;
}

11
frontend/src/App.tsx Normal file
View file

@ -0,0 +1,11 @@
import "./App.css";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import routes from "./routes";
const router = createBrowserRouter(routes);
function App() {
return <RouterProvider router={router} />;
}
export default App;

26
frontend/src/Layout.tsx Normal file
View file

@ -0,0 +1,26 @@
import { Outlet, Link } from "react-router-dom";
import { Alignment, Icon, Navbar } from "@blueprintjs/core";
export default function Layout() {
return (
<>
<Navbar>
<Navbar.Group align={Alignment.LEFT}>
<Navbar.Heading>OpenStellaris</Navbar.Heading>
<Navbar.Divider />
<Link className="bp5-button bp5-minimal" role="button" to="/">
<Icon icon="path-search" />
Map
</Link>
<Link className="bp5-button bp5-minimal" role="button" to="/planets">
<Icon icon="panel-table" />
Planets
</Link>
</Navbar.Group>
</Navbar>
<Outlet />
</>
);
}

16
frontend/src/main.tsx Normal file
View file

@ -0,0 +1,16 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "normalize.css";
import "@blueprintjs/core/lib/css/blueprint.css";
import "@blueprintjs/icons/lib/css/blueprint-icons.css";
// biome-ignore lint/style/noNonNullAssertion: <explanation>
const el = document.getElementById("root")!;
ReactDOM.createRoot(el).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);

View file

@ -0,0 +1,40 @@
import { useRef, useState } from "react";
import { Canvas, useFrame, type MeshProps } from "@react-three/fiber";
import styles from "./MapView.module.scss";
export default function MapView() {
return (
<main className={styles.main}>
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
</main>
);
}
function Box(props: MeshProps) {
// This reference will give us direct access to the mesh
const meshRef = useRef();
// Set up state for the hovered and active state
const [hovered, setHover] = useState(false);
const [active, setActive] = useState(false);
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((_state, delta) => (meshRef.current.rotation.x += delta));
// Return view, these are regular three.js elements expressed in JSX
return (
<mesh
{...props}
ref={meshRef}
scale={active ? 1.5 : 1}
onClick={(_event) => setActive(!active)}
onPointerOver={(_event) => setHover(true)}
onPointerOut={(_event) => setHover(false)}
>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
</mesh>
);
}

View file

@ -0,0 +1,3 @@
export default function PlanetsView() {
return <main>Planets</main>;
}

View file

@ -0,0 +1,23 @@
import type { RouteObject } from "react-router-dom";
import Layout from "../Layout";
import MapView from "./MapView";
import PlanetsView from "./PlanetsView";
const routes: RouteObject[] = [
{
path: "/",
element: <Layout />,
children: [
{
path: "/",
element: <MapView />,
},
{
path: "/planets",
element: <PlanetsView />,
},
],
},
];
export default routes;

1
frontend/src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite/client" />

25
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

16
frontend/vite.config.ts Normal file
View file

@ -0,0 +1,16 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api": {
target: "http://localhost:1440",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});

3779
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,44 +0,0 @@
{
"name": "openstellaris",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.27.4",
"@types/delaunator": "^5.0.2",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^2.30.0",
"prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.0.0",
"prisma": "^5.7.0",
"rescript": "^10.1.4",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.2",
"vitest": "^0.34.0"
},
"type": "module",
"dependencies": {
"@auth/core": "^0.18.4",
"@auth/prisma-adapter": "^1.0.9",
"@auth/sveltekit": "^0.3.15",
"@prisma/client": "5.7.0",
"delaunator": "^5.0.0",
"sass": "^1.69.5"
}
}

12
src/app.d.ts vendored
View file

@ -1,12 +0,0 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export {};

View file

@ -1,12 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View file

@ -1,25 +0,0 @@
import {
AUTH_SECRET,
DISCORD_CLIENT_ID,
DISCORD_CLIENT_SECRET,
} from "$env/static/private";
import Discord from "@auth/core/providers/discord";
import { SvelteKitAuth } from "@auth/sveltekit";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export const handle = SvelteKitAuth(async (event) => {
return {
secret: AUTH_SECRET,
trustHost: true,
adapter: PrismaAdapter(prisma),
providers: [
Discord({
clientId: DISCORD_CLIENT_ID,
clientSecret: DISCORD_CLIENT_SECRET,
}),
],
};
});

View file

@ -1,7 +0,0 @@
import { describe, it, expect } from "vitest";
describe("sum test", () => {
it("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
});

View file

@ -1 +0,0 @@
// place files you want to import through the `$lib` alias in this folder.

View file

@ -1,144 +0,0 @@
import Delaunator from "delaunator";
import { euclideanDistance, lawOfCosines } from "./math";
export interface MapGenOptions {
numSystems?: number;
}
export interface MapGenResult {
nodes: { x: number; y: number }[];
adj: Map<number, Set<number>>;
}
export default function mapGen(opts: MapGenOptions = {}): MapGenResult {
const nodes = [];
const adj = new Map<number, Set<number>>();
const numSystems = opts.numSystems ?? 1000;
for (let i = 0; i < numSystems; ++i) {
nodes.push({
x: Math.floor(Math.random() * 800),
y: Math.floor(Math.random() * 600),
});
}
// Remove nodes that are too close
// eslint-disable-next-line no-constant-condition
while (true) {
let idx = null;
let ctr = 0;
for (const node of nodes) {
for (const otherNode of nodes) {
if (node == otherNode) continue;
const dist = euclideanDistance(
node.x,
node.y,
otherNode.x,
otherNode.y,
);
if (dist < 25) {
idx = ctr;
break;
}
}
if (idx !== null) break;
ctr += 1;
}
if (idx !== null) nodes.splice(idx, 1);
else break;
}
// Generate edges
const delaunay = new Delaunator(nodes.flatMap((node) => [node.x, node.y]));
console.log("result", delaunay);
for (let i = 0; i < delaunay.triangles.length; i += 3) {
const a = delaunay.triangles[i];
const b = delaunay.triangles[i + 1];
const c = delaunay.triangles[i + 2];
const an = nodes[a];
const bn = nodes[b];
const cn = nodes[c];
const ab = euclideanDistance(an.x, an.y, bn.x, bn.y);
const ac = euclideanDistance(an.x, an.y, cn.x, cn.y);
const bc = euclideanDistance(bn.x, bn.y, cn.x, cn.y);
const angA = lawOfCosines(bc, ab, ac);
const angB = lawOfCosines(ac, bc, ab);
const angC = lawOfCosines(ab, bc, ac);
const threshold = Math.PI / 6;
if (angA < threshold || angB < threshold || angC < threshold) {
continue;
}
if (!adj.has(a)) adj.set(a, new Set());
if (!adj.has(b)) adj.set(b, new Set());
if (!adj.has(c)) adj.set(c, new Set());
adj.get(a)?.add(b);
adj.get(a)?.add(c);
adj.get(b)?.add(a);
adj.get(b)?.add(c);
adj.get(c)?.add(a);
adj.get(c)?.add(b);
}
// Remove hull
const hull = new Set(delaunay.hull);
for (const [nodeIdx, neighborIdxs] of adj) {
if (!hull.has(nodeIdx)) continue;
for (const neighborIdx of neighborIdxs) {
if (hull.has(neighborIdx)) {
adj.get(nodeIdx)?.delete(neighborIdx);
}
}
}
// Randomly remove some edges
// for (const [nodeIdx, neighborIdxs] of adj) {
// const numNeighbors = neighborIdxs.size;
// // Reverse weight
// const weightSlices = ((numNeighbors + 1) * numNeighbors) / 2;
// const sliceWidth = 1 / weightSlices;
// const roll = Math.random();
// const whichSlice = Math.floor(roll / sliceWidth);
// const whichTriangleNum = Math.floor(
// (-1 + Math.sqrt(1 + 8 * whichSlice)) / 2,
// );
// const actualWeight = numNeighbors - whichTriangleNum;
// const toRemove = numNeighbors - actualWeight;
// const asArray = [...neighborIdxs];
// const toRemoveSet = new Set();
// while (toRemoveSet.size < toRemove) {
// const idx = Math.floor(Math.random() * asArray.length);
// toRemoveSet.add(idx);
// }
// const newArray = [];
// for (let i = 0; i < asArray.length; ++i) {
// if (toRemoveSet.has(i)) continue;
// newArray.push(asArray[i]);
// }
// adj.set(nodeIdx, new Set(newArray));
// }
// Make sure each edge has a reverse edge
for (const [nodeIdx, neighborIdxs] of adj) {
for (const neighborIdx of neighborIdxs) {
adj.get(neighborIdx)?.add(nodeIdx);
}
}
return { nodes, adj };
}

View file

@ -1,18 +0,0 @@
export function euclideanDistance(
x1: number,
y1: number,
x2: number,
y2: number,
): number {
return Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
}
export function lawOfCosines(
opposite: number,
other1: number,
other2: number,
): number {
return Math.acos(
(other1 ** 2 + other2 ** 2 - opposite ** 2) / (2 * other1 * other2),
);
}

View file

@ -1,5 +0,0 @@
type empireId = {id: string}
type coreState = {id: string}
type derivedState = {id: string, energy: number, minerals: number, food: number, alloys: number}

View file

@ -1,10 +0,0 @@
type coreState = {
startTime: Js.Date.t,
decisionTime: Js.Date.t,
empires: Belt.Map.t<string, Empires.coreState, string>,
}
type derivedState = {
instant: Js.Date.t,
empires: Belt.Map.t<string, Empires.derivedState, string>,
}

View file

@ -1 +0,0 @@
type coreState = {}

View file

@ -1 +0,0 @@

View file

@ -1,5 +0,0 @@
export const load = async (event) => {
return {
session: await event.locals.getSession(),
};
};

View file

@ -1,16 +0,0 @@
<script lang="ts">
import { signIn, signOut } from "@auth/sveltekit/client";
import { page } from "$app/stores";
</script>
SHIET
{JSON.stringify($page.data.session)}
{#if $page.data.session}
<button on:click={() => signOut()}>Sign out</button>
{:else}
<button on:click={() => signIn()}>Sign In</button>
{/if}
<slot />

View file

@ -1,4 +0,0 @@
<h1>Welcome to SvelteKit</h1>
<p>
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
</p>

View file

@ -1,55 +0,0 @@
import mapGen from "$lib/mapGen.js";
import { PrismaClient } from "@prisma/client";
import { redirect } from "@sveltejs/kit";
export const actions = {
default: async () => {
const prisma = new PrismaClient();
// Create everything in a transaction
const { universeId } = await prisma.$transaction(async (client) => {
const result = await client.universe.create({
data: { config: { hello: "world" } },
});
const universeId = result.id;
const generatedMap = mapGen();
await client.starSystem.createMany({
data: generatedMap.nodes.map(({ x, y }) => ({
universeId,
coordX: x,
coordY: y,
})),
});
await client.starSystemEdges.createMany({
data: [...generatedMap.adj.entries()]
.flatMap(([nodeIdx, neighbors]) =>
[...neighbors].map((neighbor) => [nodeIdx, neighbor]),
)
.filter(([aIdx, bIdx]) => {
const a = generatedMap.nodes[aIdx];
const b = generatedMap.nodes[bIdx];
return a.x <= b.x ? (a.x == b.x ? a.y <= b.y : true) : false;
})
.map(([aIdx, bIdx]) => {
const a = generatedMap.nodes[aIdx];
const b = generatedMap.nodes[bIdx];
return {
universeId,
fromX: a.x,
fromY: a.y,
toX: b.x,
toY: b.y,
};
}),
});
return { universeId };
});
// console.log("Helloge", result.id);
throw redirect(301, `/game/${universeId}`);
},
};

View file

@ -1,5 +0,0 @@
Helloge
<form method="POST">
<button type="submit">Create Game</button>
</form>

View file

@ -1,6 +0,0 @@
import { redirect } from "@sveltejs/kit";
export function load({ params }) {
// console.log("params", params);
throw redirect(307, `/game/${params.id}/createEmpire`);
}

View file

@ -1,12 +0,0 @@
<h1>Create Empire</h1>
<form>
<p>
<label>
Empire Name
<input type="text" />
</label>
</p>
<button type="submit">Create Empire</button>
</form>

View file

@ -1,57 +0,0 @@
<script lang="ts">
import mapGen from "$lib/mapGen";
import { onMount } from "svelte";
let canvas: HTMLCanvasElement;
function generate() {
console.log("helloge", canvas);
const ctx = canvas.getContext("2d")!;
ctx.clearRect(0, 0, 800, 600);
const generatedMap = mapGen();
ctx.strokeStyle = "lightgray";
for (const [nodeIdx, neighborIdxs] of generatedMap.adj.entries()) {
const node = generatedMap.nodes[nodeIdx];
for (const neighborIdx of neighborIdxs) {
const neighbor = generatedMap.nodes[neighborIdx];
ctx.beginPath();
ctx.moveTo(node.x, node.y);
ctx.lineTo(neighbor.x, neighbor.y);
ctx.stroke();
}
}
const size = 3;
let ctr = 0;
for (const node of generatedMap.nodes) {
const neighbors = generatedMap.adj.get(ctr);
if (neighbors?.size == 0) continue;
ctx.beginPath();
ctx.ellipse(node.x, node.y, size, size, 0, 0, 2 * Math.PI);
ctx.fill();
ctr += 1;
}
}
onMount(() => {
generate();
});
</script>
<div>
<button on:click={() => generate()}>Generate</button>
</div>
<div>
<canvas class="canvas" bind:this={canvas} width="800" height="600"></canvas>
</div>
<style lang="scss" scoped>
.canvas {
border: 1px solid black;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,18 +0,0 @@
import adapter from "@sveltejs/adapter-auto";
import { vitePreprocess } from "@sveltejs/kit/vite";
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
},
};
export default config;

1
triangle/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
src/tricall.c

View file

@ -5,4 +5,5 @@ edition = "2021"
[dependencies]
anyhow = "1.0.76"
derive_builder = "0.12.0"
triangle-sys = { path = "../triangle-sys" }

View file

@ -1,51 +1,92 @@
use anyhow::Result;
use std::{ffi::CString, mem::MaybeUninit, ptr};
#[macro_use]
extern crate derive_builder;
extern crate triangle_sys as sys;
pub struct TrianglulateOptions {}
#[cfg(test)]
mod tests;
pub struct TriangulateResult {}
use std::{ffi::CString, mem::MaybeUninit, ptr};
pub fn triangulate(opts: TrianglulateOptions) -> Result<TriangulateResult> {
let switches = CString::new("")?;
use anyhow::Result;
let mut input = sys::triangulateio {
pointlist: todo!(),
pointattributelist: todo!(),
pointmarkerlist: todo!(),
numberofpoints: todo!(),
numberofpointattributes: todo!(),
trianglelist: todo!(),
triangleattributelist: todo!(),
trianglearealist: todo!(),
neighborlist: todo!(),
numberoftriangles: todo!(),
numberofcorners: todo!(),
numberoftriangleattributes: todo!(),
segmentlist: todo!(),
segmentmarkerlist: todo!(),
numberofsegments: todo!(),
holelist: todo!(),
numberofholes: todo!(),
regionlist: todo!(),
numberofregions: todo!(),
edgelist: todo!(),
edgemarkerlist: todo!(),
normlist: todo!(),
numberofedges: todo!(),
};
let mut output = MaybeUninit::<sys::triangulateio>::uninit();
#[derive(Builder)]
pub struct TrianglulateOpts<P> {
point_list: P,
/// Generates a Voronoi diagram
#[builder(default)]
voronoi: bool,
}
impl<P: Clone> TrianglulateOpts<P> {
pub fn builder() -> TrianglulateOptsBuilder<P> {
TrianglulateOptsBuilder::default()
}
}
#[derive(Clone, Copy, Debug)]
pub struct Point {
x: f64,
y: f64,
}
#[derive(Debug)]
pub struct TriangulateResult {
pub point_list: Vec<Point>,
}
pub fn triangulate<P>(opts: TrianglulateOpts<P>) -> Result<TriangulateResult>
where
P: IntoIterator<Item = Point>,
{
let mut switches = Vec::new();
if opts.voronoi {
switches.push("v");
}
let switches = CString::new(switches.join(""))?;
let point_list = opts.point_list.into_iter().collect::<Vec<_>>();
let mut flat_point_list = point_list
.iter()
.flat_map(|point| [point.x, point.y])
.collect::<Vec<_>>();
let input = MaybeUninit::<sys::triangulateio>::uninit();
let output = MaybeUninit::<sys::triangulateio>::uninit();
let mut vorout = ptr::null::<sys::triangulateio>();
let mut input = unsafe { input.assume_init() };
let mut output = unsafe { output.assume_init() };
input.pointlist = flat_point_list.as_mut_ptr();
input.numberofpoints = point_list.len() as i32;
// TODO: Implement point attributes
input.numberofpointattributes = 0;
unsafe {
sys::triangulate(
switches.as_ptr() as *mut _,
&mut input as *mut _,
output.as_mut_ptr(),
&mut output as *mut _,
vorout as *mut _,
)
};
Ok(TriangulateResult {})
let flat_point_list = unsafe {
Vec::from_raw_parts(
output.pointlist,
output.numberofpoints as usize * 2,
output.numberofpoints as usize * 2,
)
};
let point_list = flat_point_list
.chunks(2)
.map(|points| Point {
x: points[0],
y: points[1],
})
.collect::<Vec<_>>();
Ok(TriangulateResult { point_list })
}

17
triangle/src/tests.rs Normal file
View file

@ -0,0 +1,17 @@
use crate::{triangulate, Point, TrianglulateOpts};
#[test]
fn test_tricall() {
let opts = TrianglulateOpts::builder()
.point_list([
Point { x: 0.0, y: 0.0 },
Point { x: 1.0, y: 0.0 },
Point { x: 1.0, y: 10.0 },
Point { x: 0.0, y: 10.0 },
])
.build()
.unwrap();
let result = triangulate(opts).unwrap();
panic!("Result: {:?}", result);
}

View file

@ -1,18 +0,0 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View file

@ -1,9 +0,0 @@
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ["src/**/*.{test,spec}.{js,ts}"],
},
});