mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
Merge pull request #66 from neocturne/docker
Watch mode and Docker publish
This commit is contained in:
commit
901489dbc3
13 changed files with 413 additions and 31 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
*
|
||||
!/Cargo.*
|
||||
!/src
|
||||
!/crates
|
91
.github/workflows/MinedMap.yml
vendored
91
.github/workflows/MinedMap.yml
vendored
|
@ -1,5 +1,14 @@
|
|||
name: 'MinedMap'
|
||||
on: ['push', 'pull_request', 'workflow_dispatch']
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
RUSTFLAGS: -Dwarnings
|
||||
|
@ -7,7 +16,7 @@ env:
|
|||
|
||||
jobs:
|
||||
viewer:
|
||||
runs-on: 'ubuntu-20.04'
|
||||
runs-on: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
|
@ -25,6 +34,7 @@ jobs:
|
|||
pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-viewer'
|
||||
mkdir -p "$pkgdir"
|
||||
cp -r viewer/* "$pkgdir"/
|
||||
rm "$pkgdir"/Dockerfile
|
||||
|
||||
- name: 'Archive'
|
||||
uses: 'actions/upload-artifact@v4'
|
||||
|
@ -101,7 +111,7 @@ jobs:
|
|||
- os: 'windows-2019'
|
||||
target: 'i686-pc-windows-msvc'
|
||||
ext: '.exe'
|
||||
- os: 'ubuntu-20.04'
|
||||
- os: 'ubuntu-22.04'
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
|
||||
steps:
|
||||
|
@ -138,3 +148,78 @@ jobs:
|
|||
with:
|
||||
name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}'
|
||||
path: 'target/pkg'
|
||||
|
||||
build-container:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- test
|
||||
steps:
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/neocturne/minedmap/minedmap
|
||||
tags: |
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=ref,event=branch
|
||||
type=ref,event=branch,suffix=-{{sha}}
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
viewer-container:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- test
|
||||
steps:
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/neocturne/minedmap/viewer
|
||||
tags: |
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=ref,event=branch
|
||||
type=ref,event=branch,suffix=-{{sha}}
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: "{{defaultContext}}:viewer"
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -4,6 +4,22 @@
|
|||
|
||||
### Added
|
||||
|
||||
- Added experimental watch mode
|
||||
|
||||
Passing `--watch` will cause MinedMap to run continuously instead of exiting
|
||||
after map generation, regenerating tiles whenever they change.
|
||||
|
||||
`--watch-delay` can be used to configure the delay between detecting a change
|
||||
and runing the map generation, also limiting how often the regeneration
|
||||
happens. This defaults to `30s`; significantly smaller values probably don't
|
||||
make sense because Minecraft writes out changes in batches anyways.
|
||||
|
||||
Finally, `--jobs-initial` can be used to configure the number of parallel
|
||||
generation threads for the initial cycle separately from the value used for
|
||||
subsequent cycles after a change is detected (`-j`/`--jobs`). Subsequent
|
||||
cycles usually need to regenerate only a small number of tiles, so setting
|
||||
`--jobs` to a smaller value than `--jobs-initial` may be advantageous.
|
||||
|
||||
- Added jemalloc support to fix performace on musl targets
|
||||
|
||||
The global allocator can be switched to jemalloc by enabling the `jemalloc`
|
||||
|
|
170
Cargo.lock
generated
170
Cargo.lock
generated
|
@ -68,7 +68,7 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -79,7 +79,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
|||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -321,7 +321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -345,6 +345,18 @@ dependencies = [
|
|||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.35"
|
||||
|
@ -362,6 +374,15 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
|
@ -454,6 +475,12 @@ version = "0.3.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.5"
|
||||
|
@ -488,6 +515,26 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
|
@ -518,6 +565,26 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
@ -530,6 +597,17 @@ version = "0.2.169"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-ng-sys"
|
||||
version = "1.1.21"
|
||||
|
@ -588,6 +666,7 @@ dependencies = [
|
|||
"fastnbt",
|
||||
"futures-util",
|
||||
"git-version",
|
||||
"humantime",
|
||||
"image",
|
||||
"indexmap",
|
||||
"lru",
|
||||
|
@ -595,6 +674,7 @@ dependencies = [
|
|||
"minedmap-nbt",
|
||||
"minedmap-resource",
|
||||
"minedmap-types",
|
||||
"notify",
|
||||
"num-integer",
|
||||
"num_cpus",
|
||||
"phf",
|
||||
|
@ -656,6 +736,43 @@ dependencies = [
|
|||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"log",
|
||||
"mio",
|
||||
"notify-types",
|
||||
"walkdir",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-types"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -930,7 +1047,7 @@ dependencies = [
|
|||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -939,6 +1056,15 @@ version = "1.0.19"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
|
@ -1052,7 +1178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1171,6 +1297,22 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -1187,12 +1329,30 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
|
|
|
@ -44,6 +44,7 @@ enum-map = "2.7.3"
|
|||
fastnbt = "2.3.2"
|
||||
futures-util = "0.3.28"
|
||||
git-version = "0.3.5"
|
||||
humantime = "2.1.0"
|
||||
image = { version = "0.25.1", default-features = false, features = ["png", "webp"] }
|
||||
indexmap = { version = "2.0.0", features = ["serde"] }
|
||||
lru = "0.13.0"
|
||||
|
@ -51,6 +52,7 @@ minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", opt
|
|||
minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false }
|
||||
minedmap-resource = { version = "0.6.0", path = "crates/resource" }
|
||||
minedmap-types = { version = "0.1.4", path = "crates/types" }
|
||||
notify = "8.0.0"
|
||||
num-integer = "0.1.45"
|
||||
num_cpus = "1.16.0"
|
||||
phf = { version = "0.11.2", features = ["macros"] }
|
||||
|
|
17
Dockerfile
17
Dockerfile
|
@ -1,14 +1,15 @@
|
|||
FROM docker.io/library/rust:alpine AS BUILDER
|
||||
FROM docker.io/library/alpine:latest AS builder
|
||||
|
||||
WORKDIR /build
|
||||
RUN apk update && apk add cmake build-base
|
||||
RUN apk add --no-cache build-base cmake cargo
|
||||
|
||||
COPY src /build/src
|
||||
COPY crates /build/crates
|
||||
COPY Cargo.toml Cargo.lock /build
|
||||
COPY . .
|
||||
RUN cargo build -r
|
||||
RUN strip target/release/minedmap
|
||||
|
||||
FROM scratch AS RUNNER
|
||||
FROM docker.io/library/alpine:latest
|
||||
|
||||
COPY --from=BUILDER /build/target/release/minedmap /minedmap
|
||||
ENTRYPOINT [ "/minedmap" ]
|
||||
RUN apk add --no-cache libgcc tini
|
||||
|
||||
COPY --from=builder /build/target/release/minedmap /bin/minedmap
|
||||
ENTRYPOINT [ "/sbin/tini", "--", "/bin/minedmap" ]
|
||||
|
|
|
@ -135,10 +135,14 @@ pub enum TileKind {
|
|||
pub struct Config {
|
||||
/// Number of threads for parallel processing
|
||||
pub num_threads: usize,
|
||||
/// Number of threads for initial parallel processing
|
||||
pub num_threads_initial: usize,
|
||||
/// Path of input region directory
|
||||
pub region_dir: PathBuf,
|
||||
/// Path of input `level.dat` file
|
||||
pub level_dat_path: PathBuf,
|
||||
/// Path of input `level.dat_old` file
|
||||
pub level_dat_old_path: PathBuf,
|
||||
/// Base path for storage of rendered tile data
|
||||
pub output_dir: PathBuf,
|
||||
/// Path for storage of intermediate processed data files
|
||||
|
@ -167,9 +171,13 @@ impl Config {
|
|||
Some(threads) => threads,
|
||||
None => 1,
|
||||
};
|
||||
let num_threads_initial = args.jobs_initial.unwrap_or(num_threads);
|
||||
|
||||
let region_dir = [&args.input_dir, Path::new("region")].iter().collect();
|
||||
let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect();
|
||||
let level_dat_old_path = [&args.input_dir, Path::new("level.dat_old")]
|
||||
.iter()
|
||||
.collect();
|
||||
let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect();
|
||||
let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect();
|
||||
let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect();
|
||||
|
@ -184,8 +192,10 @@ impl Config {
|
|||
|
||||
Ok(Config {
|
||||
num_threads,
|
||||
num_threads_initial,
|
||||
region_dir,
|
||||
level_dat_path,
|
||||
level_dat_old_path,
|
||||
output_dir: args.output_dir.clone(),
|
||||
processed_dir,
|
||||
entities_dir,
|
||||
|
|
|
@ -124,7 +124,14 @@ impl<'a> MetadataWriter<'a> {
|
|||
|
||||
/// Reads and deserializes the `level.dat` of the Minecraft save data
|
||||
fn read_level_dat(&self) -> Result<de::LevelDat> {
|
||||
crate::nbt::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat")
|
||||
let res = crate::nbt::data::from_file(&self.config.level_dat_path);
|
||||
if res.is_err() {
|
||||
if let Ok(level_dat_old) = crate::nbt::data::from_file(&self.config.level_dat_old_path)
|
||||
{
|
||||
return Ok(level_dat_old);
|
||||
}
|
||||
}
|
||||
res.context("Failed to read level.dat")
|
||||
}
|
||||
|
||||
/// Generates [Spawn] data from a [de::LevelDat]
|
||||
|
|
116
src/core/mod.rs
116
src/core/mod.rs
|
@ -10,7 +10,12 @@ mod tile_merger;
|
|||
mod tile_mipmapper;
|
||||
mod tile_renderer;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::mpsc::{self, Receiver},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Parser;
|
||||
|
@ -18,9 +23,13 @@ use git_version::git_version;
|
|||
|
||||
use common::{Config, ImageFormat};
|
||||
use metadata_writer::MetadataWriter;
|
||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher as _};
|
||||
use rayon::ThreadPool;
|
||||
use region_processor::RegionProcessor;
|
||||
use tile_mipmapper::TileMipmapper;
|
||||
use tile_renderer::TileRenderer;
|
||||
use tokio::runtime::Runtime;
|
||||
use tracing::{info, warn};
|
||||
|
||||
use self::entity_collector::EntityCollector;
|
||||
|
||||
|
@ -44,9 +53,26 @@ pub struct Args {
|
|||
/// use one thread per logical CPU core.
|
||||
#[arg(short, long)]
|
||||
pub jobs: Option<usize>,
|
||||
/// Number of parallel threads to use for initial processing
|
||||
///
|
||||
/// Passing this option only makes sense with --watch. The first run after
|
||||
/// starting MinedMap will use as many parallel jobs as configured using
|
||||
/// --job-initial, while subsequent regenerations of tiles will use the
|
||||
/// the number configured using --jobs.
|
||||
///
|
||||
/// If not given, the value from the --jobs option is used.
|
||||
#[arg(long)]
|
||||
pub jobs_initial: Option<usize>,
|
||||
/// Enable verbose messages
|
||||
#[arg(short, long)]
|
||||
pub verbose: bool,
|
||||
/// Watch for file changes and regenerate tiles automatically instead of
|
||||
/// exiting after generation
|
||||
#[arg(long)]
|
||||
pub watch: bool,
|
||||
/// Minimum delay between map generation cycles in watch mode
|
||||
#[arg(long, value_parser = humantime::parse_duration, default_value = "30s")]
|
||||
pub watch_delay: Duration,
|
||||
/// Format of generated map tiles
|
||||
#[arg(long, value_enum, default_value_t)]
|
||||
pub image_format: ImageFormat,
|
||||
|
@ -74,14 +100,73 @@ pub struct Args {
|
|||
pub output_dir: PathBuf,
|
||||
}
|
||||
|
||||
/// Configures the Rayon thread pool for parallel processing
|
||||
fn setup_threads(num_threads: usize) -> Result<()> {
|
||||
/// Configures a Rayon thread pool for parallel processing
|
||||
fn setup_threads(num_threads: usize) -> Result<ThreadPool> {
|
||||
rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(num_threads)
|
||||
.build_global()
|
||||
.build()
|
||||
.context("Failed to configure thread pool")
|
||||
}
|
||||
|
||||
/// Runs all MinedMap generation steps, updating all tiles as needed
|
||||
fn generate(config: &Config, rt: &Runtime) -> Result<()> {
|
||||
let regions = RegionProcessor::new(config).run()?;
|
||||
TileRenderer::new(config, rt, ®ions).run()?;
|
||||
let tiles = TileMipmapper::new(config, ®ions).run()?;
|
||||
EntityCollector::new(config, ®ions).run()?;
|
||||
MetadataWriter::new(config, &tiles).run()
|
||||
}
|
||||
|
||||
/// Creates a file watcher for the
|
||||
fn create_watcher(args: &Args) -> Result<(RecommendedWatcher, Receiver<()>)> {
|
||||
let (tx, rx) = mpsc::sync_channel::<()>(1);
|
||||
let mut watcher = notify::recommended_watcher(move |res| {
|
||||
// Ignore errors - we already have a watch trigger queued if try_send() fails
|
||||
let event: notify::Event = match res {
|
||||
Ok(event) => event,
|
||||
Err(err) => {
|
||||
warn!("Watch error: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let notify::EventKind::Modify(modify_kind) = event.kind else {
|
||||
return;
|
||||
};
|
||||
if !matches!(
|
||||
modify_kind,
|
||||
notify::event::ModifyKind::Data(_)
|
||||
| notify::event::ModifyKind::Name(notify::event::RenameMode::To)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if !event
|
||||
.paths
|
||||
.iter()
|
||||
.any(|path| path.ends_with("level.dat") || path.extension() == Some("mcu".as_ref()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
let _ = tx.try_send(());
|
||||
})?;
|
||||
watcher.watch(&args.input_dir, RecursiveMode::Recursive)?;
|
||||
Ok((watcher, rx))
|
||||
}
|
||||
|
||||
/// Watches the data directory for changes, returning when a change has happened
|
||||
fn wait_watcher(args: &Args, watch_channel: &Receiver<()>) -> Result<()> {
|
||||
info!("Watching for changes...");
|
||||
let () = watch_channel
|
||||
.recv()
|
||||
.context("Failed to read watch event channel")?;
|
||||
info!("Change detected.");
|
||||
|
||||
thread::sleep(args.watch_delay);
|
||||
|
||||
let _ = watch_channel.try_recv();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// MinedMap CLI main function
|
||||
pub fn cli() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
@ -96,17 +181,26 @@ pub fn cli() -> Result<()> {
|
|||
.with_target(false)
|
||||
.init();
|
||||
|
||||
setup_threads(config.num_threads)?;
|
||||
let mut pool = setup_threads(config.num_threads_initial)?;
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let regions = RegionProcessor::new(&config).run()?;
|
||||
TileRenderer::new(&config, &rt, ®ions).run()?;
|
||||
let tiles = TileMipmapper::new(&config, ®ions).run()?;
|
||||
EntityCollector::new(&config, ®ions).run()?;
|
||||
MetadataWriter::new(&config, &tiles).run()?;
|
||||
let watch = args.watch.then(|| create_watcher(&args)).transpose()?;
|
||||
|
||||
Ok(())
|
||||
pool.install(|| generate(&config, &rt))?;
|
||||
|
||||
let Some((_watcher, watch_channel)) = watch else {
|
||||
// watch mode disabled
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if config.num_threads != config.num_threads_initial {
|
||||
pool = setup_threads(config.num_threads)?;
|
||||
}
|
||||
pool.install(move || loop {
|
||||
wait_watcher(&args, &watch_channel)?;
|
||||
generate(&config, &rt)?;
|
||||
})
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ impl<'a> TileRenderer<'a> {
|
|||
/// Hashing the value as a single u32 is more efficient than hashing
|
||||
/// the tuple elements separately.
|
||||
fn biome_key((dx, dz, index): (i8, i8, u16)) -> u32 {
|
||||
(dx as u8 as u32) | (dz as u8 as u32) << 8 | (index as u32) << 16
|
||||
(dx as u8 as u32) | ((dz as u8 as u32) << 8) | ((index as u32) << 16)
|
||||
}
|
||||
|
||||
/// One quadrant of the kernel used to smooth biome edges
|
||||
|
|
|
@ -39,7 +39,9 @@ pub fn to_flat_coord<const AXIS: u8>(
|
|||
chunk: ChunkCoord<AXIS>,
|
||||
block: BlockCoord<AXIS>,
|
||||
) -> i32 {
|
||||
(region as i32) << (BLOCK_BITS + CHUNK_BITS) | ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32)
|
||||
((region as i32) << (BLOCK_BITS + CHUNK_BITS))
|
||||
| ((chunk.0 as i32) << BLOCK_BITS)
|
||||
| (block.0 as i32)
|
||||
}
|
||||
|
||||
/// Splits a flat (linear) coordinate into region, chunk and block numbers
|
||||
|
|
1
viewer/.dockerignore
Normal file
1
viewer/.dockerignore
Normal file
|
@ -0,0 +1 @@
|
|||
/data
|
|
@ -1,3 +1,3 @@
|
|||
FROM docker.io/library/nginx:alpine
|
||||
COPY viewer /usr/share/nginx/html
|
||||
COPY . /usr/share/nginx/html
|
||||
# datadir should be mounted to: /usr/share/nginx/html/data
|
Loading…
Add table
Reference in a new issue