installer
This commit is contained in:
parent
3158c3cec8
commit
6b5cc23888
8 changed files with 127 additions and 48 deletions
|
|
@ -1,40 +1,42 @@
|
|||
import { AnimationKeyframe } from "../components/AnimationKeyframe.js"
|
||||
import { AnimType } from "../types/enums/AnimType.js"
|
||||
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||
import { Binding } from "../types/properties/value.js"
|
||||
import { AnimationKeyframe } from "../components/AnimationKeyframe.js";
|
||||
import { AnimType } from "../types/enums/AnimType.js";
|
||||
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js";
|
||||
import { Binding } from "../types/properties/value.js";
|
||||
|
||||
export function FormatProperties(properties: any) {
|
||||
const property_bag: Record<Binding, any> = {}
|
||||
const property_bag: Record<Binding, any> = {};
|
||||
|
||||
for (const key in properties) {
|
||||
const value = properties[key]
|
||||
const value = properties[key];
|
||||
|
||||
if (key.startsWith("#")) {
|
||||
property_bag[<Binding>key] = value
|
||||
delete properties[key]
|
||||
property_bag[<Binding>key] = value;
|
||||
delete properties[key];
|
||||
}
|
||||
}
|
||||
|
||||
if (properties.anchor) {
|
||||
properties.anchor_from = properties.anchor_to = properties.anchor
|
||||
delete properties.anchor
|
||||
properties.anchor_from = properties.anchor_to = properties.anchor;
|
||||
delete properties.anchor;
|
||||
}
|
||||
|
||||
if (Object.keys(property_bag).length) {
|
||||
if (properties.property_bag) {
|
||||
properties.property_bag = { ...property_bag, ...properties.property_bag }
|
||||
properties.property_bag = { ...property_bag, ...properties.property_bag };
|
||||
} else {
|
||||
properties.property_bag = property_bag
|
||||
properties.property_bag = property_bag;
|
||||
}
|
||||
}
|
||||
|
||||
return properties
|
||||
return properties;
|
||||
}
|
||||
|
||||
export function FormatAnimationProperties(properties: KeyframeAnimationProperties<AnimType>) {
|
||||
export function FormatAnimationProperties(
|
||||
properties: KeyframeAnimationProperties<AnimType>,
|
||||
) {
|
||||
if (properties.next instanceof AnimationKeyframe) {
|
||||
properties.next = `${properties.next}`
|
||||
properties.next = `${properties.next}`;
|
||||
}
|
||||
|
||||
return properties
|
||||
return properties;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { AnimationKeyframe } from "../components/AnimationKeyframe.js"
|
||||
import { Class } from "../components/Class.js"
|
||||
import { ModifyUI, UI } from "../components/UI.js"
|
||||
import { UI } from "../components/UI.js"
|
||||
import { AnimType } from "../types/enums/AnimType.js"
|
||||
import { Renderer } from "../types/enums/Renderer.js"
|
||||
import { Type } from "../types/enums/Type.js"
|
||||
|
|
@ -40,9 +40,7 @@ export class Memory extends Class {
|
|||
Memory.files.entries().forEach(([path, { elements, namespace }]) => {
|
||||
const record: Record<string, any> = {}
|
||||
|
||||
elements.forEach(element => {
|
||||
record[element.name] = element
|
||||
})
|
||||
elements.forEach(element => (record[element.name] = element))
|
||||
|
||||
data.set(path, {
|
||||
namespace,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { isBuildMode } from "../Configuration.js"
|
||||
import { Memory } from "../Memory.js"
|
||||
import { createBuildFolder } from "./linker.js"
|
||||
import fs from "fs/promises"
|
||||
import { createBuildFolder, linkToGame } from "./linker.js"
|
||||
import { genManifest } from "./manifest.js"
|
||||
import { UI } from "../../components/UI.js"
|
||||
import { Type } from "../../types/enums/Type.js"
|
||||
import fs from "fs/promises"
|
||||
|
||||
async function buildUI() {
|
||||
const build = Memory.build()
|
||||
|
|
@ -11,6 +13,10 @@ async function buildUI() {
|
|||
ui_defs: Array.from(build.keys()),
|
||||
})
|
||||
|
||||
build.set("build.json", {
|
||||
files: Array.from(build.keys()),
|
||||
})
|
||||
|
||||
const out = await Promise.all(
|
||||
build.entries().map(async ([file, value]) => {
|
||||
const outFile = `build/build/${file}`
|
||||
|
|
@ -18,12 +24,30 @@ async function buildUI() {
|
|||
.stat(outFile.split(/\\|\//g).slice(0, -1).join("/"))
|
||||
.catch(async () => await fs.mkdir(outFile.split(/\\|\//g).slice(0, -1).join("/"), { recursive: true }))
|
||||
|
||||
await fs.writeFile(outFile, JSON.stringify(value), "utf-8")
|
||||
await fs.writeFile(
|
||||
outFile,
|
||||
JSON.stringify(
|
||||
Object.fromEntries(
|
||||
Object.entries(value).map(([key, value]: [string, any]) => {
|
||||
const extend = (value as UI<Type>).extend
|
||||
return [extend ? key + String(extend) : key, value]
|
||||
}),
|
||||
),
|
||||
),
|
||||
"utf-8",
|
||||
)
|
||||
build.delete(file)
|
||||
return file
|
||||
}),
|
||||
)
|
||||
|
||||
await fs.writeFile("build/build/manifest.json", await genManifest(), "utf-8")
|
||||
await Promise.all([
|
||||
fs.writeFile("build/build/manifest.json", await genManifest(), "utf-8"),
|
||||
fs.writeFile("build/build/.gitignore", [...out, "manifest.json"].join("\n"), "utf-8"),
|
||||
fs
|
||||
.stat("build/build/pack_icon.png")
|
||||
.catch(() => fs.copyFile("node_modules/asajs/resources/pack_icon.png", "build/build/pack_icon.png")),
|
||||
])
|
||||
|
||||
return out.length
|
||||
}
|
||||
|
|
@ -34,6 +58,7 @@ if (isBuildMode) {
|
|||
if (first) {
|
||||
await createBuildFolder()
|
||||
await buildUI()
|
||||
await linkToGame()
|
||||
}
|
||||
first = false
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import os from "os"
|
||||
import path from "path"
|
||||
|
||||
function getGamedataPath() {
|
||||
export function getGamedataPath() {
|
||||
switch (os.platform()) {
|
||||
case "win32": {
|
||||
if (/Windows (10|11)/.test(os.version())) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import fs from "fs/promises"
|
||||
import { BuildCache } from "./buildcache.js"
|
||||
import { RandomString } from "../../components/Utils.js"
|
||||
import { prevData } from "./prevdata.js"
|
||||
import path from "path"
|
||||
import { getGamedataPath } from "./installer.js"
|
||||
|
||||
const HEX: string[] = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"))
|
||||
|
||||
|
|
@ -22,7 +25,7 @@ function genUUID(): string {
|
|||
}
|
||||
|
||||
export async function clearBuild() {
|
||||
await fs.rm("build/build", { recursive: true, force: true })
|
||||
await Promise.all(prevData.files.map(file => fs.rm(`build/build/${file}`).catch(() => null)))
|
||||
}
|
||||
|
||||
export async function createBuildFolder() {
|
||||
|
|
@ -36,6 +39,14 @@ export async function getBuildFolderName() {
|
|||
return await BuildCache.getWithSetDefault("build-key", () => RandomString(16))
|
||||
}
|
||||
|
||||
export async function linkToGame() {
|
||||
const sourcePath = path.resolve("build/build")
|
||||
const targetPath = path.resolve(getGamedataPath(), "development_resource_packs", await getBuildFolderName())
|
||||
await fs.stat(targetPath).catch(async () => {
|
||||
await fs.symlink(sourcePath, targetPath, "junction")
|
||||
})
|
||||
}
|
||||
|
||||
export async function getUUID(): Promise<[string, string]> {
|
||||
return await BuildCache.getWithSetDefault("uuid", () => {
|
||||
return [genUUID(), genUUID()]
|
||||
|
|
|
|||
11
src/compilers/ui/prevdata.ts
Normal file
11
src/compilers/ui/prevdata.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import fs from "fs"
|
||||
|
||||
export let prevData: {
|
||||
files: string[]
|
||||
}
|
||||
|
||||
try {
|
||||
prevData = JSON.parse(fs.readFileSync("build/build/build.json", "utf-8"))
|
||||
} catch (error) {
|
||||
prevData = { files: [] }
|
||||
}
|
||||
|
|
@ -15,12 +15,18 @@ import { RandomNamespace } from "../compilers/Random.js"
|
|||
|
||||
import util from "node:util"
|
||||
|
||||
interface ExtendUI {
|
||||
name: string
|
||||
namespace: string
|
||||
toString(): string
|
||||
}
|
||||
|
||||
export class UI<T extends Type, K extends Renderer | null = null> extends Class {
|
||||
readonly path: string
|
||||
readonly name: string
|
||||
readonly namespace: string
|
||||
|
||||
readonly extend?: UI<Type, Renderer | null>
|
||||
readonly extend?: UI<Type, Renderer | null> | ExtendUI
|
||||
readonly extendable: boolean
|
||||
|
||||
protected readonly controls = new Map<string, [UI<Type, Renderer | null>, Properties<Type, Renderer | null>]>()
|
||||
|
|
@ -53,7 +59,7 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
|
|||
this.name = name?.match(/^(\w|\/)+/)?.[0] || RandomString(16)
|
||||
this.namespace = namespace || RandomNamespace()
|
||||
|
||||
if (!path) this.path = `@/${this.namespace}.json`
|
||||
if (!path) this.path = `asajs/${this.namespace}.json`
|
||||
else this.path = path
|
||||
|
||||
this.extendable = this.name.search("/") === -1
|
||||
|
|
@ -132,8 +138,15 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
|
|||
* @param namespace
|
||||
* @returns
|
||||
*/
|
||||
clone(properties?: Properties<T, K>, name?: string, namespace?: string) {
|
||||
return ExtendsOf(this, properties, name, namespace)
|
||||
createExtends(properties?: Properties<T, K>, name?: string, namespace?: string) {
|
||||
if (!this.extendable) throw new Error("This element is not extendable")
|
||||
const ui = new UI<T, K>(undefined, name, namespace)
|
||||
if (properties) ui.setProperties(properties)
|
||||
// @ts-ignore
|
||||
ui.extend = this
|
||||
// @ts-ignore
|
||||
ui.extendType = this.type || this.extendType
|
||||
return ui
|
||||
}
|
||||
|
||||
protected toString() {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import { AnimationKeyframe } from "./AnimationKeyframe.js"
|
|||
import { AnimationProperties, KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||
import { Animation } from "./Animation.js"
|
||||
import { SmartAnimation } from "../types/enums/SmartAnimation.js"
|
||||
import { Memory, MemoryModify } from "../compilers/Memory.js"
|
||||
import { MemoryModify } from "../compilers/Memory.js"
|
||||
|
||||
type CompileBinding = `[${string}]`
|
||||
|
||||
|
|
@ -250,9 +250,7 @@ export function ExtendsOf<T extends Type, K extends Renderer | null>(
|
|||
namespace?: string,
|
||||
name?: string,
|
||||
) {
|
||||
if (!element.extendable) {
|
||||
throw new Error("Cannot extend a UI that cannot be extended")
|
||||
}
|
||||
if (!element.extendable) throw new Error("Cannot extend a UI that cannot be extended")
|
||||
const ui = new UI<T, K>(undefined, name, namespace)
|
||||
if (properties) ui.setProperties(properties)
|
||||
// @ts-ignore
|
||||
|
|
@ -262,6 +260,27 @@ export function ExtendsOf<T extends Type, K extends Renderer | null>(
|
|||
return ui as typeof element
|
||||
}
|
||||
|
||||
export function VanillaExtendsOf<T extends Namespace, K extends Exclude<Element<T>, `${string}/${string}`>>(
|
||||
originNamespace: T,
|
||||
originName: K,
|
||||
// @ts-ignore
|
||||
properties?: Properties<VanillaType<T, K>, null>,
|
||||
namespace?: string,
|
||||
name?: string,
|
||||
) {
|
||||
// @ts-ignore
|
||||
const ui = new UI<VanillaType<T, K>, null>(undefined, name, namespace)
|
||||
if (properties) ui.setProperties(properties)
|
||||
// @ts-ignore
|
||||
ui.extend = {
|
||||
name: originName,
|
||||
namespace: originNamespace,
|
||||
toString: () => `@${originNamespace}.${originName}`,
|
||||
}
|
||||
|
||||
return ui
|
||||
}
|
||||
|
||||
// Quick Keyframe
|
||||
export function KeyframeOffset(
|
||||
properties?: KeyframeAnimationProperties<AnimType.OFFSET>,
|
||||
|
|
@ -359,7 +378,7 @@ export function AnimationAlpha(...keyframes: AnimWithSmartAnim<AnimType.ALPHA>)
|
|||
return new Animation(AnimType.ALPHA, ...keyframes)
|
||||
}
|
||||
|
||||
// Animation Extendof
|
||||
// Animation ExtendsOf
|
||||
export function AnimationExtendsOf<T extends AnimType>(
|
||||
animation: AnimationKeyframe<T> | Animation<T>,
|
||||
properties?: AnimationProperties<T>,
|
||||
|
|
|
|||
Reference in a new issue