Add cache format and render block state map

This commit is contained in:
Misode
2020-12-20 05:02:11 +01:00
parent a52716a80a
commit 647a435930
3 changed files with 44 additions and 42 deletions

View File

@@ -40,7 +40,7 @@ export const Models: {
config.models.filter(m => m.schema)
.forEach(m => Models[m.id] = new DataModel(ObjectNode({})))
export const BlockStateRegistry: {
export let BlockStateRegistry: {
[block: string]: {
properties: {
[key: string]: string[]
@@ -106,6 +106,7 @@ App.mobilePanel.watchRun((value) => {
})
async function updateSchemas(version: string) {
BlockStateRegistry = {}
const collections = Versions[version].getCollections()
await fetchData(collections, version)
const schemas = Versions[version].getSchemas(collections)

View File

@@ -2,6 +2,8 @@ import { CollectionRegistry } from '@mcschema/core'
import { BlockStateRegistry, checkVersion } from './App'
import config from '../config.json'
const CACHE_FORMAT = 1
type VersionConfig = {
id: string,
mcdata_ref: string
@@ -27,59 +29,54 @@ export const fetchData = async (target: CollectionRegistry, versionId: string) =
if (!version) return
const cache = JSON.parse(localStorage.getItem(localStorageCache(versionId)) ?? '{}')
const cacheValid = version.mcdata_ref !== 'master' || cache.mcdata_hash === __MCDATA_MASTER_HASH__
const cacheValid = cache.format === CACHE_FORMAT && (version.mcdata_ref !== 'master' || cache.mcdata_hash === __MCDATA_MASTER_HASH__)
const cacheDirty = (await Promise.all([
await Promise.all([
fetchRegistries(target, version, cache, cacheValid),
fetchBlockStateMap(version, cache, cacheValid)
])).some(v => v)
])
if (cacheDirty) {
if (!cacheValid) {
if (version.mcdata_ref === 'master') {
cache.mcdata_hash = __MCDATA_MASTER_HASH__
}
cache.format = CACHE_FORMAT
localStorage.setItem(localStorageCache(versionId), JSON.stringify(cache))
}
}
const fetchRegistries = async (target: CollectionRegistry, version: VersionConfig, cache: any, cacheValid: boolean) => {
let cacheDirty = false
if (!cache.registries) cache.registries = {}
if (cacheValid && cache.registries) {
config.registries.forEach((r: string | RegistryConfig) => {
if (typeof r === 'string') r = { id: r }
if (!checkVersion(version.id, r.minVersion, r.maxVersion)) return
target.register(r.id, cache.registries[r.id])
})
return
}
cache.registries = {}
if (checkVersion('1.15', version.id)) {
const url = `${baseUrl}/${version.mcdata_ref}/generated/reports/registries.json`
if (cacheValid && cache.registries) {
config.registries.forEach((r: string | RegistryConfig) => {
try {
const res = await fetch(url)
const data = await res.json()
config.registries.forEach(async (r: string | RegistryConfig) => {
if (typeof r === 'string') r = { id: r }
if (!checkVersion(version.id, r.minVersion, r.maxVersion)) return
target.register(r.id, cache.registries[r.id])
const values = Object.keys(data[`minecraft:${r.id}`].entries)
target.register(r.id, values)
cache.registries[r.id] = values
})
} else {
try {
const res = await fetch(url)
const data = await res.json()
config.registries.forEach(async (r: string | RegistryConfig) => {
if (typeof r === 'string') r = { id: r }
if (!checkVersion(version.id, r.minVersion, r.maxVersion)) return
const values = Object.keys(data[`minecraft:${r.id}`].entries)
target.register(r.id, values)
cache.registries[r.id] = values
cacheDirty = true
})
} catch (e) {
console.warn(`Error occurred while fetching registries for version ${version.id}`)
}
} catch (e) {
console.warn(`Error occurred while fetching registries for version ${version.id}`)
}
} else {
await Promise.all(config.registries.map(async (r: string | RegistryConfig) => {
if (typeof r === 'string') r = { id: r }
if (!checkVersion(version.id, r.minVersion, r.maxVersion)) return
if (cacheValid && cache.registries?.[r.id]) {
target.register(r.id, cache.registries[r.id])
return
}
const url = r.path
? `${baseUrl}/${version.mcdata_ref}/${r.path}/data.min.json`
@@ -91,13 +88,11 @@ const fetchRegistries = async (target: CollectionRegistry, version: VersionConfi
target.register(r.id, data.values)
cache.registries[r.id] = data.values
cacheDirty = true
} catch (e) {
console.warn(`Error occurred while fetching registry "${r.id}":`, e)
}
}))
}
return cacheDirty
}
const fetchBlockStateMap = async (version: VersionConfig, cache: any, cacheValid: boolean) => {
@@ -105,9 +100,10 @@ const fetchBlockStateMap = async (version: VersionConfig, cache: any, cacheValid
Object.keys(cache.block_state_map).forEach(block => {
BlockStateRegistry[block] = cache.block_state_map[block]
})
return false
return
}
cache.block_state_map = {}
const url = (checkVersion(version.id, undefined, '1.15'))
? `${baseUrl}/${version.mcdata_ref}/generated/reports/blocks.json`
: `${baseUrl}/${version.mcdata_ref}/processed/reports/blocks/data.min.json`
@@ -115,7 +111,6 @@ const fetchBlockStateMap = async (version: VersionConfig, cache: any, cacheValid
const res = await fetch(url)
const data = await res.json()
cache.block_state_map = {}
Object.keys(data).forEach(block => {
const res = {
properties: data[block].properties,
@@ -124,6 +119,4 @@ const fetchBlockStateMap = async (version: VersionConfig, cache: any, cacheValid
BlockStateRegistry[block] = res
cache.block_state_map[block] = res
})
return true
}

View File

@@ -1,10 +1,10 @@
import { Hook, ModelPath, Path, StringHookParams, ValidationOption, EnumOption, INode, DataModel, MapNode, StringNode } from '@mcschema/core'
import { Hook, ModelPath, Path, StringHookParams, ValidationOption, EnumOption, INode, DataModel, MapNode, StringNode, relativePath } from '@mcschema/core'
import { locale, segmentedLocale } from '../Locales'
import { Mounter } from '../views/View'
import { hexId, htmlEncode } from '../Utils'
import { suffixInjector } from './suffixInjector'
import { Octicon } from '../components/Octicon'
import { App } from '../App'
import { App, BlockStateRegistry } from '../App'
/**
* Secondary model used to remember the keys of a map
@@ -105,13 +105,19 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
return ['', suffix, body]
},
map({ keys, children }, path, value, mounter) {
map({ keys, children, config }, path, value, mounter) {
const keyPath = new ModelPath(keysModel, new Path([hashString(path.toString())]))
const onAdd = mounter.onClick(el => {
const key = keyPath.get()
path.model.set(path.push(key), children.default())
})
const keyRendered = keys.hook(this, keyPath, keyPath.get() ?? '', mounter)
const blockState = (config.validation?.validator === 'block_state_map' ? BlockStateRegistry[relativePath(path, config.validation.params.id).get()] : null)
if (blockState && !blockState.properties) {
return ['', '', '']
}
const keyRendered = (blockState
? StringNode(null!, { enum: Object.keys(blockState.properties ?? {}) })
: keys).hook(this, keyPath, keyPath.get() ?? '', mounter)
const suffix = keyRendered[1] + `<button class="add" data-id="${onAdd}">${Octicon.plus_circle}</button>`
let body = ''
if (typeof value === 'object' && value !== undefined) {
@@ -120,7 +126,9 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
const removeId = mounter.onClick(el => path.model.set(path.push(key), undefined))
const childPath = path.modelPush(key)
const category = children.category(childPath)
const [cPrefix, cSuffix, cBody] = children.hook(this, childPath, value[key], mounter)
const [cPrefix, cSuffix, cBody] = (blockState
? StringNode(null!, { enum: blockState.properties[key] })
: children).hook(this, childPath, value[key], mounter)
return `<div class="node-entry"><div class="node ${children.type(childPath)}-node" ${category ? `data-category="${htmlEncode(category)}"` : ''}>
<div class="node-header">
${error(childPath, mounter)}