Skip to content

Commit

Permalink
Merge pull request #147 from DRincs-Productions/146-edit-all-label-ma…
Browse files Browse the repository at this point in the history
…nagement

146 edit all label management
  • Loading branch information
BlackRam-oss authored May 21, 2024
2 parents c4a7591 + c079bee commit 9e50ebc
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 137 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"homepage": "https://pixi-vn.web.app/",
"devDependencies": {
"@drincs/pixi-vn": "^0.4.8",
"@drincs/pixi-vn": "^0.5.3",
"@types/crypto-js": "^4.2.2",
"@types/css-font-loading-module": "^0.0.13",
"@types/deep-diff": "^1.0.5",
Expand Down
36 changes: 29 additions & 7 deletions src/classes/ChoiceMenuOption.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getLabelById } from "../decorators"
import { Close, CloseType, LabelRunModeType, StorageObjectType } from "../types"
import { LabelIdType } from "../types/LabelIdType"
import CloseLabel from "./CloseLabel"
Expand All @@ -7,7 +8,7 @@ import Label from "./Label"
* ChoiceMenuOption is a class that contains a Label and a text that will be displayed in the menu.
* @example
* ```typescript
* new ChoiceMenuOption("Events Test", EventsTestLabel)
* new ChoiceMenuOption("Hello", HelloLabel)
* ```
*/
export default class ChoiceMenuOption<T extends StorageObjectType> {
Expand All @@ -29,13 +30,22 @@ export default class ChoiceMenuOption<T extends StorageObjectType> {
props: StorageObjectType = {}
/**
* @param text Text to be displayed in the menu
* @param label Label to be opened when the option is selected
* @param type Type of the label to be opened
* @param props Properties to be passed to the label, when the label is called. it cannot contain functions or classes.
* @param label Label to be opened when the option is selected or the id of the label
* @param type Type of the label to be opened. @default "call"
* @param props Properties to be passed to the label, when the label is called. it cannot contain functions or classes. @default {}
*/
constructor(text: string, label: typeof Label<T>, type: LabelRunModeType = "call", props?: T) {
constructor(text: string, label: Label<T> | LabelIdType, type: LabelRunModeType = "call", props?: T) {
if (typeof label === 'string') {
let tLabel = getLabelById(label)
if (!tLabel) {
throw new Error(`[Pixi'VN] Label ${label} not found`)
}
else {
label = tLabel
}
}
this.text = text
this.label = new label()
this.label = label
this.type = type
if (props) {
this.props = props
Expand Down Expand Up @@ -86,8 +96,20 @@ export type IStoratedChoiceMenuOption = {
type: CloseType
}

/**
* HistoryChoiceMenuOption is a type that contains the history information of a choice menu option.
*/
export type HistoryChoiceMenuOption = {
/**
* Text to be displayed in the menu
*/
text: string
/**
* Method used to open the label, or close the menu.
*/
type: CloseType | LabelRunModeType
isMadeChoice: boolean
/**
* This choice is a response
*/
isResponse: boolean
}
11 changes: 10 additions & 1 deletion src/classes/CloseLabel.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import Label from "./Label"

export default class CloseLabel extends Label { }
export const CLOSE_LABEL_ID = "__close-label-id__"

/**
* CloseLabel is a label used for closing the menu.
*/
export default class CloseLabel extends Label {
constructor(choiseIndex?: number) {
super(CLOSE_LABEL_ID, [], undefined, choiseIndex)
}
}
86 changes: 65 additions & 21 deletions src/classes/Label.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,64 @@
import { checkIfStepsIsEqual } from "../functions/StepLabelUtility"
import { StorageObjectType } from "../types"
import { LabelIdType } from "../types/LabelIdType"
import { StepHistoryDataType } from "../types/StepHistoryDataType"
import { StepLabelType } from "../types/StepLabelType"

/**
* Label is a class that contains a list of steps, which will be performed as the game continues.
* You must use the labelDecorator to register the label in the game.
* For Ren'py this is the equivalent of a label.
* @example
* ```typescript
* \@labelDecorator() // this is equivalent to labelDecorator("StartLabel")
* export class StartLabel extends Label {
* override get steps(): StepLabelType[] {
* return [
* () => {
* GameWindowManager.clear()
* setDialogue({ character: liam, text: "Which test do you want to perform?" })
* setChoiceMenuOptions([
* new ChoiceMenuOption("Events Test", EventsTestLabel),
* new ChoiceMenuOption("Show Image Test", ShowImageTest),
* ])
* },
* () => GameStepManager.jumpLabel(StartLabel),
* ]
* }
* }
* const START_LABEL_ID = "StartLabel"
*
* export const startLabel = newLabel(START_LABEL_ID,
* [
* (props) => {
* GameWindowManager.clear()
* setDialogue({ character: liam, text: "Which test do you want to perform?" })
* setChoiceMenuOptions([
* new ChoiceMenuOption("Events Test", eventsTestLabel),
* new ChoiceMenuOption("Show Image Test", showImageTest),
* ])
* },
* (props) => GameStepManager.jumpLabel(START_LABEL_ID, props),
* ]
* )
*
* GameStepManager.callLabel(StartLabel)
* ```
*/
export default class Label<T extends StorageObjectType = {}> {
export default class Label<T extends {} = {}> {
/**
* @param id is the id of the label
* @param steps is the list of steps that the label will perform
* @param onStepRun is a function that will be executed before any step is executed, is useful for example to make sure all images used have been cached
* @param choiseIndex is the index of the choice that the label will perform
*/
constructor(id: LabelIdType, steps: StepLabelType<T>[], onStepRun?: () => void | Promise<void>, choiseIndex?: number) {
this._id = id
this._steps = steps
this._onStepRun = onStepRun
this._choiseIndex = choiseIndex
}

private _id: LabelIdType
/**
* Get the id of the label
*/
public get id(): LabelIdType {
return this._id
}

private _steps: StepLabelType<T>[]
/**
* Get the steps of the label.
* This class should be extended and the steps method should be overridden.
* Every time you update this list will also be updated when the other game versions load.
*/
public get steps(): StepLabelType<T>[] { throw new Error("[Pixi'VN] The method Label.steps must be overridden") }
public get steps(): StepLabelType<T>[] {
return this._steps
}

/**
* Get the corresponding steps number
* @param externalSteps
Expand All @@ -52,5 +76,25 @@ export default class Label<T extends StorageObjectType = {}> {
})
return res
}
choiseIndex?: number

private _onStepRun: (() => void | Promise<void>) | undefined
/**
* Get the function that will be executed before any step is executed, is useful for example to make sure all images used have been cached
* @returns Promise<void> or void
* @example
* ```typescript
* newLabel("id", [], () => {
* Assets.load('path/to/image1.png')
* Assets.load('path/to/image2.png')
* })
* ```
*/
public get onStepRun(): (() => void | Promise<void>) | undefined {
return this._onStepRun
}

private _choiseIndex: number | undefined
public get choiseIndex(): number | undefined {
return this._choiseIndex
}
}
2 changes: 1 addition & 1 deletion src/classes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { default as CanvasEvent } from './CanvasEvent';
export { default as CharacterBaseModel, CharacterBaseModelProps } from './CharacterBaseModel';
export { default as ChoiceMenuOption } from './ChoiceMenuOption';
export { default as ChoiceMenuOption, HistoryChoiceMenuOption } from './ChoiceMenuOption';
export { default as DialogueBaseModel } from './DialogueBaseModel';
export { default as Label } from './Label';
export { default as StoredClassModel } from './StoredClassModel';
Expand Down
75 changes: 21 additions & 54 deletions src/decorators/LabelDecorator.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,35 @@
import { Label } from "../classes"
import { StepLabelType } from "../types"
import { LabelIdType } from "../types/LabelIdType"

export const registeredLabels: { [key: LabelIdType]: typeof Label } = {}
/**
* Is a decorator that register a label in the game.
* Is a required decorator for use the label in the game.
* Thanks to this decoration the game has the possibility of updating the labels to the latest modification and saving the game.
* @param name is th identifier of the label, by default is the name of the class
* @returns
*/
export default function labelDecorator(name?: LabelIdType) {
return function (target: typeof Label) {
if (!name) {
name = target.name
}
if (registeredLabels[name]) {
console.warn(`[Pixi'VN] Label ${name} already exists, it will be overwritten`)
}
registeredLabels[name] = target
}
}
export const registeredLabels: { [key: LabelIdType]: Label<any> } = {}

/**
* is a function that returns the type of the label
* @param labelName is the name of the label
* @returns the label type
* Creates a new label and registers it in the system
* @param id The id of the label, it must be unique
* @param steps The steps of the label
* @param onStepRun is a function that will be executed before any step is executed, is useful for example to make sure all images used have been cached
* @returns The created label
*/
export function getLabelTypeByClassName<T extends typeof Label>(labelName: LabelIdType): T | undefined {
try {
let labelType = registeredLabels[labelName]
if (!labelType) {
console.error(`[Pixi'VN] Label ${labelName} not found`)
return
}
new labelType()
return labelType as T
}
catch (e) {
console.error(`[Pixi'VN] Error while getting Label ${labelName}`, e)
return
export function newLabel<T extends {} = {}>(id: LabelIdType, steps: StepLabelType<T>[], onStepRun?: () => void | Promise<void>): Label<T> {
if (registeredLabels[id]) {
console.warn(`[Pixi'VN] Label ${id} already exists, it will be overwritten`)
}
let label = new Label<T>(id, steps, onStepRun)
registeredLabels[id] = label
return label
}

/**
* is a function that returns the instance of the label
* @param labelName is the name of the label
* @returns the label
* Gets a label by its id
* @param id The id of the label
* @returns The label or undefined if it does not exist
*/
export function getLabelInstanceByClassName<T extends Label>(labelName: LabelIdType): T | undefined {
try {
let labelType = registeredLabels[labelName]
if (!labelType) {
console.error(`[Pixi'VN] Label ${labelName} not found`)
return
}
let label = new labelType()
let step = label.steps
if (step.length = 0) {
console.warn(`[Pixi'VN] Label ${labelName} has no steps`)
}
return label as T
}
catch (e) {
console.error(`[Pixi'VN] Error while getting Label ${labelName}`, e)
export function getLabelById<T = Label<any>>(id: LabelIdType): T | undefined {
let label = registeredLabels[id]
if (!label) {
console.error(`[Pixi'VN] Label ${id} not found`)
return
}
return label as T
}
2 changes: 1 addition & 1 deletion src/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { default as canvasElementDecorator } from './CanvasElementDecorator';
export { getAllCharacters, getCharacterById, saveCharacter } from './CharacterDecorator';
export { default as eventDecorator } from './EventDecorator';
export { default as labelDecorator } from './LabelDecorator';
export { getLabelById, newLabel } from './LabelDecorator';
export { default as tickerDecorator } from './TickerDecorator';

Loading

0 comments on commit 9e50ebc

Please sign in to comment.