Add Box component to improve renderers performance

This commit is contained in:
Nilay Majorwar
2022-02-22 14:54:17 +05:30
parent 3e6fb8c780
commit 032f9a6792
6 changed files with 83 additions and 69 deletions

View File

@ -81,9 +81,12 @@ export const editorTokensProvider: MonacoTokensProvider = {
};
/** Serialize tape from object format into linear array */
export const serializeTapeMap = (tape: BFRS["tape"]): number[] => {
export const serializeTapeMap = (
tape: BFRS["tape"],
minCells: number = 0
): number[] => {
const cellIdxs = Object.keys(tape).map((s) => parseInt(s, 10));
const maxCellIdx = Math.max(15, ...cellIdxs);
const maxCellIdx = Math.max(minCells - 1, ...cellIdxs);
const linearTape: number[] = Array(maxCellIdx + 1).fill(0);
cellIdxs.forEach((i) => (linearTape[i] = tape[i] || 0));
return linearTape;

View File

@ -1,14 +1,17 @@
import { Card, Colors } from "@blueprintjs/core";
import { CSSProperties } from "react";
import { useDarkMode } from "../../ui/providers/dark-mode-provider";
import * as React from "react";
import { RendererProps } from "../types";
import { Box } from "../ui-utils";
import { BFRS, serializeTapeMap } from "./common";
// Colors used as background of active cells
const darkActiveBG = Colors.DARK_GRAY2;
const lightActiveBG = Colors.LIGHT_GRAY3;
/** Number of cells shown in a single row */
const ROWSIZE = 8;
const styles: { [k: string]: CSSProperties } = {
// Parameters for cell sizing, balanced to span the full row width
// Constraint: `(width% + 2 * margin%) * ROWSIZE = 100%`
const CELL_WIDTH = "12%";
const CELL_MARGIN = "5px 0.25%";
const styles: { [k: string]: React.CSSProperties } = {
container: {
padding: 10,
height: "100%",
@ -19,9 +22,9 @@ const styles: { [k: string]: CSSProperties } = {
},
cell: {
// Sizing
width: "12%",
width: CELL_WIDTH,
margin: CELL_MARGIN,
height: "50px",
margin: "5px 0.25%",
// Center-align values
display: "flex",
justifyContent: "center",
@ -30,22 +33,24 @@ const styles: { [k: string]: CSSProperties } = {
};
/** Component for displaying a single tape cell */
const Cell = ({ value, active }: { value: number; active: boolean }) => {
const { isDark } = useDarkMode();
const cellStyle = { ...styles.cell };
const activeBg = isDark ? darkActiveBG : lightActiveBG;
if (active) {
cellStyle.backgroundColor = activeBg;
cellStyle.fontWeight = "bold";
const Cell = React.memo(
({ value, active }: { value: number; active: boolean }) => {
return (
<Box
intent={active ? "active" : "plain"}
style={{ ...styles.cell, fontWeight: active ? "bold" : undefined }}
>
{value}
</Box>
);
}
return <Card style={cellStyle}>{value}</Card>;
};
);
/** Renderer for Brainfuck */
export const Renderer = ({ state }: RendererProps<BFRS>) => {
return (
<div style={styles.container}>
{serializeTapeMap(state?.tape || {}).map((num, i) => (
{serializeTapeMap(state?.tape || {}, 2 * ROWSIZE).map((num, i) => (
<Cell value={num} key={i} active={(state?.pointer || 0) === i} />
))}
</div>