Skip to content

Commit

Permalink
feat(ecs-browser): Allow spawning of prototypes at arbitrary locations (
Browse files Browse the repository at this point in the history
#117)

* fix: clear dev highlights when mouse leaves entity section

* feat(ecs-browser): allow spawning of prototypes at arbitrary locations
  • Loading branch information
Kooshaba authored Aug 2, 2022
1 parent 934bdcb commit b31bfcd
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
12 changes: 12 additions & 0 deletions packages/ecs-browser/src/Browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { EntityEditor } from "./EntityEditor";
import { QueryBuilder } from "./QueryBuilder";
import { useClearDevHighlights } from "./hooks";
import { observer } from "mobx-react-lite";
import { PrototypeCreator } from "./PrototypeCreator";
import { Coord } from "@latticexyz/phaserx";

/**
* An Entity Browser for viewing/editiing Component values.
Expand All @@ -17,13 +19,17 @@ export const Browser = observer(
setContractComponentValue,
devHighlightComponent,
hoverHighlightComponent,
prototypeComponent,
spawnPrototypeAt,
world,
}: {
entities: EntityID[];
layers: Layers;
setContractComponentValue: SetContractComponentFunction<Schema>;
devHighlightComponent: Component<{ value: Type.OptionalNumber }>;
hoverHighlightComponent: Component<{ x: Type.OptionalNumber; y: Type.OptionalNumber }>;
prototypeComponent: Component<{ value: Type.StringArray }>;
spawnPrototypeAt: (prototypeId: EntityID, position: Coord) => void;
world: World;
}) => {
const [filteredEntities, setFilteredEntities] = useState<EntityID[]>([]);
Expand All @@ -42,6 +48,12 @@ export const Browser = observer(
clearDevHighlights={clearDevHighlights}
setOverflow={setOverflow}
/>
<PrototypeCreator
layers={layers}
hoverHighlightComponent={hoverHighlightComponent}
prototypeComponent={prototypeComponent}
spawnPrototypeAt={spawnPrototypeAt}
/>
<SmallHeadline>
Showing {filteredEntities.length} of {filteredEntities.length + overflow} entities
</SmallHeadline>
Expand Down
1 change: 1 addition & 0 deletions packages/ecs-browser/src/EntityEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const EntityEditor = observer(
value: undefined,
});
}}
onMouseLeave={() => clearDevHighlights()}
>
<div onClick={() => setOpened(!opened)} style={{ cursor: "pointer" }}>
<h3 style={{ color: "white" }}>{world.entities[entity]}</h3>
Expand Down
73 changes: 73 additions & 0 deletions packages/ecs-browser/src/PrototypeCreator/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Component, EntityID, Has, Layers, Type } from "@latticexyz/recs";
import React, { useEffect, useState } from "react";
import { ComponentBrowserButton, ComponentBrowserSelect } from "../StyledComponents";
import { Coord } from "@latticexyz/phaserx";
import { useComponentValueStream, useQuery } from "@latticexyz/std-client";

export const PrototypeCreator: React.FC<{
layers: Layers;
spawnPrototypeAt: (prototypeId: EntityID, position: Coord) => void;
prototypeComponent: Component<{ value: Type.StringArray }>;
hoverHighlightComponent: Component<{ x: Type.OptionalNumber; y: Type.OptionalNumber }>;
}> = ({ layers, prototypeComponent, hoverHighlightComponent, spawnPrototypeAt }) => {
const [selectingPosition, setSelectingPosition] = useState(false);
const [selectedPrototype, setSelectedPrototype] = useState<string | undefined>(undefined);
const hoverHighlight = useComponentValueStream(hoverHighlightComponent);

const prototypes = useQuery([Has(prototypeComponent)]);

useEffect(() => {
if (!selectingPosition) return;

function onMouseDown() {
if (!hoverHighlight) return;
if (hoverHighlight.x == null || hoverHighlight.y == null) return;

setSelectingPosition(false);
spawnPrototypeAt(selectedPrototype as EntityID, { x: hoverHighlight.x, y: hoverHighlight.y });
}

document.addEventListener("mousedown", onMouseDown);
return () => {
document.removeEventListener("mousedown", onMouseDown);
};
}, [selectingPosition, hoverHighlight]);

if (!prototypes) return null;

return (
<div
style={{
display: "flex",
flexDirection: "row",
}}
>
<ComponentBrowserSelect
style={{ margin: "8px auto" }}
value={selectedPrototype}
onChange={(e) => {
setSelectedPrototype(e.target.value);
}}
>
<option value="">None</option>
{[...prototypes].map((entityIndex) => {
const entityId = layers.network.world.entities[entityIndex];
return (
<option key={entityId} value={entityId}>
{entityId}
</option>
);
})}
</ComponentBrowserSelect>
<ComponentBrowserButton
style={{ margin: "8px auto" }}
active={selectingPosition}
onClick={() => {
setSelectingPosition(true);
}}
>
{selectingPosition ? `Spawn prototype at (${hoverHighlight?.x}, ${hoverHighlight?.y})` : 'Begin spawning prototype' }
</ComponentBrowserButton>
</div>
);
};

0 comments on commit b31bfcd

Please sign in to comment.