WPC667PRTGRE7BNP6E7ZCQIKXYMIHJT3LUTTQT7VX2HQVRBXNIKAC
5Q5FEGCXP4TBQ6SKK4YXDP7GXEU37IGGF76W7WCY3LSHIM2OE32QC
GWQKBUIJCNQP6LUV42FXP3IU7TVF5FSFSWK3BAVFT3DSEIRZLFJAC
TQAGEMW7FKIQCPQOJN44XVUZJQFQYNGSYRVIYSXFYF36HU7YDMZQC
DJCKOKLLR6ROMDLANSOZVWTCRPQMMWAZYCABIT3CCTVWHCYQYSVAC
ED3IWKTSVYYD52TWW5TOC4H63YZ7FTO3E53YO5NELPG5I3RLRAYAC
ZWX5PV44JLFYTQXGXNQG64CKTJJC6I2TVMNRII3EAEMUXMV5XNYQC
HXHNGFB2VCXB6YXDND35HJI22GBJC3QTSUR2TK3M3LXGJHVNXVHAC
FLGWAOMMMGBO5ICWD3SXBOGJQA6LL2ZHTIQIMGY5VNFAETKDPPYAC
EVVMJX2VLMIKUNBTUTSYVVNLOMJ2ZJEZTBVZVAPJTY33T4JDI4EAC
L5PRY4LCFODVMMTEJ5IKB7PX3BV2BDXDKCI4RW3QGOMTNOAWOKKAC
DPJCZOPIKAKQIS4YRXETBSJA5ZTL2KQESSJE2TEZFLRQARXUVFXQC
B4JS4Z3VVAD5RJJ272S7GJM5BUNIHHMGNK2VSKVGZFPOVFP2YO4QC
5BA7VZ3D36S2TC7NZ64R3O364TGXPY5BJUJTGCFZHWZ6JWAXJMUQC
VGU4VI6EMYILKHN3TFRCEGU7LL6NM6PW6RHRC726YUKO6RBORBQQC
WTINQMZSNRT5MSAXLMMZVM6OU6TMD4AP4OEUYAXZUFNY5IWFLZSQC
A75BWKGRLUDH3KF4M2HJYLNC6BSV5MAJFV2RJSF757F46HLRLCKQC
4TYJCGT4MTCAH7GSJJWFQPPHZNAUQZDEIZYT365EYTMXS7D2MTNAC
OET27TXMNRKBX3HWDSLQWCWAJOWNY5NU4XDKLO5N7Z3EE23CSWOAC
AAKN4XJLZ2GARZMUFYX3CJZKYHTRRZDYNTFRLMY7VPAY7K6W4N3QC
EMED7UWAGESRTWJJWVXRL27O4XMBGZDDAU4LNVF3MQAYKFKRDNXQC
6REHBZAOJN4CVZY4HFXVNEUMWGQUXFTXMLQPXEH7RTH5FBL2TXIAC
Y7VEWZEPUKX2WWPTQCUSIF7YMRUC6JZQNUU5OX3HQDB4GSDSTQZAC
DHO4JCJIELKX4R42XXAMAHVQTTE6OWULLP2QF4BXO3UWC5UTMSMAC
ZGS4FTTFBXTF2SHYTPAJJBWEUVWVYXPSJVEFI5NYJWTW273B4NHAC
TQ57VE45BHV7MOZ6GKTYZEAMAOTXLPQ3ROCWJ2FUCITQWOYVMUIAC
THNMNMVRZQVPZTEXHIK6WGYN3QDEFPKFOVOCB5HTWCYC5BOBYQ5AC
WO2ALETBVNH7N3NXJ6JKWCQ2YIZN6LBO7WEXPHAT3EQQJEUCJITQC
3EAR4KTTJ26IRF5QUGEDRMJVBR4X3VWSQ6OBIJCLDH3A4ZZ4O3ZAC
let batchedSetGameState = batchUpdates(setGameState)
batchedSetGameState((old: GameState): GameState => old );
batchedSetGameState.fireBatch();
let updaters = useMemo(() => updaterGenerator(initialGameState.get(), setGameState), [setGameState]);
let [batchedSetGameState, fireBatch] = useMemo(() => batchify(setGameState), [setGameState]);
// batchedSetGameState((old: GameState): GameState => old );
// batchedSetGameState.fireBatch();
let updaters = useMemo(() => updaterGenerator(initialGameState.get(), batchedSetGameState), [batchedSetGameState]);
const [gameState, gameStateUpdaters] = useContext(UseGameStateContext);
const [gameState, gameStateUpdaters, fireBatchedSetGameState] = useContext(UseGameStateContext);
const fireBatch = () => {
fireBatchedSetGameState();
props.fireBatchedSetPixiComponentState();
}
export const UseGameStateContext = React.createContext<[DeepReadonly<GameState>, UpdaterGeneratorType<GameState>]>([] as any);
export const UseGameStateContext = React.createContext<[DeepReadonly<GameState>, UpdaterGeneratorType<GameState>, () => void]>([] as any);
export type BaseApplicationProps = DeepReadonly<MutableProps>
type MutableProps = {
gameState: GameState,
pixiComponentState: WindowState, // shim
export type BaseApplicationProps = {
args?: Partial<Config>,
gameStateUpdaters: UpdaterGeneratorType<GameState>, // aka updaters
pixiComponentState: DeepReadonly<WindowState>,
// // needed to avoid double-updates
// prevGameState: DeepReadonly<GameState>,
gameState: DeepReadonly<GameState>,
fireBatch: () => void,
this.state.appSize = BaseApplication.appSizeFromWindowSize(new Vector2(props.pixiComponentState.innerWidth, props.pixiComponentState.innerHeight));
this.originalAppWidth = this.state.appSize.x;
this.originalAppHeight = this.state.appSize.y;
this.state.appSize = BaseApplication.appSizeFromWindowSize(
props.pixiComponentState && new Vector2(props.pixiComponentState.innerWidth, props.pixiComponentState.innerHeight)
);
this.state.originalAppSize = this.state.appSize;
this.rootApplication = new RootApplication({
args: {
renderer: this.app.renderer,
},
updaters: this.props.gameStateUpdaters,
delta: 0,
gameState: this.props.gameState,
appSize: this.state.appSize,
})
this.app.stage.addChild(this.rootApplication.container);
this.renderSelf(this.props);
// createBunnyExample({ parent: this.actionStage, ticker: this.app.ticker, x: this.app.screen.width / 2, y: this.app.screen.height / 2 });
// createBunnyExample({ parent: this.app.stage, ticker: this.app.ticker, x: this.app.screen.width / 2, y: this.app.screen.height / 2 });
this.didMount();
}
public didMount() {
rerender(props: {
gameStateUpdaters: UpdaterGeneratorType<GameState>,
pixiComponentState: DeepReadonly<WindowState>,
// needed to avoid double-updates
prevGameState: DeepReadonly<GameState>,
gameState: DeepReadonly<GameState>,
}) {
this.globalEventQueue.push(() => {
this.props.pixiComponentState = props.pixiComponentState;
this.updaters.gameState = props.gameStateUpdaters; // optional
})
rerender(props: BaseApplicationProps) {
this.props = props;
// now: read the value of this.gameState
let startGameState = this.gameState
// generates a new object by shallow copying
let setStartGameState = (arg: GameState | ((old: GameState) => GameState)) => {
if (typeof arg === 'function') {
startGameState = { ...arg(startGameState) };
} else {
startGameState = { ...arg }
}
}
// apply changes to gameState - this should be synchronous, or at least locked
let updater = updaterGenerator<GameState>(startGameState, setStartGameState);
for (let eventAction of this.globalEventQueue) {
eventAction(updater); // includes actions sent down from react
}
// pass the new game state back up
this.gameState = startGameState;
// note that react will view this as a state change and trigger this.rerender immediately, so we need to block that
this.updaters.gameState.update((old: GameState): GameState => {
this.blockedReactUpdate = { old, new: this.gameState };
return this.gameState;
// assume props is up to date
this.updateSelf(this.props);
// send props downwards
this.rootApplication.update({
args: {
renderer: this.app.renderer,
},
updaters: this.props.gameStateUpdaters,
delta,
gameState: this.props.gameState,
appSize: this.state.appSize,
// this.app = new Pixi.Application({
// width: this.originalAppWidth, // both are ignored - see resize() below
// height: this.originalAppHeight,
// antialias: true, // both about the same FPS, i get around 30 fps on 1600 x 900
// transparent: true, // true -> better fps?? https://github.com/pixijs/pixi.js/issues/5580
// resolution: window.devicePixelRatio || 1, // lower -> more FPS but uglier
// // resolution: 0.5,
// // resolution: 2,
// autoDensity: true,
// powerPreference: "low-power", // the only valid one for webgl
// backgroundColor: 0xffffff, // immaterial - we recommend setting color in backdrop graphics
// });
// this.stage = this.app.stage;
// this.stage.sortableChildren = true;
this.container.sortableChildren = true;
// // this.fixedCameraStage = new Pixi.Sprite();
// // this.fixedCameraStage.zIndex = 1;
// // this.fixedCameraStage.sortableChildren = true;
// // this.stage.addChild(this.fixedCameraStage);
this.fixedCameraStage = new Pixi.Sprite();
this.fixedCameraStage.zIndex = 1;
this.fixedCameraStage.sortableChildren = true;
this.container.addChild(this.fixedCameraStage);
// // this.actionStage = new Pixi.Sprite();
// // this.actionStage.zIndex = 0;
// // this.actionStage.sortableChildren = true;
// // this.stage.addChild(this.actionStage);
this.actionStage = new Pixi.Sprite();
this.actionStage.zIndex = 0;
this.actionStage.sortableChildren = true;
this.container.addChild(this.actionStage);
// // this.backdropStage = new Pixi.Sprite();
// // this.backdropStage.zIndex = -1;
// // this.backdropStage.sortableChildren = true;
// // this.stage.addChild(this.backdropStage);
this.backdropStage = new Pixi.Sprite();
this.backdropStage.zIndex = -1;
this.backdropStage.sortableChildren = true;
this.container.addChild(this.backdropStage);
// // test
// // createBunnyExample({ parent: this.actionStage, ticker: this.app.ticker, x: this.app.screen.width / 2, y: this.app.screen.height / 2 });
// this.app.ticker.add((delta) => this.baseGameLoop(delta));
this.renderSelf(props);
this.didMount(props);
// render(props: {
// gameState: DeepReadonly<GameState>,
// pixiComponentState: PixiComponentState,
// }) { }
public update(props: RootApplicationProps) {
this.updateSelf(props)
// this.keyboard.update(props);
this.renderSelf(props);
this.didUpdate(props);
}