Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

171 documentation become the comment master #193

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/client/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export function useSocket(
onMessage?: MessageHandler,
onOpen?: () => void,
): SendMessage {
// handle sending a message and opening it
const { sendMessage } = useWebSocket(WEBSOCKET_URL, {
onOpen: () => {
console.log("Connection established");
Expand All @@ -50,6 +51,7 @@ export function useSocket(
onOpen();
}
},
// handle what to do with the message
onMessage: (msg: MessageEvent) => {
const message = parseMessage(msg.data.toString());
console.log("Handle message: " + message.toJson());
Expand All @@ -60,6 +62,7 @@ export function useSocket(
},
});

// handle how a message is sent
const sendMessageHandler = useMemo(() => {
return (message: Message) => {
console.log("Sending message: " + message.toJson());
Expand All @@ -81,6 +84,7 @@ export async function post(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<any> {
try {
// run a post to the provided api path with the provided query
let normalizedUrl = `/api${apiPath}`;
if (query) {
normalizedUrl += `?${new URLSearchParams(query)}`;
Expand Down
6 changes: 6 additions & 0 deletions src/client/chessboard/board-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ interface BoardContainerProps extends PropsWithChildren {
rotation: number;
}

/**
* A container to deal with chessboard resizing
* @param props - width handler and inner elements
* @returns
*/
export function BoardContainer(props: BoardContainerProps) {
const [transform, setTransform] = useState<Transform | undefined>();

Expand All @@ -20,6 +25,7 @@ export function BoardContainer(props: BoardContainerProps) {
setTransform(transform);
};

// returns the resizable container
return (
<ResizeSensor onResize={handleResize}>
<div id="chess-container">
Expand Down
3 changes: 3 additions & 0 deletions src/client/chessboard/board-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export function computeChessboardTransform(
const width = Math.min(canvasHeight, canvasWidth) * scale;
const height = width;

// shifts the x and y
const xShift = (canvasWidth - width) / 2;
const yShift = (canvasHeight - height) / 2;

// return the shift
return { left: xShift, top: yShift, height, width };
}
29 changes: 27 additions & 2 deletions src/client/chessboard/chessboard-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { customSquareRenderer } from "./custom-square-renderer";
import { CustomSquareContext } from "./custom-square-context";
import { BoardOrientation } from "react-chessboard/dist/chessboard/types";

/**
* an interface of relevant properties for chessboard
*/
interface ChessboardWrapperProps {
/**
* The chess.js instance displayed by this class.
Expand All @@ -28,6 +31,13 @@ interface ChessboardWrapperProps {
onMove: (move: Move) => void;
}

/**
* Creates a chessboard that uses our custom properties inside a board container
*
* These include width, moves, promotions, piece dragging, square highlighting, and
* @param props - chess(ChessEngine), side, onMove
* @returns JSX.Element chessboard
*/
export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
const { chess, side, onMove } = props;

Expand All @@ -40,6 +50,7 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
Square | undefined
>();

// promotion states
const [isPromoting, setIsPromoting] = useState(false);

const [manualPromotionSquare, setManualPromotionSquare] = useState<
Expand All @@ -64,12 +75,17 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
);
};

/**
* make to move passed in and unset lastClickedSquare
*
* @param move - the move made
*/
const doMove = (move: Move): void => {
onMove(move);
setLastClickedSquare(undefined);
};

//set the side to their respective colors
//set the side to their respective colors and orientations
switch (props.side) {
case Side.WHITE:
if (orientation !== "white") setOrientation("white");
Expand All @@ -95,16 +111,19 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
if (width !== undefined) {
chessboard = (
<Chessboard
boardOrientation={orientation}
// set up the board
boardOrientation={side === Side.WHITE ? "white" : "black"}
boardWidth={width}
position={chess.fen}
// do a promotion check
onPromotionCheck={(from: Square, to: Square) => {
const promoting = chess.checkPromotion(from, to);
setIsPromoting(promoting);
return promoting;
}}
showPromotionDialog={manualPromotionSquare !== undefined}
promotionToSquare={manualPromotionSquare}
// handle dragging and dropping pieces
onPieceDrop={(
from: Square,
to: Square,
Expand All @@ -130,17 +149,20 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
promotion: isPromoting ? piece : undefined,
});
}

// Reset state
setIsPromoting(false);
return true;
}
return false;
}}
// when you start dragging, unset clicked square
onPieceDragBegin={(_, square: Square) => {
if (square !== lastClickedSquare) {
setLastClickedSquare(undefined);
}
}}
// handle square clicking
onSquareClick={(square: Square) => {
setManualPromotionSquare(undefined);

Expand All @@ -149,11 +171,13 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
lastClickedSquare !== undefined &&
isLegalMove(lastClickedSquare, square);

// check if the square is legal
if (isSquareLegalMove) {
if (chess.checkPromotion(lastClickedSquare, square)) {
// Manually show promotion dialog
setManualPromotionSquare(square);
} else {
// make the move normally
doMove({
from: lastClickedSquare,
to: square,
Expand All @@ -178,6 +202,7 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element {
);
}

// return the created chessboard inside the board container
return (
<BoardContainer
side={side}
Expand Down
9 changes: 8 additions & 1 deletion src/client/chessboard/custom-square-renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
} from "./svg-components";
import { CustomSquareContext } from "./custom-square-context";

/**
* A renderer for the square dots and piece highlighting
*/
export const customSquareRenderer = forwardRef<
HTMLDivElement,
CustomSquareProps
Expand All @@ -19,6 +22,7 @@ export const customSquareRenderer = forwardRef<
let lastMoveHighlight: ReactElement | null = null;
let clickedPieceHighlight: ReactElement | null = null;

// highlight the last move made
const lastMove = chess.getLastMove();
if (
lastMove !== undefined &&
Expand All @@ -32,6 +36,7 @@ export const customSquareRenderer = forwardRef<
);
}

// highlight clicked pieces
if (
lastClickedSquare !== undefined &&
lastClickedSquare === props.square &&
Expand All @@ -46,6 +51,7 @@ export const customSquareRenderer = forwardRef<
);
}

// highlight legal squares and capture opportunities
if (legalSquares.includes(props.square)) {
// Square should be highlighted
if (chess.hasPiece(props.square)) {
Expand All @@ -57,11 +63,12 @@ export const customSquareRenderer = forwardRef<
/>
);
} else {
//Square is empty
// Square is empty
selectElement = <CenterDot />;
}
}

// return all the highlights inside a div
return (
<div style={props.style} ref={ref}>
{clickedPieceHighlight}
Expand Down
3 changes: 3 additions & 0 deletions src/client/chessboard/svg-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ export function SquareHighlight(props: PieceSquareProps) {
);
}

/**
* SVG of the piece clicked
*/
export function ClickedPiece(props: PieceSquareProps) {
return (
<div
Expand Down
6 changes: 5 additions & 1 deletion src/client/debug/debug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ export function Debug() {
const [selectedRobotId, setSelectedRobotId] = useState<
string | undefined
>();
const navigate = useNavigate();

// helper functions
const navigate = useNavigate();
const sendMessage = useSocket();

// get all the registered robots
useEffect(() => {
const fetchIds = async () => {
const response = await get("/get-ids");
Expand All @@ -27,6 +29,7 @@ export function Debug() {
fetchIds();
}, [setRobotIds]);

// create the select and move buttons
let body: ReactNode;
if (robotIds === undefined) {
body = <Spinner intent="primary" />;
Expand Down Expand Up @@ -65,6 +68,7 @@ export function Debug() {
);
}

// return the dialog with buttons for home and simulator
return (
<Card>
<Button
Expand Down
10 changes: 8 additions & 2 deletions src/client/debug/drive-robot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ function almostEqual(v1: number, v2: number, epsilon: number = 0.01): boolean {
* A component which can be used to drive an individual robot around.
*/
export function DriveRobot(props: DriveRobotProps) {
//state variable for handling the power levels of the robot
// state variable for handling the power levels of the robot
const [power, setPower] = useState({ left: 0, right: 0 });
const [prevPad, setPrevPad] = useState({ left: 0, right: 0 });
const [prev, setPrev] = useState({ left: 0, right: 0 });

//useEffect hook to send the power levels to the robot if there is a change in the power levels
// useEffect hook to send the power levels to the robot if there is a change in the power levels
useEffect(() => {
if (
almostEqual(prev.left, power.left) &&
Expand All @@ -40,6 +40,7 @@ export function DriveRobot(props: DriveRobotProps) {
setPrev({ left: power.left, right: power.right });
}, [props, power.left, power.right, prev]);

// allow use of a gamepad
useEffect(() => {
if (!navigator.getGamepads) {
console.log("Gamepad API not supported");
Expand Down Expand Up @@ -67,6 +68,7 @@ export function DriveRobot(props: DriveRobotProps) {
) {
continue;
}
// set power based on pad values
setPower({ left: padLeftPower, right: padRightPower });
setPrevPad({ left: padLeftPower, right: padRightPower });
}
Expand All @@ -83,6 +85,7 @@ export function DriveRobot(props: DriveRobotProps) {
};
}, [props, prevPad]);

// the move types and corresponding motor powers
const handleStopMove = useCallback(() => {
setPower({ left: 0, right: 0 });
}, []);
Expand All @@ -100,6 +103,7 @@ export function DriveRobot(props: DriveRobotProps) {
setPower({ left: -0.5, right: 0.5 });
}, []);

// handle when the left and right powers change
const handleLeftPowerChange = useCallback(
(value: number) => {
setPower({ left: value, right: power.right });
Expand All @@ -113,6 +117,7 @@ export function DriveRobot(props: DriveRobotProps) {
[power.left],
);

/** use wasd and arrows to control robots */
const hotkeys = useMemo(
() => [
{
Expand Down Expand Up @@ -189,6 +194,7 @@ export function DriveRobot(props: DriveRobotProps) {
],
);

// show instructions and on screen buttons
const { handleKeyDown, handleKeyUp } = useHotkeys(hotkeys);

const convertJoystickXYToMotorPowers = useCallback(
Expand Down
5 changes: 5 additions & 0 deletions src/client/debug/drive-slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ interface DriveSliderProps {
onChange: (value: number) => void;
}

/**
* creates a slider to show power values in debug driving
* @param props - the value of the slider
* @returns
*/
export function DriveSlider(props: DriveSliderProps) {
return (
<Slider
Expand Down
16 changes: 15 additions & 1 deletion src/client/debug/select-robot.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { Button, MenuItem } from "@blueprintjs/core";
import { ItemRenderer, Select } from "@blueprintjs/select";

/**
* Creates a robot menu item
*
* @param robotId - id of the robot
* @param param1 - handlers for active, focus, and click
* @returns a menu item for the robot id
*/
const renderRobotIds: ItemRenderer<string> = (
robotId,
{ modifiers, handleFocus, handleClick },
Expand All @@ -17,19 +24,26 @@ const renderRobotIds: ItemRenderer<string> = (
);
};

/**
* Ids, selected id, and on robot selected function
*/
interface SelectRobotProps {
robotIds: string[];
selectedRobotId: string | undefined;
onRobotIdSelected: (robotId: string) => void;
}

/**
* Creates a selector for a robot.
* Creates the robot selector dialog
*
* @param props - robot ids and select function
* @returns - select dropdown
*/
export function SelectRobot(props: SelectRobotProps) {
const hasSelection = props.selectedRobotId !== undefined;

return (
// get all the robot ids in the list for selection
<Select<string>
items={props.robotIds}
itemRenderer={renderRobotIds}
Expand Down
5 changes: 5 additions & 0 deletions src/client/debug/set-robot-variable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ interface SetRobotVariableProps {
sendMessage: SendMessage;
}

/**
* set a variable for a robot
* @param props - function for setting the variable
* @returns - setup form
*/
export function SetRobotVariable(props: SetRobotVariableProps): JSX.Element {
const [variableName, setVariableName] = useState("");
const [variableValue, setVariableValue] = useState("");
Expand Down
Loading