@combos-fun/plugin-renderer-3d-text 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/agent-skill.md +3 -2
- package/dist/plugin-renderer-3d-text.cjs.js +12 -3
- package/dist/plugin-renderer-3d-text.cjs.js.map +1 -1
- package/dist/plugin-renderer-3d-text.cjs.prod.js +1 -1
- package/dist/plugin-renderer-3d-text.esm.js +12 -3
- package/dist/plugin-renderer-3d-text.esm.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -50,7 +50,8 @@ new Text3D({
|
|
|
50
50
|
|
|
51
51
|
The host injects `window.combos` into the game HTML head. The first
|
|
52
52
|
`requestI18n` runs in `beforeReady` and holds `combos-game:ready` / `start`
|
|
53
|
-
until the host replies.
|
|
53
|
+
until the host replies. Labels stay empty until that reply so source copy does
|
|
54
|
+
not paint first. Put every later-screen template in `sourceTexts` so
|
|
54
55
|
those screens reuse the startup catalog instead of flashing source text.
|
|
55
56
|
The system keeps one growing session catalog of source templates and
|
|
56
57
|
translations; later `requestI18n` calls only run for templates still missing
|
package/agent-skill.md
CHANGED
|
@@ -44,8 +44,9 @@ rebuilding from the current screen. You can also call
|
|
|
44
44
|
The source template itself is the translation lookup key. After labels exist,
|
|
45
45
|
the system checks that `window.combos.requestI18n` exists. The first
|
|
46
46
|
`requestI18n({ sourceLocale, sourceTexts })` runs in `beforeReady` and holds
|
|
47
|
-
game `ready` / `start` until the host replies.
|
|
48
|
-
|
|
47
|
+
game `ready` / `start` until the host replies. Labels stay empty until that
|
|
48
|
+
first reply so the source language does not flash on the canvas. Apply the
|
|
49
|
+
result only when `needed: true`. If that reply is `needed: true` but a current template is
|
|
49
50
|
missing from `translations`, merge every seeded and mounted template and
|
|
50
51
|
`requestI18n` once more before `ready`. After ready, a new label whose
|
|
51
52
|
translation is still missing stays empty, merges all current templates, waits
|
|
@@ -244,15 +244,22 @@ function shouldRequestI18nForSourceTexts(sourceTexts, translations, state) {
|
|
|
244
244
|
return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;
|
|
245
245
|
}
|
|
246
246
|
function shouldHoldForMissingTranslation(sourceText, translations, state) {
|
|
247
|
-
if (!state.sourceLocale
|
|
248
|
-
return false;
|
|
249
|
-
if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase())
|
|
247
|
+
if (!state.sourceLocale)
|
|
250
248
|
return false;
|
|
251
249
|
const trimmed = sourceText.trim();
|
|
252
250
|
if (!trimmed)
|
|
253
251
|
return false;
|
|
254
252
|
if (hasSourceTranslation(sourceText, translations))
|
|
255
253
|
return false;
|
|
254
|
+
// Flush mounts Text before the first requestI18n. targetLocale still equals
|
|
255
|
+
// sourceLocale and i18nNeeded is still false, so holding only after settle
|
|
256
|
+
// would paint the source copy, then swap it when the host replies.
|
|
257
|
+
if (!state.firstI18nSettled)
|
|
258
|
+
return true;
|
|
259
|
+
if (!state.i18nNeeded)
|
|
260
|
+
return false;
|
|
261
|
+
if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase())
|
|
262
|
+
return false;
|
|
256
263
|
return !state.resolvedSourceTexts.has(trimmed);
|
|
257
264
|
}
|
|
258
265
|
function localizeText(sourceText, replacements, sourceLocale, targetLocale, translations) {
|
|
@@ -327,6 +334,8 @@ let Text3DSystem = class Text3DSystem extends pluginRenderer3d.Renderer3D {
|
|
|
327
334
|
await this.requestI18nAndApply();
|
|
328
335
|
}
|
|
329
336
|
this.firstI18nSettled = true;
|
|
337
|
+
// needed:false refresh still ran with firstI18nSettled=false (empty hold).
|
|
338
|
+
this.refreshAllText();
|
|
330
339
|
}
|
|
331
340
|
setI18n(locale, translations) {
|
|
332
341
|
const targetLocale = locale?.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-3d-text.cjs.js","sources":["../lib/component.ts","../lib/hostSdk.ts","../lib/localization.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextReplacements } from './localization';\n\nexport type { TextReplacementValue, TextReplacements } from './localization';\n\nexport interface Text3DParams {\n text?: string;\n /** Values substituted into named placeholders such as `{score}`. */\n replacements?: TextReplacements;\n fontSize?: number;\n color?: number;\n anchorX?: string;\n anchorY?: string;\n maxWidth?: number;\n font?: string;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n}\n\nexport default class Text3D extends Component<Text3DParams> {\n static componentName: string = 'Text3D';\n\n @Field({\n\n type: 'string',\n\n group: 'Text3D',\n\n label: 'text',\n\n description: 'Visible text content.',\n\n editor: 'text',\n\n })\n\n text: string = '';\n\n replacements: TextReplacements = {};\n\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'fontSize',\n description: 'Font size.',\n editor: 'number-stepper',\n })\n fontSize: number = 0.5;\n @Field({\n type: 'number',\n group: 'Text3D',\n label: 'color',\n description: 'Color value.',\n editor: 'number-stepper',\n })\n color: number = 0xffffff;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorX',\n description: 'Horizontal text anchor.',\n editor: 'text',\n })\n anchorX: string = 'center';\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorY',\n description: 'Vertical text anchor.',\n editor: 'text',\n })\n anchorY: string = 'middle';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'maxWidth',\n description: 'Maximum text wrap width.',\n editor: 'number-stepper',\n })\n maxWidth: number = 0;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'font',\n description: 'Font URL or path for troika-three-text (not an engine resource name).',\n editor: 'text',\n })\n font: string = '';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n\n init(obj?: Text3DParams) {\n if (!obj) return;\n const { replacements, ...rest } = obj;\n Object.assign(this, rest);\n if (replacements) this.replacements = { ...replacements };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` hostSdk. */\nimport type { TextTranslations } from './localization';\n\n/** Host-injected global. The SDK itself is not part of this repo. */\nexport const COMBOS_HOST_SDK = 'combos' as const;\n\nexport interface CombosI18nRequest {\n sourceLocale: string;\n sourceTexts: string[];\n}\n\nexport type CombosI18nResult =\n | { needed: false }\n | { needed: true; locale: string; translations: TextTranslations };\n\nexport interface CombosHostSdk {\n requestI18n?(request: CombosI18nRequest): Promise<CombosI18nResult>;\n}\n\ndeclare global {\n interface Window {\n combos?: CombosHostSdk;\n }\n}\n\nexport function hasCombosRequestI18n(\n sdk: CombosHostSdk | undefined | null = typeof window === 'undefined' ? undefined : window.combos,\n): sdk is CombosHostSdk & { requestI18n: NonNullable<CombosHostSdk['requestI18n']> } {\n return !!sdk && typeof sdk.requestI18n === 'function';\n}\n\nexport function parseI18nResult(data: unknown): CombosI18nResult {\n if (!data || typeof data !== 'object') return { needed: false };\n const input = data as {\n needed?: unknown;\n locale?: unknown;\n translations?: unknown;\n };\n if (input.needed !== true) return { needed: false };\n if (typeof input.locale !== 'string' || !input.locale.trim()) {\n return { needed: false };\n }\n if (\n !input.translations ||\n typeof input.translations !== 'object' ||\n Array.isArray(input.translations)\n ) {\n return { needed: false };\n }\n const entries = Object.entries(input.translations);\n if (entries.some(([, value]) => typeof value !== 'string')) {\n return { needed: false };\n }\n return {\n needed: true,\n locale: input.locale.trim(),\n translations: Object.fromEntries(entries) as TextTranslations,\n };\n}\n\n/** Ask the injected host SDK. Always resolves; missing method means no translation. */\nexport async function requestHostI18n(\n request: CombosI18nRequest,\n): Promise<CombosI18nResult> {\n if (typeof window === 'undefined' || !hasCombosRequestI18n(window.combos)) {\n return { needed: false };\n }\n try {\n return parseI18nResult(await window.combos.requestI18n(request));\n } catch {\n return { needed: false };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` localization. */\n\nexport type TextReplacementValue = string | number;\nexport type TextReplacements = Record<string, TextReplacementValue>;\nexport type TextTranslations = Record<string, string>;\n\nconst PLACEHOLDER_PATTERN = /\\{([A-Za-z_$][\\w$.-]*)\\}/g;\n\nexport function interpolateText(\n template: string,\n replacements?: TextReplacements,\n): string {\n if (!replacements) return template;\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, name: string) => {\n if (!Object.prototype.hasOwnProperty.call(replacements, name)) {\n return placeholder;\n }\n return String(replacements[name]);\n });\n}\n\nexport function findTranslatedTemplate(\n sourceText: string,\n translations: TextTranslations,\n): string | undefined {\n if (Object.prototype.hasOwnProperty.call(translations, sourceText)) {\n return translations[sourceText];\n }\n const trimmed = sourceText.trim();\n if (\n trimmed &&\n trimmed !== sourceText &&\n Object.prototype.hasOwnProperty.call(translations, trimmed)\n ) {\n return translations[trimmed];\n }\n return undefined;\n}\n\nexport function hasSourceTranslation(\n sourceText: string,\n translations: TextTranslations,\n): boolean {\n return findTranslatedTemplate(sourceText, translations) !== undefined;\n}\n\nexport function hasMissingSourceTranslations(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n): boolean {\n return sourceTexts.some((text) => !hasSourceTranslation(text, translations));\n}\n\nexport function sourceTextsSignature(sourceTexts: readonly string[]): string {\n return [...sourceTexts].sort().join('\\0');\n}\n\n/** After the first host reply, only request again for templates still missing. */\nexport function shouldRequestI18nForSourceTexts(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n state: {\n i18nNeeded: boolean;\n lastRequestedSourceTexts: string;\n },\n): boolean {\n if (!state.i18nNeeded) return false;\n if (!hasMissingSourceTranslations(sourceTexts, translations)) return false;\n return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;\n}\n\nexport function shouldHoldForMissingTranslation(\n sourceText: string,\n translations: TextTranslations,\n state: {\n sourceLocale: string;\n targetLocale: string;\n i18nNeeded: boolean;\n firstI18nSettled: boolean;\n resolvedSourceTexts: ReadonlySet<string>;\n },\n): boolean {\n if (!state.sourceLocale || !state.i18nNeeded || !state.firstI18nSettled) return false;\n if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase()) return false;\n const trimmed = sourceText.trim();\n if (!trimmed) return false;\n if (hasSourceTranslation(sourceText, translations)) return false;\n return !state.resolvedSourceTexts.has(trimmed);\n}\n\nexport function localizeText(\n sourceText: string,\n replacements: TextReplacements | undefined,\n sourceLocale: string,\n targetLocale: string,\n translations: TextTranslations,\n): string {\n const shouldTranslate =\n !!sourceLocale &&\n !!targetLocale &&\n sourceLocale.toLowerCase() !== targetLocale.toLowerCase();\n const template = shouldTranslate\n ? findTranslatedTemplate(sourceText, translations) ?? sourceText\n : sourceText;\n return interpolateText(template, replacements);\n}\n\nexport function addSourceTexts(\n target: Set<string>,\n texts?: Iterable<string | undefined | null>,\n) {\n if (!texts) return;\n for (const text of texts) {\n const source = typeof text === 'string' ? text.trim() : '';\n if (source) target.add(source);\n }\n}\n\nexport function mergeTranslations(\n current: TextTranslations,\n incoming: Record<string, unknown>,\n): TextTranslations {\n const next = { ...current };\n for (const [key, value] of Object.entries(incoming)) {\n if (typeof value === 'string') next[key] = value;\n }\n return next;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem, tagObject3D, Transform3D, VisualPoseBridge } from '@combos-fun/plugin-renderer-3d';\nimport { Text as TroikaText } from 'troika-three-text';\nimport Text3D from './component';\nimport { requestHostI18n } from './hostSdk';\nimport {\n addSourceTexts,\n hasMissingSourceTranslations,\n localizeText,\n mergeTranslations,\n shouldHoldForMissingTranslation,\n shouldRequestI18nForSourceTexts,\n sourceTextsSignature,\n type TextTranslations,\n} from './localization';\n\nexport interface Text3DSystemParams {\n /** BCP 47 locale of the source text, for example `zh-CN`. Omit to disable host-driven i18n. */\n sourceLocale?: string;\n /**\n * All source templates to translate on first `requestI18n`, including copy\n * for screens that are not mounted yet. The system also keeps a growing\n * session catalog of every later template it sees.\n */\n sourceTexts?: string[];\n}\n\n@decorators.componentObserver({\n Text3D: [\n 'text',\n { prop: ['replacements'], deep: true },\n 'fontSize', 'color', 'anchorX', 'anchorY', 'maxWidth', 'font',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n ],\n})\nexport default class Text3DSystem extends Renderer3D<Text3DSystemParams> {\n static systemName = 'Text3DSystem';\n name: string = 'Text3DSystem';\n\n private texts = new Map<number, { mesh: TroikaText; component: Text3D }>();\n private poseBridges = new Map<number, VisualPoseBridge>();\n private sourceLocale = '';\n private targetLocale = '';\n private translations: TextTranslations = {};\n /** Growing catalog of every source template seen this session. */\n private knownSourceTexts = new Set<string>();\n private lastRequestedSourceTexts = '';\n private i18nRequestScheduled = false;\n private i18nRequestId = 0;\n private firstI18nSettled = false;\n private i18nNeeded = false;\n private resolvedSourceTexts = new Set<string>();\n\n init(params?: Text3DSystemParams) {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n this.sourceLocale = params?.sourceLocale?.trim() ?? '';\n this.targetLocale = this.sourceLocale;\n this.declareSourceTexts(params?.sourceTexts);\n }\n\n /** Register extra source templates before or after ready. First request includes these. */\n declareSourceTexts(texts?: string[]) {\n this.rememberSourceTexts(texts);\n this.scheduleI18nRequest();\n }\n\n async beforeReady() {\n if (this.firstI18nSettled) return;\n this.update();\n if (!this.sourceLocale) {\n this.firstI18nSettled = true;\n return;\n }\n await this.requestI18nAndApply();\n if (\n this.i18nNeeded &&\n hasMissingSourceTranslations(this.collectSourceTexts(), this.translations)\n ) {\n await this.requestI18nAndApply();\n }\n this.firstI18nSettled = true;\n }\n\n setI18n(locale: string, translations: TextTranslations) {\n const targetLocale = locale?.trim();\n if (!targetLocale || !translations || typeof translations !== 'object') return;\n this.targetLocale = targetLocale;\n this.translations = mergeTranslations(this.translations, translations);\n this.refreshAllText();\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as Text3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(Text3D) as Text3D;\n if (!component) return;\n\n const entry = this.texts.get(gameObject.id);\n if (!entry) return;\n this.applyPose(gameObject, component, entry.mesh);\n }\n\n private handleAdd(gameObject: GameObject, component: Text3D) {\n const textMesh = new TroikaText();\n this.syncTextProps(textMesh, component);\n textMesh.sync();\n tagObject3D(textMesh, gameObject.id);\n\n this.threeContext.attachVisual(gameObject.id, textMesh, gameObject);\n this.texts.set(gameObject.id, { mesh: textMesh, component });\n this.poseBridges.set(gameObject.id, new VisualPoseBridge());\n this.rememberSourceTexts([component.text]);\n this.scheduleI18nRequest();\n }\n\n private handleChange(changed: ComponentChanged) {\n const entry = this.texts.get(changed.gameObject.id);\n if (!entry) return;\n const component = changed.component as Text3D;\n entry.component = component;\n if (changed.prop.prop[0] === 'text') this.rememberSourceTexts([component.text]);\n this.syncTextProps(entry.mesh, component);\n entry.mesh.sync();\n if (changed.prop.prop[0] === 'text') this.scheduleI18nRequest();\n }\n\n private handleRemove(id: number) {\n const entry = this.texts.get(id);\n if (!entry) return;\n\n this.threeContext.detachVisual(id, entry.mesh);\n entry.mesh.dispose();\n this.texts.delete(id);\n this.poseBridges.delete(id);\n }\n\n private syncTextProps(textMesh: TroikaText, component: Text3D) {\n textMesh.text = this.resolveText(component);\n textMesh.fontSize = component.fontSize;\n textMesh.color = component.color;\n textMesh.anchorX = component.anchorX;\n textMesh.anchorY = component.anchorY;\n if (component.maxWidth > 0) {\n textMesh.maxWidth = component.maxWidth;\n }\n if (component.font) {\n textMesh.font = component.font;\n }\n }\n\n private applyPose(gameObject: GameObject, component: Text3D, textMesh: TroikaText) {\n let bridge = this.poseBridges.get(gameObject.id);\n if (!bridge) {\n bridge = new VisualPoseBridge();\n this.poseBridges.set(gameObject.id, bridge);\n }\n const transform = gameObject.getComponent(Transform3D) as Transform3D | undefined;\n if (!bridge.sync(component, transform)) {\n textMesh.position.set(0, 0, 0);\n textMesh.rotation.set(0, 0, 0);\n return;\n }\n textMesh.position.set(component.positionX, component.positionY, component.positionZ);\n textMesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n }\n\n onDestroy() {\n this.i18nRequestId += 1;\n this.firstI18nSettled = false;\n this.i18nNeeded = false;\n this.resolvedSourceTexts.clear();\n for (const [id] of this.texts) {\n this.handleRemove(id);\n }\n this.texts.clear();\n }\n\n private resolveText(component: Text3D): string {\n if (\n shouldHoldForMissingTranslation(component.text, this.translations, {\n sourceLocale: this.sourceLocale,\n targetLocale: this.targetLocale,\n i18nNeeded: this.i18nNeeded,\n firstI18nSettled: this.firstI18nSettled,\n resolvedSourceTexts: this.resolvedSourceTexts,\n })\n ) {\n return '';\n }\n return localizeText(\n component.text,\n component.replacements,\n this.sourceLocale,\n this.targetLocale,\n this.translations,\n );\n }\n\n private rememberSourceTexts(texts?: Iterable<string | undefined | null>) {\n addSourceTexts(this.knownSourceTexts, texts);\n }\n\n private collectSourceTexts(): string[] {\n for (const entry of this.texts.values()) {\n this.rememberSourceTexts([entry.component.text]);\n }\n return [...this.knownSourceTexts];\n }\n\n private scheduleI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled || this.i18nRequestScheduled) return;\n this.i18nRequestScheduled = true;\n queueMicrotask(() => {\n this.i18nRequestScheduled = false;\n this.startI18nRequest();\n });\n }\n\n private startI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled) return;\n const sourceTexts = this.collectSourceTexts();\n if (\n !shouldRequestI18nForSourceTexts(sourceTexts, this.translations, {\n i18nNeeded: this.i18nNeeded,\n lastRequestedSourceTexts: this.lastRequestedSourceTexts,\n })\n ) {\n return;\n }\n void this.requestI18nAndApply();\n }\n\n private async requestI18nAndApply() {\n const sourceTexts = this.collectSourceTexts();\n this.lastRequestedSourceTexts = sourceTextsSignature(sourceTexts);\n const requestId = ++this.i18nRequestId;\n const result = await requestHostI18n({\n sourceLocale: this.sourceLocale,\n sourceTexts,\n });\n if (requestId !== this.i18nRequestId) return;\n addSourceTexts(this.resolvedSourceTexts, sourceTexts);\n this.i18nNeeded = result.needed;\n if (!result.needed) {\n this.refreshAllText();\n return;\n }\n this.setI18n(result.locale, result.translations);\n }\n\n private refreshAllText() {\n for (const entry of this.texts.values()) {\n entry.mesh.text = this.resolveText(entry.component);\n entry.mesh.sync();\n }\n }\n}\n"],"names":["Component","__decorate","Field","Renderer3D","Renderer3DSystem","OBSERVER_TYPE","TroikaText","tagObject3D","VisualPoseBridge","Transform3D","decorators"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-3d-text.cjs.js","sources":["../lib/component.ts","../lib/hostSdk.ts","../lib/localization.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextReplacements } from './localization';\n\nexport type { TextReplacementValue, TextReplacements } from './localization';\n\nexport interface Text3DParams {\n text?: string;\n /** Values substituted into named placeholders such as `{score}`. */\n replacements?: TextReplacements;\n fontSize?: number;\n color?: number;\n anchorX?: string;\n anchorY?: string;\n maxWidth?: number;\n font?: string;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n}\n\nexport default class Text3D extends Component<Text3DParams> {\n static componentName: string = 'Text3D';\n\n @Field({\n\n type: 'string',\n\n group: 'Text3D',\n\n label: 'text',\n\n description: 'Visible text content.',\n\n editor: 'text',\n\n })\n\n text: string = '';\n\n replacements: TextReplacements = {};\n\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'fontSize',\n description: 'Font size.',\n editor: 'number-stepper',\n })\n fontSize: number = 0.5;\n @Field({\n type: 'number',\n group: 'Text3D',\n label: 'color',\n description: 'Color value.',\n editor: 'number-stepper',\n })\n color: number = 0xffffff;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorX',\n description: 'Horizontal text anchor.',\n editor: 'text',\n })\n anchorX: string = 'center';\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorY',\n description: 'Vertical text anchor.',\n editor: 'text',\n })\n anchorY: string = 'middle';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'maxWidth',\n description: 'Maximum text wrap width.',\n editor: 'number-stepper',\n })\n maxWidth: number = 0;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'font',\n description: 'Font URL or path for troika-three-text (not an engine resource name).',\n editor: 'text',\n })\n font: string = '';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n\n init(obj?: Text3DParams) {\n if (!obj) return;\n const { replacements, ...rest } = obj;\n Object.assign(this, rest);\n if (replacements) this.replacements = { ...replacements };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` hostSdk. */\nimport type { TextTranslations } from './localization';\n\n/** Host-injected global. The SDK itself is not part of this repo. */\nexport const COMBOS_HOST_SDK = 'combos' as const;\n\nexport interface CombosI18nRequest {\n sourceLocale: string;\n sourceTexts: string[];\n}\n\nexport type CombosI18nResult =\n | { needed: false }\n | { needed: true; locale: string; translations: TextTranslations };\n\nexport interface CombosHostSdk {\n requestI18n?(request: CombosI18nRequest): Promise<CombosI18nResult>;\n}\n\ndeclare global {\n interface Window {\n combos?: CombosHostSdk;\n }\n}\n\nexport function hasCombosRequestI18n(\n sdk: CombosHostSdk | undefined | null = typeof window === 'undefined' ? undefined : window.combos,\n): sdk is CombosHostSdk & { requestI18n: NonNullable<CombosHostSdk['requestI18n']> } {\n return !!sdk && typeof sdk.requestI18n === 'function';\n}\n\nexport function parseI18nResult(data: unknown): CombosI18nResult {\n if (!data || typeof data !== 'object') return { needed: false };\n const input = data as {\n needed?: unknown;\n locale?: unknown;\n translations?: unknown;\n };\n if (input.needed !== true) return { needed: false };\n if (typeof input.locale !== 'string' || !input.locale.trim()) {\n return { needed: false };\n }\n if (\n !input.translations ||\n typeof input.translations !== 'object' ||\n Array.isArray(input.translations)\n ) {\n return { needed: false };\n }\n const entries = Object.entries(input.translations);\n if (entries.some(([, value]) => typeof value !== 'string')) {\n return { needed: false };\n }\n return {\n needed: true,\n locale: input.locale.trim(),\n translations: Object.fromEntries(entries) as TextTranslations,\n };\n}\n\n/** Ask the injected host SDK. Always resolves; missing method means no translation. */\nexport async function requestHostI18n(\n request: CombosI18nRequest,\n): Promise<CombosI18nResult> {\n if (typeof window === 'undefined' || !hasCombosRequestI18n(window.combos)) {\n return { needed: false };\n }\n try {\n return parseI18nResult(await window.combos.requestI18n(request));\n } catch {\n return { needed: false };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` localization. */\n\nexport type TextReplacementValue = string | number;\nexport type TextReplacements = Record<string, TextReplacementValue>;\nexport type TextTranslations = Record<string, string>;\n\nconst PLACEHOLDER_PATTERN = /\\{([A-Za-z_$][\\w$.-]*)\\}/g;\n\nexport function interpolateText(\n template: string,\n replacements?: TextReplacements,\n): string {\n if (!replacements) return template;\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, name: string) => {\n if (!Object.prototype.hasOwnProperty.call(replacements, name)) {\n return placeholder;\n }\n return String(replacements[name]);\n });\n}\n\nexport function findTranslatedTemplate(\n sourceText: string,\n translations: TextTranslations,\n): string | undefined {\n if (Object.prototype.hasOwnProperty.call(translations, sourceText)) {\n return translations[sourceText];\n }\n const trimmed = sourceText.trim();\n if (\n trimmed &&\n trimmed !== sourceText &&\n Object.prototype.hasOwnProperty.call(translations, trimmed)\n ) {\n return translations[trimmed];\n }\n return undefined;\n}\n\nexport function hasSourceTranslation(\n sourceText: string,\n translations: TextTranslations,\n): boolean {\n return findTranslatedTemplate(sourceText, translations) !== undefined;\n}\n\nexport function hasMissingSourceTranslations(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n): boolean {\n return sourceTexts.some((text) => !hasSourceTranslation(text, translations));\n}\n\nexport function sourceTextsSignature(sourceTexts: readonly string[]): string {\n return [...sourceTexts].sort().join('\\0');\n}\n\n/** After the first host reply, only request again for templates still missing. */\nexport function shouldRequestI18nForSourceTexts(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n state: {\n i18nNeeded: boolean;\n lastRequestedSourceTexts: string;\n },\n): boolean {\n if (!state.i18nNeeded) return false;\n if (!hasMissingSourceTranslations(sourceTexts, translations)) return false;\n return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;\n}\n\nexport function shouldHoldForMissingTranslation(\n sourceText: string,\n translations: TextTranslations,\n state: {\n sourceLocale: string;\n targetLocale: string;\n i18nNeeded: boolean;\n firstI18nSettled: boolean;\n resolvedSourceTexts: ReadonlySet<string>;\n },\n): boolean {\n if (!state.sourceLocale) return false;\n const trimmed = sourceText.trim();\n if (!trimmed) return false;\n if (hasSourceTranslation(sourceText, translations)) return false;\n // Flush mounts Text before the first requestI18n. targetLocale still equals\n // sourceLocale and i18nNeeded is still false, so holding only after settle\n // would paint the source copy, then swap it when the host replies.\n if (!state.firstI18nSettled) return true;\n if (!state.i18nNeeded) return false;\n if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase()) return false;\n return !state.resolvedSourceTexts.has(trimmed);\n}\n\nexport function localizeText(\n sourceText: string,\n replacements: TextReplacements | undefined,\n sourceLocale: string,\n targetLocale: string,\n translations: TextTranslations,\n): string {\n const shouldTranslate =\n !!sourceLocale &&\n !!targetLocale &&\n sourceLocale.toLowerCase() !== targetLocale.toLowerCase();\n const template = shouldTranslate\n ? findTranslatedTemplate(sourceText, translations) ?? sourceText\n : sourceText;\n return interpolateText(template, replacements);\n}\n\nexport function addSourceTexts(\n target: Set<string>,\n texts?: Iterable<string | undefined | null>,\n) {\n if (!texts) return;\n for (const text of texts) {\n const source = typeof text === 'string' ? text.trim() : '';\n if (source) target.add(source);\n }\n}\n\nexport function mergeTranslations(\n current: TextTranslations,\n incoming: Record<string, unknown>,\n): TextTranslations {\n const next = { ...current };\n for (const [key, value] of Object.entries(incoming)) {\n if (typeof value === 'string') next[key] = value;\n }\n return next;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem, tagObject3D, Transform3D, VisualPoseBridge } from '@combos-fun/plugin-renderer-3d';\nimport { Text as TroikaText } from 'troika-three-text';\nimport Text3D from './component';\nimport { requestHostI18n } from './hostSdk';\nimport {\n addSourceTexts,\n hasMissingSourceTranslations,\n localizeText,\n mergeTranslations,\n shouldHoldForMissingTranslation,\n shouldRequestI18nForSourceTexts,\n sourceTextsSignature,\n type TextTranslations,\n} from './localization';\n\nexport interface Text3DSystemParams {\n /** BCP 47 locale of the source text, for example `zh-CN`. Omit to disable host-driven i18n. */\n sourceLocale?: string;\n /**\n * All source templates to translate on first `requestI18n`, including copy\n * for screens that are not mounted yet. The system also keeps a growing\n * session catalog of every later template it sees.\n */\n sourceTexts?: string[];\n}\n\n@decorators.componentObserver({\n Text3D: [\n 'text',\n { prop: ['replacements'], deep: true },\n 'fontSize', 'color', 'anchorX', 'anchorY', 'maxWidth', 'font',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n ],\n})\nexport default class Text3DSystem extends Renderer3D<Text3DSystemParams> {\n static systemName = 'Text3DSystem';\n name: string = 'Text3DSystem';\n\n private texts = new Map<number, { mesh: TroikaText; component: Text3D }>();\n private poseBridges = new Map<number, VisualPoseBridge>();\n private sourceLocale = '';\n private targetLocale = '';\n private translations: TextTranslations = {};\n /** Growing catalog of every source template seen this session. */\n private knownSourceTexts = new Set<string>();\n private lastRequestedSourceTexts = '';\n private i18nRequestScheduled = false;\n private i18nRequestId = 0;\n private firstI18nSettled = false;\n private i18nNeeded = false;\n private resolvedSourceTexts = new Set<string>();\n\n init(params?: Text3DSystemParams) {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n this.sourceLocale = params?.sourceLocale?.trim() ?? '';\n this.targetLocale = this.sourceLocale;\n this.declareSourceTexts(params?.sourceTexts);\n }\n\n /** Register extra source templates before or after ready. First request includes these. */\n declareSourceTexts(texts?: string[]) {\n this.rememberSourceTexts(texts);\n this.scheduleI18nRequest();\n }\n\n async beforeReady() {\n if (this.firstI18nSettled) return;\n this.update();\n if (!this.sourceLocale) {\n this.firstI18nSettled = true;\n return;\n }\n await this.requestI18nAndApply();\n if (\n this.i18nNeeded &&\n hasMissingSourceTranslations(this.collectSourceTexts(), this.translations)\n ) {\n await this.requestI18nAndApply();\n }\n this.firstI18nSettled = true;\n // needed:false refresh still ran with firstI18nSettled=false (empty hold).\n this.refreshAllText();\n }\n\n setI18n(locale: string, translations: TextTranslations) {\n const targetLocale = locale?.trim();\n if (!targetLocale || !translations || typeof translations !== 'object') return;\n this.targetLocale = targetLocale;\n this.translations = mergeTranslations(this.translations, translations);\n this.refreshAllText();\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as Text3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(Text3D) as Text3D;\n if (!component) return;\n\n const entry = this.texts.get(gameObject.id);\n if (!entry) return;\n this.applyPose(gameObject, component, entry.mesh);\n }\n\n private handleAdd(gameObject: GameObject, component: Text3D) {\n const textMesh = new TroikaText();\n this.syncTextProps(textMesh, component);\n textMesh.sync();\n tagObject3D(textMesh, gameObject.id);\n\n this.threeContext.attachVisual(gameObject.id, textMesh, gameObject);\n this.texts.set(gameObject.id, { mesh: textMesh, component });\n this.poseBridges.set(gameObject.id, new VisualPoseBridge());\n this.rememberSourceTexts([component.text]);\n this.scheduleI18nRequest();\n }\n\n private handleChange(changed: ComponentChanged) {\n const entry = this.texts.get(changed.gameObject.id);\n if (!entry) return;\n const component = changed.component as Text3D;\n entry.component = component;\n if (changed.prop.prop[0] === 'text') this.rememberSourceTexts([component.text]);\n this.syncTextProps(entry.mesh, component);\n entry.mesh.sync();\n if (changed.prop.prop[0] === 'text') this.scheduleI18nRequest();\n }\n\n private handleRemove(id: number) {\n const entry = this.texts.get(id);\n if (!entry) return;\n\n this.threeContext.detachVisual(id, entry.mesh);\n entry.mesh.dispose();\n this.texts.delete(id);\n this.poseBridges.delete(id);\n }\n\n private syncTextProps(textMesh: TroikaText, component: Text3D) {\n textMesh.text = this.resolveText(component);\n textMesh.fontSize = component.fontSize;\n textMesh.color = component.color;\n textMesh.anchorX = component.anchorX;\n textMesh.anchorY = component.anchorY;\n if (component.maxWidth > 0) {\n textMesh.maxWidth = component.maxWidth;\n }\n if (component.font) {\n textMesh.font = component.font;\n }\n }\n\n private applyPose(gameObject: GameObject, component: Text3D, textMesh: TroikaText) {\n let bridge = this.poseBridges.get(gameObject.id);\n if (!bridge) {\n bridge = new VisualPoseBridge();\n this.poseBridges.set(gameObject.id, bridge);\n }\n const transform = gameObject.getComponent(Transform3D) as Transform3D | undefined;\n if (!bridge.sync(component, transform)) {\n textMesh.position.set(0, 0, 0);\n textMesh.rotation.set(0, 0, 0);\n return;\n }\n textMesh.position.set(component.positionX, component.positionY, component.positionZ);\n textMesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n }\n\n onDestroy() {\n this.i18nRequestId += 1;\n this.firstI18nSettled = false;\n this.i18nNeeded = false;\n this.resolvedSourceTexts.clear();\n for (const [id] of this.texts) {\n this.handleRemove(id);\n }\n this.texts.clear();\n }\n\n private resolveText(component: Text3D): string {\n if (\n shouldHoldForMissingTranslation(component.text, this.translations, {\n sourceLocale: this.sourceLocale,\n targetLocale: this.targetLocale,\n i18nNeeded: this.i18nNeeded,\n firstI18nSettled: this.firstI18nSettled,\n resolvedSourceTexts: this.resolvedSourceTexts,\n })\n ) {\n return '';\n }\n return localizeText(\n component.text,\n component.replacements,\n this.sourceLocale,\n this.targetLocale,\n this.translations,\n );\n }\n\n private rememberSourceTexts(texts?: Iterable<string | undefined | null>) {\n addSourceTexts(this.knownSourceTexts, texts);\n }\n\n private collectSourceTexts(): string[] {\n for (const entry of this.texts.values()) {\n this.rememberSourceTexts([entry.component.text]);\n }\n return [...this.knownSourceTexts];\n }\n\n private scheduleI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled || this.i18nRequestScheduled) return;\n this.i18nRequestScheduled = true;\n queueMicrotask(() => {\n this.i18nRequestScheduled = false;\n this.startI18nRequest();\n });\n }\n\n private startI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled) return;\n const sourceTexts = this.collectSourceTexts();\n if (\n !shouldRequestI18nForSourceTexts(sourceTexts, this.translations, {\n i18nNeeded: this.i18nNeeded,\n lastRequestedSourceTexts: this.lastRequestedSourceTexts,\n })\n ) {\n return;\n }\n void this.requestI18nAndApply();\n }\n\n private async requestI18nAndApply() {\n const sourceTexts = this.collectSourceTexts();\n this.lastRequestedSourceTexts = sourceTextsSignature(sourceTexts);\n const requestId = ++this.i18nRequestId;\n const result = await requestHostI18n({\n sourceLocale: this.sourceLocale,\n sourceTexts,\n });\n if (requestId !== this.i18nRequestId) return;\n addSourceTexts(this.resolvedSourceTexts, sourceTexts);\n this.i18nNeeded = result.needed;\n if (!result.needed) {\n this.refreshAllText();\n return;\n }\n this.setI18n(result.locale, result.translations);\n }\n\n private refreshAllText() {\n for (const entry of this.texts.values()) {\n entry.mesh.text = this.resolveText(entry.component);\n entry.mesh.sync();\n }\n }\n}\n"],"names":["Component","__decorate","Field","Renderer3D","Renderer3DSystem","OBSERVER_TYPE","TroikaText","tagObject3D","VisualPoseBridge","Transform3D","decorators"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),o=require("@combos-fun/inspector-decorator"),s=require("@combos-fun/plugin-renderer-3d"),r=require("troika-three-text");class i extends t.Component{constructor(){super(...arguments),this.text="",this.replacements={},this.fontSize=.5,this.color=16777215,this.anchorX="center",this.anchorY="middle",this.maxWidth=0,this.font="",this.positionX=0,this.positionY=0,this.positionZ=0,this.rotationX=0,this.rotationY=0,this.rotationZ=0}static{this.componentName="Text3D"}init(e){if(!e)return;const{replacements:t,...o}=e;Object.assign(this,o),t&&(this.replacements={...t})}}e.__decorate([o.Field({type:"string",group:"Text3D",label:"text",description:"Visible text content.",editor:"text"})],i.prototype,"text",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"fontSize",description:"Font size.",editor:"number-stepper"})],i.prototype,"fontSize",void 0),e.__decorate([o.Field({type:"number",group:"Text3D",label:"color",description:"Color value.",editor:"number-stepper"})],i.prototype,"color",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"anchorX",description:"Horizontal text anchor.",editor:"text"})],i.prototype,"anchorX",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"anchorY",description:"Vertical text anchor.",editor:"text"})],i.prototype,"anchorY",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"maxWidth",description:"Maximum text wrap width.",editor:"number-stepper"})],i.prototype,"maxWidth",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"font",description:"Font URL or path for troika-three-text (not an engine resource name).",editor:"text"})],i.prototype,"font",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionX",description:"Local X position.",editor:"number-stepper"})],i.prototype,"positionX",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionY",description:"Local Y position.",editor:"number-stepper"})],i.prototype,"positionY",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionZ",description:"Local Z position.",editor:"number-stepper"})],i.prototype,"positionZ",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationX",description:"Rotation around X in radians.",editor:"number-stepper"})],i.prototype,"rotationX",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationY",description:"Rotation around Y in radians.",editor:"number-stepper"})],i.prototype,"rotationY",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationZ",description:"Rotation around Z in radians.",editor:"number-stepper"})],i.prototype,"rotationZ",void 0);function n(e=("undefined"==typeof window?void 0:window.combos)){return!!e&&"function"==typeof e.requestI18n}function a(e){if(!e||"object"!=typeof e)return{needed:!1};const t=e;if(!0!==t.needed)return{needed:!1};if("string"!=typeof t.locale||!t.locale.trim())return{needed:!1};if(!t.translations||"object"!=typeof t.translations||Array.isArray(t.translations))return{needed:!1};const o=Object.entries(t.translations);return o.some(([,e])=>"string"!=typeof e)?{needed:!1}:{needed:!0,locale:t.locale.trim(),translations:Object.fromEntries(o)}}async function c(e){if("undefined"==typeof window||!n(window.combos))return{needed:!1};try{return a(await window.combos.requestI18n(e))}catch{return{needed:!1}}}const d=/\{([A-Za-z_$][\w$.-]*)\}/g;function p(e,t){return t?e.replace(d,(e,o)=>Object.prototype.hasOwnProperty.call(t,o)?String(t[o]):e):e}function l(e,t){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const o=e.trim();return o&&o!==e&&Object.prototype.hasOwnProperty.call(t,o)?t[o]:void 0}function
|
|
1
|
+
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),o=require("@combos-fun/inspector-decorator"),s=require("@combos-fun/plugin-renderer-3d"),r=require("troika-three-text");class i extends t.Component{constructor(){super(...arguments),this.text="",this.replacements={},this.fontSize=.5,this.color=16777215,this.anchorX="center",this.anchorY="middle",this.maxWidth=0,this.font="",this.positionX=0,this.positionY=0,this.positionZ=0,this.rotationX=0,this.rotationY=0,this.rotationZ=0}static{this.componentName="Text3D"}init(e){if(!e)return;const{replacements:t,...o}=e;Object.assign(this,o),t&&(this.replacements={...t})}}e.__decorate([o.Field({type:"string",group:"Text3D",label:"text",description:"Visible text content.",editor:"text"})],i.prototype,"text",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"fontSize",description:"Font size.",editor:"number-stepper"})],i.prototype,"fontSize",void 0),e.__decorate([o.Field({type:"number",group:"Text3D",label:"color",description:"Color value.",editor:"number-stepper"})],i.prototype,"color",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"anchorX",description:"Horizontal text anchor.",editor:"text"})],i.prototype,"anchorX",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"anchorY",description:"Vertical text anchor.",editor:"text"})],i.prototype,"anchorY",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"maxWidth",description:"Maximum text wrap width.",editor:"number-stepper"})],i.prototype,"maxWidth",void 0),e.__decorate([o.Field({type:"string",group:"Text3D",label:"font",description:"Font URL or path for troika-three-text (not an engine resource name).",editor:"text"})],i.prototype,"font",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionX",description:"Local X position.",editor:"number-stepper"})],i.prototype,"positionX",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionY",description:"Local Y position.",editor:"number-stepper"})],i.prototype,"positionY",void 0),e.__decorate([o.Field({type:"number",step:.1,group:"Text3D",label:"positionZ",description:"Local Z position.",editor:"number-stepper"})],i.prototype,"positionZ",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationX",description:"Rotation around X in radians.",editor:"number-stepper"})],i.prototype,"rotationX",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationY",description:"Rotation around Y in radians.",editor:"number-stepper"})],i.prototype,"rotationY",void 0),e.__decorate([o.Field({type:"number",step:.01,group:"Text3D",label:"rotationZ",description:"Rotation around Z in radians.",editor:"number-stepper"})],i.prototype,"rotationZ",void 0);function n(e=("undefined"==typeof window?void 0:window.combos)){return!!e&&"function"==typeof e.requestI18n}function a(e){if(!e||"object"!=typeof e)return{needed:!1};const t=e;if(!0!==t.needed)return{needed:!1};if("string"!=typeof t.locale||!t.locale.trim())return{needed:!1};if(!t.translations||"object"!=typeof t.translations||Array.isArray(t.translations))return{needed:!1};const o=Object.entries(t.translations);return o.some(([,e])=>"string"!=typeof e)?{needed:!1}:{needed:!0,locale:t.locale.trim(),translations:Object.fromEntries(o)}}async function c(e){if("undefined"==typeof window||!n(window.combos))return{needed:!1};try{return a(await window.combos.requestI18n(e))}catch{return{needed:!1}}}const d=/\{([A-Za-z_$][\w$.-]*)\}/g;function p(e,t){return t?e.replace(d,(e,o)=>Object.prototype.hasOwnProperty.call(t,o)?String(t[o]):e):e}function l(e,t){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const o=e.trim();return o&&o!==e&&Object.prototype.hasOwnProperty.call(t,o)?t[o]:void 0}function h(e,t){return void 0!==l(e,t)}function u(e,t){return e.some(e=>!h(e,t))}function x(e){return[...e].sort().join("\0")}function m(e,t,o){return!!o.i18nNeeded&&(!!u(e,t)&&x(e)!==o.lastRequestedSourceTexts)}function f(e,t,o){if(!o.sourceLocale)return!1;const s=e.trim();return!!s&&(!h(e,t)&&(!o.firstI18nSettled||!!o.i18nNeeded&&(o.sourceLocale.toLowerCase()!==o.targetLocale.toLowerCase()&&!o.resolvedSourceTexts.has(s))))}function T(e,t,o,s,r){return p(!!o&&!!s&&o.toLowerCase()!==s.toLowerCase()?l(e,r)??e:e,t)}function y(e,t){if(t)for(const o of t){const t="string"==typeof o?o.trim():"";t&&e.add(t)}}function S(e,t){const o={...e};for(const[e,s]of Object.entries(t))"string"==typeof s&&(o[e]=s);return o}let b=class extends s.Renderer3D{constructor(){super(...arguments),this.name="Text3DSystem",this.texts=new Map,this.poseBridges=new Map,this.sourceLocale="",this.targetLocale="",this.translations={},this.knownSourceTexts=new Set,this.lastRequestedSourceTexts="",this.i18nRequestScheduled=!1,this.i18nRequestId=0,this.firstI18nSettled=!1,this.i18nNeeded=!1,this.resolvedSourceTexts=new Set}static{this.systemName="Text3DSystem"}init(e){this.game.getSystem(s.Renderer3DSystem).rendererManager.register(this),this.sourceLocale=e?.sourceLocale?.trim()??"",this.targetLocale=this.sourceLocale,this.declareSourceTexts(e?.sourceTexts)}declareSourceTexts(e){this.rememberSourceTexts(e),this.scheduleI18nRequest()}async beforeReady(){this.firstI18nSettled||(this.update(),this.sourceLocale?(await this.requestI18nAndApply(),this.i18nNeeded&&u(this.collectSourceTexts(),this.translations)&&await this.requestI18nAndApply(),this.firstI18nSettled=!0,this.refreshAllText()):this.firstI18nSettled=!0)}setI18n(e,t){const o=e?.trim();o&&t&&"object"==typeof t&&(this.targetLocale=o,this.translations=S(this.translations,t),this.refreshAllText())}componentChanged(e){"Text3D"===e.componentName&&(e.type===t.OBSERVER_TYPE.ADD?this.handleAdd(e.gameObject,e.component):e.type===t.OBSERVER_TYPE.REMOVE?this.handleRemove(e.gameObject.id):this.handleChange(e))}rendererUpdate(e){const t=e.getComponent(i);if(!t)return;const o=this.texts.get(e.id);o&&this.applyPose(e,t,o.mesh)}handleAdd(e,t){const o=new r.Text;this.syncTextProps(o,t),o.sync(),s.tagObject3D(o,e.id),this.threeContext.attachVisual(e.id,o,e),this.texts.set(e.id,{mesh:o,component:t}),this.poseBridges.set(e.id,new s.VisualPoseBridge),this.rememberSourceTexts([t.text]),this.scheduleI18nRequest()}handleChange(e){const t=this.texts.get(e.gameObject.id);if(!t)return;const o=e.component;t.component=o,"text"===e.prop.prop[0]&&this.rememberSourceTexts([o.text]),this.syncTextProps(t.mesh,o),t.mesh.sync(),"text"===e.prop.prop[0]&&this.scheduleI18nRequest()}handleRemove(e){const t=this.texts.get(e);t&&(this.threeContext.detachVisual(e,t.mesh),t.mesh.dispose(),this.texts.delete(e),this.poseBridges.delete(e))}syncTextProps(e,t){e.text=this.resolveText(t),e.fontSize=t.fontSize,e.color=t.color,e.anchorX=t.anchorX,e.anchorY=t.anchorY,t.maxWidth>0&&(e.maxWidth=t.maxWidth),t.font&&(e.font=t.font)}applyPose(e,t,o){let r=this.poseBridges.get(e.id);r||(r=new s.VisualPoseBridge,this.poseBridges.set(e.id,r));const i=e.getComponent(s.Transform3D);if(!r.sync(t,i))return o.position.set(0,0,0),void o.rotation.set(0,0,0);o.position.set(t.positionX,t.positionY,t.positionZ),o.rotation.set(t.rotationX,t.rotationY,t.rotationZ)}onDestroy(){this.i18nRequestId+=1,this.firstI18nSettled=!1,this.i18nNeeded=!1,this.resolvedSourceTexts.clear();for(const[e]of this.texts)this.handleRemove(e);this.texts.clear()}resolveText(e){return f(e.text,this.translations,{sourceLocale:this.sourceLocale,targetLocale:this.targetLocale,i18nNeeded:this.i18nNeeded,firstI18nSettled:this.firstI18nSettled,resolvedSourceTexts:this.resolvedSourceTexts})?"":T(e.text,e.replacements,this.sourceLocale,this.targetLocale,this.translations)}rememberSourceTexts(e){y(this.knownSourceTexts,e)}collectSourceTexts(){for(const e of this.texts.values())this.rememberSourceTexts([e.component.text]);return[...this.knownSourceTexts]}scheduleI18nRequest(){this.sourceLocale&&this.firstI18nSettled&&!this.i18nRequestScheduled&&(this.i18nRequestScheduled=!0,queueMicrotask(()=>{this.i18nRequestScheduled=!1,this.startI18nRequest()}))}startI18nRequest(){if(!this.sourceLocale||!this.firstI18nSettled)return;m(this.collectSourceTexts(),this.translations,{i18nNeeded:this.i18nNeeded,lastRequestedSourceTexts:this.lastRequestedSourceTexts})&&this.requestI18nAndApply()}async requestI18nAndApply(){const e=this.collectSourceTexts();this.lastRequestedSourceTexts=x(e);const t=++this.i18nRequestId,o=await c({sourceLocale:this.sourceLocale,sourceTexts:e});t===this.i18nRequestId&&(y(this.resolvedSourceTexts,e),this.i18nNeeded=o.needed,o.needed?this.setI18n(o.locale,o.translations):this.refreshAllText())}refreshAllText(){for(const e of this.texts.values())e.mesh.text=this.resolveText(e.component),e.mesh.sync()}};b=e.__decorate([t.decorators.componentObserver({Text3D:["text",{prop:["replacements"],deep:!0},"fontSize","color","anchorX","anchorY","maxWidth","font","positionX","positionY","positionZ","rotationX","rotationY","rotationZ"]})],b);var g=b;exports.COMBOS_HOST_SDK="combos",exports.Text3D=i,exports.Text3DSystem=g,exports.addSourceTexts=y,exports.findTranslatedTemplate=l,exports.hasCombosRequestI18n=n,exports.hasMissingSourceTranslations=u,exports.hasSourceTranslation=h,exports.interpolateText=p,exports.localizeText=T,exports.mergeTranslations=S,exports.parseI18nResult=a,exports.requestHostI18n=c,exports.shouldHoldForMissingTranslation=f,exports.shouldRequestI18nForSourceTexts=m,exports.sourceTextsSignature=x;
|
|
@@ -242,15 +242,22 @@ function shouldRequestI18nForSourceTexts(sourceTexts, translations, state) {
|
|
|
242
242
|
return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;
|
|
243
243
|
}
|
|
244
244
|
function shouldHoldForMissingTranslation(sourceText, translations, state) {
|
|
245
|
-
if (!state.sourceLocale
|
|
246
|
-
return false;
|
|
247
|
-
if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase())
|
|
245
|
+
if (!state.sourceLocale)
|
|
248
246
|
return false;
|
|
249
247
|
const trimmed = sourceText.trim();
|
|
250
248
|
if (!trimmed)
|
|
251
249
|
return false;
|
|
252
250
|
if (hasSourceTranslation(sourceText, translations))
|
|
253
251
|
return false;
|
|
252
|
+
// Flush mounts Text before the first requestI18n. targetLocale still equals
|
|
253
|
+
// sourceLocale and i18nNeeded is still false, so holding only after settle
|
|
254
|
+
// would paint the source copy, then swap it when the host replies.
|
|
255
|
+
if (!state.firstI18nSettled)
|
|
256
|
+
return true;
|
|
257
|
+
if (!state.i18nNeeded)
|
|
258
|
+
return false;
|
|
259
|
+
if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase())
|
|
260
|
+
return false;
|
|
254
261
|
return !state.resolvedSourceTexts.has(trimmed);
|
|
255
262
|
}
|
|
256
263
|
function localizeText(sourceText, replacements, sourceLocale, targetLocale, translations) {
|
|
@@ -325,6 +332,8 @@ let Text3DSystem = class Text3DSystem extends Renderer3D {
|
|
|
325
332
|
await this.requestI18nAndApply();
|
|
326
333
|
}
|
|
327
334
|
this.firstI18nSettled = true;
|
|
335
|
+
// needed:false refresh still ran with firstI18nSettled=false (empty hold).
|
|
336
|
+
this.refreshAllText();
|
|
328
337
|
}
|
|
329
338
|
setI18n(locale, translations) {
|
|
330
339
|
const targetLocale = locale?.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-3d-text.esm.js","sources":["../lib/component.ts","../lib/hostSdk.ts","../lib/localization.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextReplacements } from './localization';\n\nexport type { TextReplacementValue, TextReplacements } from './localization';\n\nexport interface Text3DParams {\n text?: string;\n /** Values substituted into named placeholders such as `{score}`. */\n replacements?: TextReplacements;\n fontSize?: number;\n color?: number;\n anchorX?: string;\n anchorY?: string;\n maxWidth?: number;\n font?: string;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n}\n\nexport default class Text3D extends Component<Text3DParams> {\n static componentName: string = 'Text3D';\n\n @Field({\n\n type: 'string',\n\n group: 'Text3D',\n\n label: 'text',\n\n description: 'Visible text content.',\n\n editor: 'text',\n\n })\n\n text: string = '';\n\n replacements: TextReplacements = {};\n\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'fontSize',\n description: 'Font size.',\n editor: 'number-stepper',\n })\n fontSize: number = 0.5;\n @Field({\n type: 'number',\n group: 'Text3D',\n label: 'color',\n description: 'Color value.',\n editor: 'number-stepper',\n })\n color: number = 0xffffff;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorX',\n description: 'Horizontal text anchor.',\n editor: 'text',\n })\n anchorX: string = 'center';\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorY',\n description: 'Vertical text anchor.',\n editor: 'text',\n })\n anchorY: string = 'middle';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'maxWidth',\n description: 'Maximum text wrap width.',\n editor: 'number-stepper',\n })\n maxWidth: number = 0;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'font',\n description: 'Font URL or path for troika-three-text (not an engine resource name).',\n editor: 'text',\n })\n font: string = '';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n\n init(obj?: Text3DParams) {\n if (!obj) return;\n const { replacements, ...rest } = obj;\n Object.assign(this, rest);\n if (replacements) this.replacements = { ...replacements };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` hostSdk. */\nimport type { TextTranslations } from './localization';\n\n/** Host-injected global. The SDK itself is not part of this repo. */\nexport const COMBOS_HOST_SDK = 'combos' as const;\n\nexport interface CombosI18nRequest {\n sourceLocale: string;\n sourceTexts: string[];\n}\n\nexport type CombosI18nResult =\n | { needed: false }\n | { needed: true; locale: string; translations: TextTranslations };\n\nexport interface CombosHostSdk {\n requestI18n?(request: CombosI18nRequest): Promise<CombosI18nResult>;\n}\n\ndeclare global {\n interface Window {\n combos?: CombosHostSdk;\n }\n}\n\nexport function hasCombosRequestI18n(\n sdk: CombosHostSdk | undefined | null = typeof window === 'undefined' ? undefined : window.combos,\n): sdk is CombosHostSdk & { requestI18n: NonNullable<CombosHostSdk['requestI18n']> } {\n return !!sdk && typeof sdk.requestI18n === 'function';\n}\n\nexport function parseI18nResult(data: unknown): CombosI18nResult {\n if (!data || typeof data !== 'object') return { needed: false };\n const input = data as {\n needed?: unknown;\n locale?: unknown;\n translations?: unknown;\n };\n if (input.needed !== true) return { needed: false };\n if (typeof input.locale !== 'string' || !input.locale.trim()) {\n return { needed: false };\n }\n if (\n !input.translations ||\n typeof input.translations !== 'object' ||\n Array.isArray(input.translations)\n ) {\n return { needed: false };\n }\n const entries = Object.entries(input.translations);\n if (entries.some(([, value]) => typeof value !== 'string')) {\n return { needed: false };\n }\n return {\n needed: true,\n locale: input.locale.trim(),\n translations: Object.fromEntries(entries) as TextTranslations,\n };\n}\n\n/** Ask the injected host SDK. Always resolves; missing method means no translation. */\nexport async function requestHostI18n(\n request: CombosI18nRequest,\n): Promise<CombosI18nResult> {\n if (typeof window === 'undefined' || !hasCombosRequestI18n(window.combos)) {\n return { needed: false };\n }\n try {\n return parseI18nResult(await window.combos.requestI18n(request));\n } catch {\n return { needed: false };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` localization. */\n\nexport type TextReplacementValue = string | number;\nexport type TextReplacements = Record<string, TextReplacementValue>;\nexport type TextTranslations = Record<string, string>;\n\nconst PLACEHOLDER_PATTERN = /\\{([A-Za-z_$][\\w$.-]*)\\}/g;\n\nexport function interpolateText(\n template: string,\n replacements?: TextReplacements,\n): string {\n if (!replacements) return template;\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, name: string) => {\n if (!Object.prototype.hasOwnProperty.call(replacements, name)) {\n return placeholder;\n }\n return String(replacements[name]);\n });\n}\n\nexport function findTranslatedTemplate(\n sourceText: string,\n translations: TextTranslations,\n): string | undefined {\n if (Object.prototype.hasOwnProperty.call(translations, sourceText)) {\n return translations[sourceText];\n }\n const trimmed = sourceText.trim();\n if (\n trimmed &&\n trimmed !== sourceText &&\n Object.prototype.hasOwnProperty.call(translations, trimmed)\n ) {\n return translations[trimmed];\n }\n return undefined;\n}\n\nexport function hasSourceTranslation(\n sourceText: string,\n translations: TextTranslations,\n): boolean {\n return findTranslatedTemplate(sourceText, translations) !== undefined;\n}\n\nexport function hasMissingSourceTranslations(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n): boolean {\n return sourceTexts.some((text) => !hasSourceTranslation(text, translations));\n}\n\nexport function sourceTextsSignature(sourceTexts: readonly string[]): string {\n return [...sourceTexts].sort().join('\\0');\n}\n\n/** After the first host reply, only request again for templates still missing. */\nexport function shouldRequestI18nForSourceTexts(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n state: {\n i18nNeeded: boolean;\n lastRequestedSourceTexts: string;\n },\n): boolean {\n if (!state.i18nNeeded) return false;\n if (!hasMissingSourceTranslations(sourceTexts, translations)) return false;\n return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;\n}\n\nexport function shouldHoldForMissingTranslation(\n sourceText: string,\n translations: TextTranslations,\n state: {\n sourceLocale: string;\n targetLocale: string;\n i18nNeeded: boolean;\n firstI18nSettled: boolean;\n resolvedSourceTexts: ReadonlySet<string>;\n },\n): boolean {\n if (!state.sourceLocale || !state.i18nNeeded || !state.firstI18nSettled) return false;\n if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase()) return false;\n const trimmed = sourceText.trim();\n if (!trimmed) return false;\n if (hasSourceTranslation(sourceText, translations)) return false;\n return !state.resolvedSourceTexts.has(trimmed);\n}\n\nexport function localizeText(\n sourceText: string,\n replacements: TextReplacements | undefined,\n sourceLocale: string,\n targetLocale: string,\n translations: TextTranslations,\n): string {\n const shouldTranslate =\n !!sourceLocale &&\n !!targetLocale &&\n sourceLocale.toLowerCase() !== targetLocale.toLowerCase();\n const template = shouldTranslate\n ? findTranslatedTemplate(sourceText, translations) ?? sourceText\n : sourceText;\n return interpolateText(template, replacements);\n}\n\nexport function addSourceTexts(\n target: Set<string>,\n texts?: Iterable<string | undefined | null>,\n) {\n if (!texts) return;\n for (const text of texts) {\n const source = typeof text === 'string' ? text.trim() : '';\n if (source) target.add(source);\n }\n}\n\nexport function mergeTranslations(\n current: TextTranslations,\n incoming: Record<string, unknown>,\n): TextTranslations {\n const next = { ...current };\n for (const [key, value] of Object.entries(incoming)) {\n if (typeof value === 'string') next[key] = value;\n }\n return next;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem, tagObject3D, Transform3D, VisualPoseBridge } from '@combos-fun/plugin-renderer-3d';\nimport { Text as TroikaText } from 'troika-three-text';\nimport Text3D from './component';\nimport { requestHostI18n } from './hostSdk';\nimport {\n addSourceTexts,\n hasMissingSourceTranslations,\n localizeText,\n mergeTranslations,\n shouldHoldForMissingTranslation,\n shouldRequestI18nForSourceTexts,\n sourceTextsSignature,\n type TextTranslations,\n} from './localization';\n\nexport interface Text3DSystemParams {\n /** BCP 47 locale of the source text, for example `zh-CN`. Omit to disable host-driven i18n. */\n sourceLocale?: string;\n /**\n * All source templates to translate on first `requestI18n`, including copy\n * for screens that are not mounted yet. The system also keeps a growing\n * session catalog of every later template it sees.\n */\n sourceTexts?: string[];\n}\n\n@decorators.componentObserver({\n Text3D: [\n 'text',\n { prop: ['replacements'], deep: true },\n 'fontSize', 'color', 'anchorX', 'anchorY', 'maxWidth', 'font',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n ],\n})\nexport default class Text3DSystem extends Renderer3D<Text3DSystemParams> {\n static systemName = 'Text3DSystem';\n name: string = 'Text3DSystem';\n\n private texts = new Map<number, { mesh: TroikaText; component: Text3D }>();\n private poseBridges = new Map<number, VisualPoseBridge>();\n private sourceLocale = '';\n private targetLocale = '';\n private translations: TextTranslations = {};\n /** Growing catalog of every source template seen this session. */\n private knownSourceTexts = new Set<string>();\n private lastRequestedSourceTexts = '';\n private i18nRequestScheduled = false;\n private i18nRequestId = 0;\n private firstI18nSettled = false;\n private i18nNeeded = false;\n private resolvedSourceTexts = new Set<string>();\n\n init(params?: Text3DSystemParams) {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n this.sourceLocale = params?.sourceLocale?.trim() ?? '';\n this.targetLocale = this.sourceLocale;\n this.declareSourceTexts(params?.sourceTexts);\n }\n\n /** Register extra source templates before or after ready. First request includes these. */\n declareSourceTexts(texts?: string[]) {\n this.rememberSourceTexts(texts);\n this.scheduleI18nRequest();\n }\n\n async beforeReady() {\n if (this.firstI18nSettled) return;\n this.update();\n if (!this.sourceLocale) {\n this.firstI18nSettled = true;\n return;\n }\n await this.requestI18nAndApply();\n if (\n this.i18nNeeded &&\n hasMissingSourceTranslations(this.collectSourceTexts(), this.translations)\n ) {\n await this.requestI18nAndApply();\n }\n this.firstI18nSettled = true;\n }\n\n setI18n(locale: string, translations: TextTranslations) {\n const targetLocale = locale?.trim();\n if (!targetLocale || !translations || typeof translations !== 'object') return;\n this.targetLocale = targetLocale;\n this.translations = mergeTranslations(this.translations, translations);\n this.refreshAllText();\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as Text3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(Text3D) as Text3D;\n if (!component) return;\n\n const entry = this.texts.get(gameObject.id);\n if (!entry) return;\n this.applyPose(gameObject, component, entry.mesh);\n }\n\n private handleAdd(gameObject: GameObject, component: Text3D) {\n const textMesh = new TroikaText();\n this.syncTextProps(textMesh, component);\n textMesh.sync();\n tagObject3D(textMesh, gameObject.id);\n\n this.threeContext.attachVisual(gameObject.id, textMesh, gameObject);\n this.texts.set(gameObject.id, { mesh: textMesh, component });\n this.poseBridges.set(gameObject.id, new VisualPoseBridge());\n this.rememberSourceTexts([component.text]);\n this.scheduleI18nRequest();\n }\n\n private handleChange(changed: ComponentChanged) {\n const entry = this.texts.get(changed.gameObject.id);\n if (!entry) return;\n const component = changed.component as Text3D;\n entry.component = component;\n if (changed.prop.prop[0] === 'text') this.rememberSourceTexts([component.text]);\n this.syncTextProps(entry.mesh, component);\n entry.mesh.sync();\n if (changed.prop.prop[0] === 'text') this.scheduleI18nRequest();\n }\n\n private handleRemove(id: number) {\n const entry = this.texts.get(id);\n if (!entry) return;\n\n this.threeContext.detachVisual(id, entry.mesh);\n entry.mesh.dispose();\n this.texts.delete(id);\n this.poseBridges.delete(id);\n }\n\n private syncTextProps(textMesh: TroikaText, component: Text3D) {\n textMesh.text = this.resolveText(component);\n textMesh.fontSize = component.fontSize;\n textMesh.color = component.color;\n textMesh.anchorX = component.anchorX;\n textMesh.anchorY = component.anchorY;\n if (component.maxWidth > 0) {\n textMesh.maxWidth = component.maxWidth;\n }\n if (component.font) {\n textMesh.font = component.font;\n }\n }\n\n private applyPose(gameObject: GameObject, component: Text3D, textMesh: TroikaText) {\n let bridge = this.poseBridges.get(gameObject.id);\n if (!bridge) {\n bridge = new VisualPoseBridge();\n this.poseBridges.set(gameObject.id, bridge);\n }\n const transform = gameObject.getComponent(Transform3D) as Transform3D | undefined;\n if (!bridge.sync(component, transform)) {\n textMesh.position.set(0, 0, 0);\n textMesh.rotation.set(0, 0, 0);\n return;\n }\n textMesh.position.set(component.positionX, component.positionY, component.positionZ);\n textMesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n }\n\n onDestroy() {\n this.i18nRequestId += 1;\n this.firstI18nSettled = false;\n this.i18nNeeded = false;\n this.resolvedSourceTexts.clear();\n for (const [id] of this.texts) {\n this.handleRemove(id);\n }\n this.texts.clear();\n }\n\n private resolveText(component: Text3D): string {\n if (\n shouldHoldForMissingTranslation(component.text, this.translations, {\n sourceLocale: this.sourceLocale,\n targetLocale: this.targetLocale,\n i18nNeeded: this.i18nNeeded,\n firstI18nSettled: this.firstI18nSettled,\n resolvedSourceTexts: this.resolvedSourceTexts,\n })\n ) {\n return '';\n }\n return localizeText(\n component.text,\n component.replacements,\n this.sourceLocale,\n this.targetLocale,\n this.translations,\n );\n }\n\n private rememberSourceTexts(texts?: Iterable<string | undefined | null>) {\n addSourceTexts(this.knownSourceTexts, texts);\n }\n\n private collectSourceTexts(): string[] {\n for (const entry of this.texts.values()) {\n this.rememberSourceTexts([entry.component.text]);\n }\n return [...this.knownSourceTexts];\n }\n\n private scheduleI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled || this.i18nRequestScheduled) return;\n this.i18nRequestScheduled = true;\n queueMicrotask(() => {\n this.i18nRequestScheduled = false;\n this.startI18nRequest();\n });\n }\n\n private startI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled) return;\n const sourceTexts = this.collectSourceTexts();\n if (\n !shouldRequestI18nForSourceTexts(sourceTexts, this.translations, {\n i18nNeeded: this.i18nNeeded,\n lastRequestedSourceTexts: this.lastRequestedSourceTexts,\n })\n ) {\n return;\n }\n void this.requestI18nAndApply();\n }\n\n private async requestI18nAndApply() {\n const sourceTexts = this.collectSourceTexts();\n this.lastRequestedSourceTexts = sourceTextsSignature(sourceTexts);\n const requestId = ++this.i18nRequestId;\n const result = await requestHostI18n({\n sourceLocale: this.sourceLocale,\n sourceTexts,\n });\n if (requestId !== this.i18nRequestId) return;\n addSourceTexts(this.resolvedSourceTexts, sourceTexts);\n this.i18nNeeded = result.needed;\n if (!result.needed) {\n this.refreshAllText();\n return;\n }\n this.setI18n(result.locale, result.translations);\n }\n\n private refreshAllText() {\n for (const entry of this.texts.values()) {\n entry.mesh.text = this.resolveText(entry.component);\n entry.mesh.sync();\n }\n }\n}\n"],"names":["TroikaText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-3d-text.esm.js","sources":["../lib/component.ts","../lib/hostSdk.ts","../lib/localization.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextReplacements } from './localization';\n\nexport type { TextReplacementValue, TextReplacements } from './localization';\n\nexport interface Text3DParams {\n text?: string;\n /** Values substituted into named placeholders such as `{score}`. */\n replacements?: TextReplacements;\n fontSize?: number;\n color?: number;\n anchorX?: string;\n anchorY?: string;\n maxWidth?: number;\n font?: string;\n positionX?: number;\n positionY?: number;\n positionZ?: number;\n rotationX?: number;\n rotationY?: number;\n rotationZ?: number;\n}\n\nexport default class Text3D extends Component<Text3DParams> {\n static componentName: string = 'Text3D';\n\n @Field({\n\n type: 'string',\n\n group: 'Text3D',\n\n label: 'text',\n\n description: 'Visible text content.',\n\n editor: 'text',\n\n })\n\n text: string = '';\n\n replacements: TextReplacements = {};\n\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'fontSize',\n description: 'Font size.',\n editor: 'number-stepper',\n })\n fontSize: number = 0.5;\n @Field({\n type: 'number',\n group: 'Text3D',\n label: 'color',\n description: 'Color value.',\n editor: 'number-stepper',\n })\n color: number = 0xffffff;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorX',\n description: 'Horizontal text anchor.',\n editor: 'text',\n })\n anchorX: string = 'center';\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'anchorY',\n description: 'Vertical text anchor.',\n editor: 'text',\n })\n anchorY: string = 'middle';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'maxWidth',\n description: 'Maximum text wrap width.',\n editor: 'number-stepper',\n })\n maxWidth: number = 0;\n @Field({\n type: 'string',\n group: 'Text3D',\n label: 'font',\n description: 'Font URL or path for troika-three-text (not an engine resource name).',\n editor: 'text',\n })\n font: string = '';\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionX',\n description: 'Local X position.',\n editor: 'number-stepper',\n })\n positionX: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionY',\n description: 'Local Y position.',\n editor: 'number-stepper',\n })\n positionY: number = 0;\n @Field({\n type: 'number',\n step: 0.1,\n group: 'Text3D',\n label: 'positionZ',\n description: 'Local Z position.',\n editor: 'number-stepper',\n })\n positionZ: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationX',\n description: 'Rotation around X in radians.',\n editor: 'number-stepper',\n })\n rotationX: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationY',\n description: 'Rotation around Y in radians.',\n editor: 'number-stepper',\n })\n rotationY: number = 0;\n @Field({\n type: 'number',\n step: 0.01,\n group: 'Text3D',\n label: 'rotationZ',\n description: 'Rotation around Z in radians.',\n editor: 'number-stepper',\n })\n rotationZ: number = 0;\n\n init(obj?: Text3DParams) {\n if (!obj) return;\n const { replacements, ...rest } = obj;\n Object.assign(this, rest);\n if (replacements) this.replacements = { ...replacements };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` hostSdk. */\nimport type { TextTranslations } from './localization';\n\n/** Host-injected global. The SDK itself is not part of this repo. */\nexport const COMBOS_HOST_SDK = 'combos' as const;\n\nexport interface CombosI18nRequest {\n sourceLocale: string;\n sourceTexts: string[];\n}\n\nexport type CombosI18nResult =\n | { needed: false }\n | { needed: true; locale: string; translations: TextTranslations };\n\nexport interface CombosHostSdk {\n requestI18n?(request: CombosI18nRequest): Promise<CombosI18nResult>;\n}\n\ndeclare global {\n interface Window {\n combos?: CombosHostSdk;\n }\n}\n\nexport function hasCombosRequestI18n(\n sdk: CombosHostSdk | undefined | null = typeof window === 'undefined' ? undefined : window.combos,\n): sdk is CombosHostSdk & { requestI18n: NonNullable<CombosHostSdk['requestI18n']> } {\n return !!sdk && typeof sdk.requestI18n === 'function';\n}\n\nexport function parseI18nResult(data: unknown): CombosI18nResult {\n if (!data || typeof data !== 'object') return { needed: false };\n const input = data as {\n needed?: unknown;\n locale?: unknown;\n translations?: unknown;\n };\n if (input.needed !== true) return { needed: false };\n if (typeof input.locale !== 'string' || !input.locale.trim()) {\n return { needed: false };\n }\n if (\n !input.translations ||\n typeof input.translations !== 'object' ||\n Array.isArray(input.translations)\n ) {\n return { needed: false };\n }\n const entries = Object.entries(input.translations);\n if (entries.some(([, value]) => typeof value !== 'string')) {\n return { needed: false };\n }\n return {\n needed: true,\n locale: input.locale.trim(),\n translations: Object.fromEntries(entries) as TextTranslations,\n };\n}\n\n/** Ask the injected host SDK. Always resolves; missing method means no translation. */\nexport async function requestHostI18n(\n request: CombosI18nRequest,\n): Promise<CombosI18nResult> {\n if (typeof window === 'undefined' || !hasCombosRequestI18n(window.combos)) {\n return { needed: false };\n }\n try {\n return parseI18nResult(await window.combos.requestI18n(request));\n } catch {\n return { needed: false };\n }\n}\n","/** Keep identical to `@combos-fun/plugin-renderer-text` localization. */\n\nexport type TextReplacementValue = string | number;\nexport type TextReplacements = Record<string, TextReplacementValue>;\nexport type TextTranslations = Record<string, string>;\n\nconst PLACEHOLDER_PATTERN = /\\{([A-Za-z_$][\\w$.-]*)\\}/g;\n\nexport function interpolateText(\n template: string,\n replacements?: TextReplacements,\n): string {\n if (!replacements) return template;\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, name: string) => {\n if (!Object.prototype.hasOwnProperty.call(replacements, name)) {\n return placeholder;\n }\n return String(replacements[name]);\n });\n}\n\nexport function findTranslatedTemplate(\n sourceText: string,\n translations: TextTranslations,\n): string | undefined {\n if (Object.prototype.hasOwnProperty.call(translations, sourceText)) {\n return translations[sourceText];\n }\n const trimmed = sourceText.trim();\n if (\n trimmed &&\n trimmed !== sourceText &&\n Object.prototype.hasOwnProperty.call(translations, trimmed)\n ) {\n return translations[trimmed];\n }\n return undefined;\n}\n\nexport function hasSourceTranslation(\n sourceText: string,\n translations: TextTranslations,\n): boolean {\n return findTranslatedTemplate(sourceText, translations) !== undefined;\n}\n\nexport function hasMissingSourceTranslations(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n): boolean {\n return sourceTexts.some((text) => !hasSourceTranslation(text, translations));\n}\n\nexport function sourceTextsSignature(sourceTexts: readonly string[]): string {\n return [...sourceTexts].sort().join('\\0');\n}\n\n/** After the first host reply, only request again for templates still missing. */\nexport function shouldRequestI18nForSourceTexts(\n sourceTexts: readonly string[],\n translations: TextTranslations,\n state: {\n i18nNeeded: boolean;\n lastRequestedSourceTexts: string;\n },\n): boolean {\n if (!state.i18nNeeded) return false;\n if (!hasMissingSourceTranslations(sourceTexts, translations)) return false;\n return sourceTextsSignature(sourceTexts) !== state.lastRequestedSourceTexts;\n}\n\nexport function shouldHoldForMissingTranslation(\n sourceText: string,\n translations: TextTranslations,\n state: {\n sourceLocale: string;\n targetLocale: string;\n i18nNeeded: boolean;\n firstI18nSettled: boolean;\n resolvedSourceTexts: ReadonlySet<string>;\n },\n): boolean {\n if (!state.sourceLocale) return false;\n const trimmed = sourceText.trim();\n if (!trimmed) return false;\n if (hasSourceTranslation(sourceText, translations)) return false;\n // Flush mounts Text before the first requestI18n. targetLocale still equals\n // sourceLocale and i18nNeeded is still false, so holding only after settle\n // would paint the source copy, then swap it when the host replies.\n if (!state.firstI18nSettled) return true;\n if (!state.i18nNeeded) return false;\n if (state.sourceLocale.toLowerCase() === state.targetLocale.toLowerCase()) return false;\n return !state.resolvedSourceTexts.has(trimmed);\n}\n\nexport function localizeText(\n sourceText: string,\n replacements: TextReplacements | undefined,\n sourceLocale: string,\n targetLocale: string,\n translations: TextTranslations,\n): string {\n const shouldTranslate =\n !!sourceLocale &&\n !!targetLocale &&\n sourceLocale.toLowerCase() !== targetLocale.toLowerCase();\n const template = shouldTranslate\n ? findTranslatedTemplate(sourceText, translations) ?? sourceText\n : sourceText;\n return interpolateText(template, replacements);\n}\n\nexport function addSourceTexts(\n target: Set<string>,\n texts?: Iterable<string | undefined | null>,\n) {\n if (!texts) return;\n for (const text of texts) {\n const source = typeof text === 'string' ? text.trim() : '';\n if (source) target.add(source);\n }\n}\n\nexport function mergeTranslations(\n current: TextTranslations,\n incoming: Record<string, unknown>,\n): TextTranslations {\n const next = { ...current };\n for (const [key, value] of Object.entries(incoming)) {\n if (typeof value === 'string') next[key] = value;\n }\n return next;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE, GameObject } from '@combos-fun/engine';\nimport { Renderer3D, Renderer3DSystem, tagObject3D, Transform3D, VisualPoseBridge } from '@combos-fun/plugin-renderer-3d';\nimport { Text as TroikaText } from 'troika-three-text';\nimport Text3D from './component';\nimport { requestHostI18n } from './hostSdk';\nimport {\n addSourceTexts,\n hasMissingSourceTranslations,\n localizeText,\n mergeTranslations,\n shouldHoldForMissingTranslation,\n shouldRequestI18nForSourceTexts,\n sourceTextsSignature,\n type TextTranslations,\n} from './localization';\n\nexport interface Text3DSystemParams {\n /** BCP 47 locale of the source text, for example `zh-CN`. Omit to disable host-driven i18n. */\n sourceLocale?: string;\n /**\n * All source templates to translate on first `requestI18n`, including copy\n * for screens that are not mounted yet. The system also keeps a growing\n * session catalog of every later template it sees.\n */\n sourceTexts?: string[];\n}\n\n@decorators.componentObserver({\n Text3D: [\n 'text',\n { prop: ['replacements'], deep: true },\n 'fontSize', 'color', 'anchorX', 'anchorY', 'maxWidth', 'font',\n 'positionX', 'positionY', 'positionZ',\n 'rotationX', 'rotationY', 'rotationZ',\n ],\n})\nexport default class Text3DSystem extends Renderer3D<Text3DSystemParams> {\n static systemName = 'Text3DSystem';\n name: string = 'Text3DSystem';\n\n private texts = new Map<number, { mesh: TroikaText; component: Text3D }>();\n private poseBridges = new Map<number, VisualPoseBridge>();\n private sourceLocale = '';\n private targetLocale = '';\n private translations: TextTranslations = {};\n /** Growing catalog of every source template seen this session. */\n private knownSourceTexts = new Set<string>();\n private lastRequestedSourceTexts = '';\n private i18nRequestScheduled = false;\n private i18nRequestId = 0;\n private firstI18nSettled = false;\n private i18nNeeded = false;\n private resolvedSourceTexts = new Set<string>();\n\n init(params?: Text3DSystemParams) {\n const renderer3DSystem = this.game.getSystem(Renderer3DSystem) as Renderer3DSystem;\n renderer3DSystem.rendererManager.register(this);\n this.sourceLocale = params?.sourceLocale?.trim() ?? '';\n this.targetLocale = this.sourceLocale;\n this.declareSourceTexts(params?.sourceTexts);\n }\n\n /** Register extra source templates before or after ready. First request includes these. */\n declareSourceTexts(texts?: string[]) {\n this.rememberSourceTexts(texts);\n this.scheduleI18nRequest();\n }\n\n async beforeReady() {\n if (this.firstI18nSettled) return;\n this.update();\n if (!this.sourceLocale) {\n this.firstI18nSettled = true;\n return;\n }\n await this.requestI18nAndApply();\n if (\n this.i18nNeeded &&\n hasMissingSourceTranslations(this.collectSourceTexts(), this.translations)\n ) {\n await this.requestI18nAndApply();\n }\n this.firstI18nSettled = true;\n // needed:false refresh still ran with firstI18nSettled=false (empty hold).\n this.refreshAllText();\n }\n\n setI18n(locale: string, translations: TextTranslations) {\n const targetLocale = locale?.trim();\n if (!targetLocale || !translations || typeof translations !== 'object') return;\n this.targetLocale = targetLocale;\n this.translations = mergeTranslations(this.translations, translations);\n this.refreshAllText();\n }\n\n componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text3D') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.handleAdd(changed.gameObject, changed.component as Text3D);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.handleRemove(changed.gameObject.id);\n } else {\n this.handleChange(changed);\n }\n }\n\n rendererUpdate(gameObject: GameObject) {\n const component = gameObject.getComponent(Text3D) as Text3D;\n if (!component) return;\n\n const entry = this.texts.get(gameObject.id);\n if (!entry) return;\n this.applyPose(gameObject, component, entry.mesh);\n }\n\n private handleAdd(gameObject: GameObject, component: Text3D) {\n const textMesh = new TroikaText();\n this.syncTextProps(textMesh, component);\n textMesh.sync();\n tagObject3D(textMesh, gameObject.id);\n\n this.threeContext.attachVisual(gameObject.id, textMesh, gameObject);\n this.texts.set(gameObject.id, { mesh: textMesh, component });\n this.poseBridges.set(gameObject.id, new VisualPoseBridge());\n this.rememberSourceTexts([component.text]);\n this.scheduleI18nRequest();\n }\n\n private handleChange(changed: ComponentChanged) {\n const entry = this.texts.get(changed.gameObject.id);\n if (!entry) return;\n const component = changed.component as Text3D;\n entry.component = component;\n if (changed.prop.prop[0] === 'text') this.rememberSourceTexts([component.text]);\n this.syncTextProps(entry.mesh, component);\n entry.mesh.sync();\n if (changed.prop.prop[0] === 'text') this.scheduleI18nRequest();\n }\n\n private handleRemove(id: number) {\n const entry = this.texts.get(id);\n if (!entry) return;\n\n this.threeContext.detachVisual(id, entry.mesh);\n entry.mesh.dispose();\n this.texts.delete(id);\n this.poseBridges.delete(id);\n }\n\n private syncTextProps(textMesh: TroikaText, component: Text3D) {\n textMesh.text = this.resolveText(component);\n textMesh.fontSize = component.fontSize;\n textMesh.color = component.color;\n textMesh.anchorX = component.anchorX;\n textMesh.anchorY = component.anchorY;\n if (component.maxWidth > 0) {\n textMesh.maxWidth = component.maxWidth;\n }\n if (component.font) {\n textMesh.font = component.font;\n }\n }\n\n private applyPose(gameObject: GameObject, component: Text3D, textMesh: TroikaText) {\n let bridge = this.poseBridges.get(gameObject.id);\n if (!bridge) {\n bridge = new VisualPoseBridge();\n this.poseBridges.set(gameObject.id, bridge);\n }\n const transform = gameObject.getComponent(Transform3D) as Transform3D | undefined;\n if (!bridge.sync(component, transform)) {\n textMesh.position.set(0, 0, 0);\n textMesh.rotation.set(0, 0, 0);\n return;\n }\n textMesh.position.set(component.positionX, component.positionY, component.positionZ);\n textMesh.rotation.set(component.rotationX, component.rotationY, component.rotationZ);\n }\n\n onDestroy() {\n this.i18nRequestId += 1;\n this.firstI18nSettled = false;\n this.i18nNeeded = false;\n this.resolvedSourceTexts.clear();\n for (const [id] of this.texts) {\n this.handleRemove(id);\n }\n this.texts.clear();\n }\n\n private resolveText(component: Text3D): string {\n if (\n shouldHoldForMissingTranslation(component.text, this.translations, {\n sourceLocale: this.sourceLocale,\n targetLocale: this.targetLocale,\n i18nNeeded: this.i18nNeeded,\n firstI18nSettled: this.firstI18nSettled,\n resolvedSourceTexts: this.resolvedSourceTexts,\n })\n ) {\n return '';\n }\n return localizeText(\n component.text,\n component.replacements,\n this.sourceLocale,\n this.targetLocale,\n this.translations,\n );\n }\n\n private rememberSourceTexts(texts?: Iterable<string | undefined | null>) {\n addSourceTexts(this.knownSourceTexts, texts);\n }\n\n private collectSourceTexts(): string[] {\n for (const entry of this.texts.values()) {\n this.rememberSourceTexts([entry.component.text]);\n }\n return [...this.knownSourceTexts];\n }\n\n private scheduleI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled || this.i18nRequestScheduled) return;\n this.i18nRequestScheduled = true;\n queueMicrotask(() => {\n this.i18nRequestScheduled = false;\n this.startI18nRequest();\n });\n }\n\n private startI18nRequest() {\n if (!this.sourceLocale || !this.firstI18nSettled) return;\n const sourceTexts = this.collectSourceTexts();\n if (\n !shouldRequestI18nForSourceTexts(sourceTexts, this.translations, {\n i18nNeeded: this.i18nNeeded,\n lastRequestedSourceTexts: this.lastRequestedSourceTexts,\n })\n ) {\n return;\n }\n void this.requestI18nAndApply();\n }\n\n private async requestI18nAndApply() {\n const sourceTexts = this.collectSourceTexts();\n this.lastRequestedSourceTexts = sourceTextsSignature(sourceTexts);\n const requestId = ++this.i18nRequestId;\n const result = await requestHostI18n({\n sourceLocale: this.sourceLocale,\n sourceTexts,\n });\n if (requestId !== this.i18nRequestId) return;\n addSourceTexts(this.resolvedSourceTexts, sourceTexts);\n this.i18nNeeded = result.needed;\n if (!result.needed) {\n this.refreshAllText();\n return;\n }\n this.setI18n(result.locale, result.translations);\n }\n\n private refreshAllText() {\n for (const entry of this.texts.values()) {\n entry.mesh.text = this.resolveText(entry.component);\n entry.mesh.sync();\n }\n }\n}\n"],"names":["TroikaText"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combos-fun/plugin-renderer-3d-text",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "3D text rendering, backed by troika-three-text",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/plugin-renderer-3d-text.esm.js",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"three": "^0.172.0",
|
|
30
30
|
"troika-three-text": "^0.52.3",
|
|
31
|
-
"@combos-fun/engine": "0.1.
|
|
32
|
-
"@combos-fun/inspector-decorator": "0.1.
|
|
33
|
-
"@combos-fun/plugin-renderer-3d": "0.1.
|
|
31
|
+
"@combos-fun/engine": "0.1.9",
|
|
32
|
+
"@combos-fun/inspector-decorator": "0.1.9",
|
|
33
|
+
"@combos-fun/plugin-renderer-3d": "0.1.9"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"tsx": "^4.20.3"
|