Skip to content

Commit

Permalink
fut: add wire precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
fulcanelly committed Jan 11, 2024
2 parents 4ab4cb3 + 5c0e98d commit 958451d
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 137 deletions.
13 changes: 11 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import './App.css';
import { useEffect, useReducer } from 'react';
import { defaultReducer, initState, sendCellsUpdate } from './reducer';
import { defaultReducer, handleMouseWheel, initState, sendCellsUpdate } from './reducer';
import { Field, Grid, MovableField, Toolbar } from './gui';
import { CircuitComposer } from './circuit';
import ReactJson from 'react-json-view'
Expand All @@ -13,10 +13,19 @@ import ReactJson from 'react-json-view'

function App() {



const [state, dispatch] = useReducer(defaultReducer, initState())


useEffect(() => {
const interval = setInterval(() => sendCellsUpdate(dispatch), 200)
document.addEventListener('keydown', function(event) {
if (event.key === 'r') {
dispatch({type:'scale_change', deltaY: 1})
}
});

const interval = setInterval(() => sendCellsUpdate(dispatch), 2100)

return () => clearInterval(interval)
}, [])
Expand Down
43 changes: 36 additions & 7 deletions src/engine.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as R from 'ramda'
//import { buildModelOfState } from './nothing';
import { debugEntry, drawShuntWire } from './circuit'
import { Cell, findByPosition, getConnectedTo, getOppositeIndex, NotCell, PinCell, PinIndex, PinInfo, Position, State, updateCellsNToActuall, WireCell } from './model';
import { Cell, findByPosition, findWires, getConnectedTo, getOppositeIndex, NotCell, PinCell, PinIndex, PinInfo, Position, State, updateWiresAndGatesInState, WireCell } from './model';
import { buildLens, buildPath, isMatch } from './utils'


Expand Down Expand Up @@ -108,7 +108,7 @@ const valueLens = buildLens<PinInfo>().value!._()
export type Datasheet = {
pattern: any,
pinInfo: PinInfo[],
toPins: (cell: any) => PinCell,
toPins: (cell: Cell) => PinCell,
update?: (cells: PinCell[], self: PinCell) => PinCell
}

Expand All @@ -131,7 +131,7 @@ export type Datasheet = {

// buildLens<PinCell>().actual.state.

export const actualStatePoweredLens = buildLens<PinCell>().actual.state.powered?._()!
export const actualStatePoweredLens = buildLens<PinCell>().actual.state.powered!._()!


export const notDatasheet = {
Expand All @@ -146,7 +146,10 @@ export const notDatasheet = {
pinTypes.input(1),
],

toPins(cell: NotCell) {
toPins(cell: Cell) {
if (cell.cellType !== 'not') {
throw new Error('wrong cell type')
}
const pins = this.pinInfo.map(it => {
if (it.type === 'output') {
return R.set(valueLens, Boolean(cell.state.powered), it)
Expand Down Expand Up @@ -196,6 +199,10 @@ export const datasheets: Datasheet[] = [


toPins(cell) {
if (cell.cellType !== 'wire') {
throw new Error('wrong cell type')
}

const pins = this.pinInfo.map(it => ({
...it,
value: it.type == 'bidirect' ? Boolean(cell.state.powered) : false
Expand Down Expand Up @@ -229,7 +236,10 @@ export const datasheets: Datasheet[] = [
pinTypes.bidirect(1),
],

toPins(cell: WireCell) {
toPins(cell: Cell) {
if (cell.cellType !== 'wire') {
throw new Error('wrong cell type')
}
const pins = this.pinInfo.map(it => {
if (it.type == 'bidirect') {
return R.set(valueLens, Boolean(cell.state.powered), it)
Expand Down Expand Up @@ -266,6 +276,9 @@ export const datasheets: Datasheet[] = [
],

toPins(cell) {
if (cell.cellType !== 'wire') {
throw new Error('wrong cell type')
}
const pins = this.pinInfo.map(it => {
if (it.type == 'bidirect') {
return R.set(valueLens, Boolean(cell.state.powered), it)
Expand Down Expand Up @@ -302,6 +315,9 @@ export const datasheets: Datasheet[] = [
],

toPins(cell) {
if (cell.cellType !== 'wire') {
throw new Error('wrong cell type')
}
const pins = this.pinInfo.map(it => {
if (it.type == 'bidirect') {
return R.set(valueLens, Boolean(cell.state.powered), it)
Expand Down Expand Up @@ -338,6 +354,9 @@ export const datasheets: Datasheet[] = [
],

toPins(cell) {
if (cell.cellType !== 'wire') {
throw new Error('wrong cell type')
}
const pins = this.pinInfo.map(it => {
if (it.type == 'bidirect') {
return R.set(valueLens, Boolean(cell.state.powered), it)
Expand Down Expand Up @@ -436,7 +455,17 @@ export function visualToPins(cell: Cell): PinCell {


export function updateState(state: State): State {
const pinsCells = state.cells.map(visualToPins)
return R.set(cellsLens, updateCellsNToActuall(pinsCells), state)
const complied = state.compiled

if (!complied.gates) {
const pinsCells = state.cells.map(visualToPins)
let [wires, rest] = findWires(pinsCells)
complied.gates = rest
complied.wires = wires
}

return updateWiresAndGatesInState(state)

// return R.set(cellsLens, updateCellsNToActuall(complied.wires!, complied.gates!), state)
}

98 changes: 5 additions & 93 deletions src/model.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { actualStatePoweredLens, datasheets, floorMod, getNeighbours, notDatasheet, rotateReverseTimes, rotateTimes, visualToPins } from "./engine"
import { Cell, findByPosition, findWires, getOppositeIndex, NotCell, PinCell, PowerCell, updateCellsNToActuall, WireCell } from "./model"

import { datasheets, floorMod, notDatasheet, rotateTimes, visualToPins } from "./engine"
import { Cell, findWires, NotCell, PinCell, PowerCell } from "./model"
import * as R from 'ramda'
import { buildPath, isMatch } from './utils'
import { buildPath } from './utils'
import { genericWire } from "./reducer"
import { notGateEntry, powerSourceEntry } from "./circuit"

Expand All @@ -19,7 +20,7 @@ function builtLens(handler: (proxy: ProxyType) => ProxyType) {
return R.lensPath(buildPath(handler))
}

const helpers = {
export const helpers = {

cells2PinCells(cells: Cell[]): PinCell[] {
return cells.map(visualToPins)
Expand Down Expand Up @@ -178,98 +179,9 @@ describe("model", () => {

let [wires, _] = findWires(helpers.cells2PinCells([first, second]))

console.log(wires[0].inputs)
expect(wires[0].inputs[0].pinIndex).toBe(0)
})


it("power source should power a wire", () => {
let first: Cell = R.mergeDeepLeft({
position: { x: 0, y: 0 },
state: { rotation: 1 }
}, genericWire)

let second: Cell = R.mergeDeepLeft({
position: { x: 1, y: 0 },
cellType: 'power'
}, genericWire)


let cells = updateCellsNToActuall(
helpers.cells2PinCells([first, second]))

let updatedWire = cells.find(cell => cell.cellType == 'wire') as WireCell

expect(updatedWire.state.powered).toBe(true)
})

/**
* =>
* x O > x x x => x O > X X X
* =>
*/
it("NOT should power wire", () => {
let first: Cell = {
cellType: 'not',
position: { x: 1, y: 0 },
state: {
rotation: 1, //TODO WHY?
powered: true
}
}

let second: Cell = {
cellType: 'wire',
position: { x: 0, y: 0 },
state: {
rotation: 1,
wireType: 0,
powered: false
}
}

let cells = updateCellsNToActuall(
helpers.cells2PinCells([first, second]))

let updatedWire = cells.find(cell => cell.cellType == 'wire') as WireCell

expect(updatedWire.state.powered).toBe(true)
})

/**
* =>
* x O > x O > => x O > X o >
* =>
*/
it("NOT should power another NOT", () => {
let first: any = {
id: 1,
cellType: 'not',
position: { x: 0, y: 0 },
state: {
rotation: 1,
powered: true
}
}
let second: any = {
id: 2,
cellType: 'not',
position: { x: 1, y: 0 },
state: {
rotation: 1, //not
powered: true
}
}

let cells = updateCellsNToActuall(
helpers.cells2PinCells([first, second]))

let updatedNot = cells.find(cell => (cell as any).id == 1) as NotCell

expect(updatedNot.state.powered).toBe(false)

})

/**
*
* O O O x => O O O X <- test this pin
Expand Down
58 changes: 34 additions & 24 deletions src/model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

import { initState } from "./reducer"
import * as R from 'ramda'
import { actualStatePoweredLens, Datasheet, floorMod, getNearWithTouchingIndex } from "./engine"
import { actualStatePoweredLens, Datasheet, floorMod, getNearWithTouchingIndex, visualToPins } from "./engine"
import { buildLens } from "./utils"

export type Mode = {
editing: boolean
Expand All @@ -16,6 +17,10 @@ export type Field = {
export type State = {
mode: Mode
cells: Cell[],
compiled: {
wires?: Wire[],
gates?: PinCell[]
}
field: Field,
selected: {
index: number | null,
Expand Down Expand Up @@ -173,8 +178,8 @@ export function findWires(tiles: PinCell[]): [Wire[], PinCell[]] {
//todo .filter wire
let wires: Wire[] = []
while (tiles.find(p => p.actual.cellType === 'wire')) {
let [wire, tilesUpd] = getWire(tiles)
tiles = tilesUpd
let wire
[wire, tiles] = getWire(tiles)
if (wire) {
wires.push(wire)
}
Expand All @@ -192,35 +197,40 @@ function pinCellToCell(cells: PinCell[]): Cell[] {
return cells.map(it => it.actual)
}

export function updateWiresAndGatesInState(state: State): State {
const { gates, wires } = state.compiled

export function updateCellsNToActuall(cells: PinCell[]): Cell[] {
let [wires, rest] = findWires(cells)
let result: PinCell[] = []

// update wires
for (let wire of wires) {
const powered = wire.inputs.some(
input => getValueAt(rest, input)
)
const updatedWires: Wire[] = []
const updatedGates: PinCell[] = []
const total: PinCell[] = []

const wireTiles = wire.cells.map(cell => R.set(actualStatePoweredLens, powered, cell))
for (const wire of wires!) {
const powered = wire.inputs.some(input => getValueAt(gates!, input))

result.push(...wireTiles)
}
const wireTiles = wire.cells
.map(R.set(actualStatePoweredLens, powered))
.map(it => it.data.toPins(it.actual))

result.push(...rest)
total.push(...wireTiles)

// update gates
const resultCopy = [...result]
for (const i in resultCopy) {
updatedWires.push(
R.set(buildLens<Wire>().cells._(), wireTiles, wire)
)
}

const gate = resultCopy[i]
const totalCopy = [ ...total, ...gates! ]

if (gate.data.update) {
result[i] = gate.data.update?.(resultCopy, gate)
}
for (const gate of gates!) {
const updatedGate = gate.data.update?.(totalCopy, gate) ?? gate
total.push(updatedGate.data.toPins(updatedGate.actual))
updatedGates.push(updatedGate.data.toPins(updatedGate.actual))
}

return pinCellToCell(result)

return R.pipe(
R.set(buildLens<State>().compiled.gates!._(), updatedGates),
R.set(buildLens<State>().compiled.wires!._(), updatedWires),
R.set(buildLens<State>().cells._(), pinCellToCell(total))
)(state)
}

Loading

0 comments on commit 958451d

Please sign in to comment.