From aace63b1a2f896e6f7b47fe7c5051a12db13e5b6 Mon Sep 17 00:00:00 2001 From: Gator Date: Thu, 1 Dec 2022 12:03:34 +0100 Subject: [PATCH] wip moved canvas routine in store. it's awful --- src/App.vue | 6 +- src/assets/main.css | 0 src/components/Board.vue | 128 ----------- src/components/CanvasBoard.vue | 56 +++++ src/components/MenuElementaryCA.vue | 338 +++++++++++++++------------- src/main.js | 4 + src/store/index.js | 144 +++++++++++- 7 files changed, 376 insertions(+), 300 deletions(-) create mode 100644 src/assets/main.css delete mode 100644 src/components/Board.vue create mode 100644 src/components/CanvasBoard.vue diff --git a/src/App.vue b/src/App.vue index 5489aeb..10b1827 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,20 +3,20 @@

Cellular Automata Explorer

- +
diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Board.vue b/src/components/Board.vue deleted file mode 100644 index ba75795..0000000 --- a/src/components/Board.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - diff --git a/src/components/CanvasBoard.vue b/src/components/CanvasBoard.vue new file mode 100644 index 0000000..d307a31 --- /dev/null +++ b/src/components/CanvasBoard.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/components/MenuElementaryCA.vue b/src/components/MenuElementaryCA.vue index 914708d..4e3ce31 100644 --- a/src/components/MenuElementaryCA.vue +++ b/src/components/MenuElementaryCA.vue @@ -2,17 +2,16 @@
-
@@ -72,150 +73,171 @@ diff --git a/src/main.js b/src/main.js index 654699f..94d53fb 100644 --- a/src/main.js +++ b/src/main.js @@ -2,8 +2,12 @@ import { createApp } from 'vue' import App from "./App.vue"; import { store } from "./store"; +const gobalsProperties = {'canvas': null}; + const app = createApp(App) +app.provide('gobalsProperties', gobalsProperties) + app.use(store) app.mount('#app') diff --git a/src/store/index.js b/src/store/index.js index 82c3907..af39d2d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,25 +1,53 @@ +/* TODO: terminology is to be changed for : +canvas/board : +currently, the canvas object is named board, +while the structure used to store automata current state is named "board" as well. This is confusing +drawing board could be enough to lift any ambiguity + +rules: +confusion bewteen ruleset and rules. +it's never clear if we refers to a rule or the whole (named) set +*/ import { createStore } from 'vuex' +import { + create1dState, + create1dStateOneCell, + create2dState, + createBoard, + conwayRules, + evolve2d, +} from "../modules/automata.js"; +import { getRandomInt, sleep } from "../modules/common.js"; export const store = createStore({ + strict: process.env.NODE_ENV !== 'production', state: { drawing: 0, rules1d: { - 111: 0, - 110: 1, - 101: 0, - 100: 0, - "011": 1, - "010": 0, - "001": 0, - "000": 1, + name: "rule 73", + rules: + { + 111: 0, + 110: 1, + 101: 0, + 100: 0, + "011": 1, + "010": 0, + "001": 0, + "000": 1, + } }, cellProperties: { size: 3, liveColor: "#000000", deadColor: "#F5F5F5", }, + canvas: null, + ctx: null, canvasWidth: 0, canvasHeight: 0, + boardWidth: 0, + boardHeight: 0, refreshRate: 300, initial1dState: "onecell", activeMenu: "", @@ -28,7 +56,8 @@ export const store = createStore({ }, mutations: { update1dSingleRule(state, data) { - state.rules1d[data.rule] = data.value; + state.rules1d.name = data.name + state.rules1d.rules[data.rule] = data.value; }, update1dRules(state, data) { state.rules1d = data; @@ -60,6 +89,20 @@ export const store = createStore({ setLastBoard(state, data) { state.lastBoard = data; }, + setCanvas(state, data) { + state.canvas = data + }, + setContext(state, data) { + state.ctx = data + }, + setBoardWidth(state) { + const width = Math.floor(state.canvasWidth / state.cellProperties.size); + state.boardWidth = width + }, + setBoardHeight(state) { + const height = Math.floor(state.canvasHeight / state.cellProperties.size); + state.boardHeight = height + }, }, getters: { getCellProperties(state) { @@ -69,7 +112,8 @@ export const store = createStore({ return state.rules1d; }, getRule1d(state) { - return (rule) => state.rules1d[rule]; + // getter with side-effect. no work + return state.rules1d; }, isDrawing(state) { return state.drawing; @@ -96,6 +140,84 @@ export const store = createStore({ return state.lastBoard; }, }, - actions: {}, + actions: { + async drawCanvas({state}, board) { + /** Draw the board on the canvas according to the + cells' properties and drawing direction */ + const props = state.cellProperties + board.map((row, y) => { + const d = props.size; + return row.map((cell, x) => { + state.ctx.fillStyle = (() => { + if (cell === 1) return props.liveColor; + return props.deadColor; + })(); + if (state.drawingDirection === "x") + state.ctx.fillRect(y * d, x * d, d, d); + else state.ctx.fillRect(x * d, y * d, d, d); + return cell; + }); + }); + }, + async compute1dInitialState({state}) { + /** + create the initial state for an elementary automaton based : + - on the selected board dimensions + - if we want to start from a single cell or several random ones + */ + if (state.initial1dState === "onecell") + return create1dStateOneCell(state.canvasWidth); + return create1dState(state.canvasWidth, getRandomInt, [0, 2]); + }, + async draw1d({state, commit, dispatch}) { + /** draw an elementary cellular automaton from an initial state and + a set of rules */ + const initialState = await dispatch("compute1dInitialState") + const board = createBoard(initialState, state.rules1d.rules, state.boardWidth); + commit("setLastBoard", board); + await dispatch("drawCanvas", board); + }, + async draw2d({state, dispatch}, board) { + /** draw a 2D cellular automaton from an initial state and + a set of rules */ + if (this.drawing === 0) return; + + const draw2dNext = async (b) => { + if (state.drawing === 0) return; + const newBoard = evolve2d(b, conwayRules); + dispatch("drawCanvas", b, this.cellProperties); + await sleep(this.refreshRate); + draw2dNext(newBoard); + }; + return draw2dNext(board); + }, + async draw2dNew({state, commit, dispatch}) { + /** draw a 2d cellular automaton from a random initial state + and a set of rules */ + const initialState = create2dState( + state.boardWidth, + state.boardHeight, + getRandomInt, + [0, 2] + ); + const board = evolve2d(initialState, conwayRules); + commit("setLastBoard", board); + await dispatch("draw2d", board); + }, + async draw2dLast({state, dispatch}) { + /** draw a 2d cellular automaton from the latest known state + of the board and a set of rules */ + await dispatch("draw2d", state.lastBoard); + }, + stop({ commit }) { + /** stop currently running drawing routine */ + commit("setDrawingStatus", 0); + }, + reset({state, dispatch}) { + /** stop currently running drawing routine and clear the board */ + dispatch("stop"); + state.ctx.clearRect(0, 0, state.canvasWidth, state.canvasHeight); + } + }, modules: {}, });