diff --git a/package.json b/package.json
index df16aba..507b8dc 100644
--- a/package.json
+++ b/package.json
@@ -28,8 +28,8 @@
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.1.2",
"@storybook/addon-centered": "^3.4.11",
- "@storybook/addon-knobs": "^4.0.0-rc.6",
"@storybook/addon-info": "^4.0.0-rc.6",
+ "@storybook/addon-knobs": "^4.0.0-rc.6",
"@storybook/addon-notes": "^4.0.0-rc.6",
"@storybook/addon-options": "^4.0.0-rc.6",
"@storybook/addon-storysource": "^4.0.0-rc.6",
@@ -61,7 +61,7 @@
},
"dependencies": {
"classnames": "^2.2.5",
- "memoize-one": "^4.0.2"
+ "flatbush": "^3.1.0"
},
"files": [
"lib/**/*"
diff --git a/src/IndexedEngine.js b/src/IndexedEngine.js
new file mode 100644
index 0000000..1f25b44
--- /dev/null
+++ b/src/IndexedEngine.js
@@ -0,0 +1,122 @@
+import React, { useMutationEffect, useState } from "react";
+import PropTypes from "prop-types";
+import Flatbush from "flatbush";
+import Hex from "./models/Hex";
+import HexEngine from "./HexEngine";
+import HexUtils from "./HexUtils";
+import Orientation from "./models/Orientation";
+import Point from "./models/Point";
+
+const IndexedEngine = ({
+ children,
+ flat,
+ map,
+ origin,
+ size,
+ spacing,
+ viewBox,
+ ...props
+}) => {
+ const orientation = flat ? Orientation.Flat : Orientation.Pointy;
+ const layout = { orientation, origin, size, spacing };
+ const [visible, updateVisible] = useState([]);
+ const [index, setIndex] = useState(() => new Flatbush(map.length));
+
+ useMutationEffect(
+ () => {
+ console.log("new index effect");
+ setIndex(() => new Flatbush(map.length));
+ },
+ [map.length, orientation, origin, spacing, size]
+ );
+ useMutationEffect(
+ () => {
+ console.log("populate index effect");
+ map.forEach(hex => {
+ const point = HexUtils.hexToPixel(hex, layout);
+ index.add(
+ point.x - layout.size.x / 2,
+ point.y - layout.size.y / 2 - 1,
+ point.x + layout.size.x / 2 + 1,
+ point.y + layout.size.y / 2 + 1
+ );
+ });
+ index.finish();
+ },
+ [index]
+ );
+ useMutationEffect(
+ () => {
+ console.log("update visible effect");
+ updateVisible(() =>
+ index
+ .search(
+ viewBox.x,
+ viewBox.y,
+ viewBox.x + viewBox.width,
+ viewBox.y + viewBox.height
+ )
+ .map(i => map[i])
+ );
+ console.log(visible.length);
+ },
+ [viewBox, index]
+ );
+
+ return (
+
+ {children(visible)}
+
+ );
+};
+
+IndexedEngine.propTypes = {
+ children: PropTypes.func.isRequired,
+ /** Determines if the hexagons are oriented with a point or an edge facing up */
+ flat: PropTypes.bool,
+ map: PropTypes.arrayOf(PropTypes.instanceOf(Hex)).isRequired,
+ /** Origin of the grid */
+ origin: PropTypes.oneOfType([
+ PropTypes.instanceOf(Point),
+ PropTypes.shape({
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired
+ })
+ ]),
+ /** Size of the hexagons in each dimension */
+ size: PropTypes.oneOfType([
+ PropTypes.instanceOf(Point),
+ PropTypes.shape({
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired
+ })
+ ]),
+ /** Space between hexagons */
+ spacing: PropTypes.number,
+ /** The viewBox {x,y,width,height} of the svg view area */
+ viewBox: PropTypes.shape({
+ height: PropTypes.number.isRequired,
+ width: PropTypes.number.isRequired,
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired
+ })
+};
+
+IndexedEngine.defaultProps = {
+ classes: { grid: "", layout: "" },
+ flat: true,
+ height: 480,
+ origin: new Point(0, 0),
+ size: new Point(10, 10),
+ spacing: 1.0,
+ width: 640,
+ viewBox: {
+ height: 100,
+ width: 100,
+ x: -50,
+ y: -50
+ }
+};
+
+export const IndexedEngine_ = IndexedEngine;
+export default IndexedEngine_;
diff --git a/stories/HexEngine.js b/stories/HexEngine.js
index efffa32..d2aa378 100644
--- a/stories/HexEngine.js
+++ b/stories/HexEngine.js
@@ -6,6 +6,8 @@ import GridGenerator from "../src/GridGenerator";
import Hexagon, { Hexagon_ } from "../src/Hexagon";
import HexEngine from "../src/HexEngine";
import Point from "../src/models/Point";
+import IndexedEngine from "../src/IndexedEngine";
+import "./Hexagon.css";
Hexagon.displayName = "Hexagon";
Hexagon_.displayName = "Hexagon";
@@ -129,4 +131,42 @@ stories
- ));
+ ))
+ .add("indexed", () => {
+ const viewBox = object(
+ "viewBox",
+ { x: -50, y: -50, width: 100, height: 100 },
+ "HexEngine"
+ );
+ const map = GridGenerator.hexagon(50);
+ const classes = {
+ hexagon: "showCoordinates text",
+ highlighted: "highlighted",
+ hovered: "hovered",
+ selected: "selected",
+ q: "axis",
+ r: "axis",
+ s: "axis",
+ text: "text"
+ };
+ return (
+
+ {hexes =>
+ hexes.map(hex => (
+ 0.5}
+ />
+ ))
+ }
+
+ );
+ });
diff --git a/test/src/HexEngine.test.js b/test/src/HexEngine.test.js
index c14e04f..a368175 100644
--- a/test/src/HexEngine.test.js
+++ b/test/src/HexEngine.test.js
@@ -1,7 +1,9 @@
import React from "react";
import renderer from "react-test-renderer";
+import Hex from "../../src//models/Hex";
import Hexagon from "../../src/Hexagon";
import HexEngine from "../../src/HexEngine";
+import IndexedEngine from "../../src/IndexedEngine";
describe("HexEngine", () => {
it("HexEngine should render correctly with default props", () => {
@@ -26,3 +28,28 @@ describe("HexEngine", () => {
expect(tree).toMatchSnapshot();
});
});
+
+describe("IndexedEngine", () => {
+ it("IndexedEngine should render correctly with default props", () => {
+ const map = [
+ new Hex(-4, 0, 0),
+ new Hex(-3, 0, 0),
+ new Hex(-2, 0, 0),
+ new Hex(-1, 0, 0),
+ new Hex(0, 0, 0),
+ new Hex(1, 0, 0),
+ new Hex(2, 0, 0),
+ new Hex(3, 0, 0),
+ new Hex(4, 0, 0)
+ ];
+
+ const tree = renderer
+ .create(
+
+ {hexes => hexes.map(hex => )}
+
+ )
+ .toJSON();
+ expect(tree).toMatchSnapshot();
+ });
+});
diff --git a/test/src/__snapshots__/HexEngine.test.js.snap b/test/src/__snapshots__/HexEngine.test.js.snap
index f812d97..02b4e5c 100644
--- a/test/src/__snapshots__/HexEngine.test.js.snap
+++ b/test/src/__snapshots__/HexEngine.test.js.snap
@@ -67,3 +67,145 @@ exports[`HexEngine HexEngine should render correctly with pointy orientation 1`]
`;
+
+exports[`IndexedEngine IndexedEngine should render correctly with default props 1`] = `
+
+`;
diff --git a/yarn.lock b/yarn.lock
index a70f463..c2262f0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3608,6 +3608,16 @@ flat-cache@^1.2.1:
graceful-fs "^4.1.2"
write "^0.2.1"
+flatbush@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/flatbush/-/flatbush-3.1.0.tgz#ccd6957685a7db95d2fc27f5d4f24b7131d46553"
+ dependencies:
+ flatqueue "^1.1.0"
+
+flatqueue@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/flatqueue/-/flatqueue-1.1.0.tgz#bc03140d40940c4cb799d18d45eaced176c3ef2d"
+
flush-write-stream@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd"
@@ -5262,10 +5272,6 @@ mem@^1.1.0:
dependencies:
mimic-fn "^1.0.0"
-memoize-one@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.0.2.tgz#3fb8db695aa14ab9c0f1644e1585a8806adc1aee"
-
memory-fs@^0.4.0, memory-fs@~0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"