Skip to content

Commit

Permalink
Merge branch 'feature-debugger'
Browse files Browse the repository at this point in the history
  • Loading branch information
spaaaacccee committed Nov 30, 2023
2 parents fa84f6a + 292e980 commit 0ec934d
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 169 deletions.
2 changes: 1 addition & 1 deletion client/src/components/app-bar/Playback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function PlaybackService({

const notify = useSnackbar();
const [{ playbackRate = 1 }] = useSettings();
const shouldBreak = useBreakpoints();
const shouldBreak = useBreakpoints(value?.key);

const renderLabel = useCallback(
(label: ReactNode, offset: number) => (
Expand Down
24 changes: 12 additions & 12 deletions client/src/components/breakpoint-editor/BreakpointEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Divider, TextField, Typography as Type } from "@mui/material";
import { find, last, map, startCase } from "lodash";
import { comparators } from "./comparators";
import { eventTypes } from "./eventTypes";
import { Flex } from "components/generic/Flex";
import { SelectField as Select } from "components/generic/Select";
import { Space } from "components/generic/Space";
import { Switch } from "components/generic/Switch";
import { Breakpoint } from "slices/UIState";

import { Divider, TextField, Typography as Type } from "@mui/material";
import { find, last, map, startCase } from "lodash";
import { comparators } from "./comparators";
import { eventTypes } from "./eventTypes";
import { Flex } from "components/generic/Flex";
import { SelectField as Select } from "components/generic/Select";
import { Space } from "components/generic/Space";
import { Switch } from "components/generic/Switch";
import { Breakpoint } from "slices/UIState";

type BreakpointEditorProps = {
value: Breakpoint;
onValueChange?: (v: Breakpoint) => void;
Expand All @@ -23,7 +23,7 @@ export function BreakpointEditor({
onChange?.({ ...value, ...next });
}
return (
<Flex>
<Flex sx={{ mx: -2 }}>
<Select
placeholder="Event"
sx={{ minWidth: 160 }}
Expand Down Expand Up @@ -85,4 +85,4 @@ export function BreakpointEditor({
/>
</Flex>
);
}
}
37 changes: 28 additions & 9 deletions client/src/components/breakpoint-editor/BreakpointListEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
import { Box } from "@mui/material";
import { ListEditor } from "components/generic/ListEditor";
import { debounce, flatMap as flat, get, keys, map, uniq } from "lodash";
import { Breakpoint, useUIState } from "slices/UIState";
import { Breakpoint, DebugLayerData } from "hooks/useBreakpoints";
import { flatMap as flat, get, keys, map, set, uniq } from "lodash";
import { produce } from "produce";
import { useLayer } from "slices/layers";
import { BreakpointEditor } from "./BreakpointEditor";
import { comparators } from "./comparators";
import { intrinsicProperties } from "./intrinsicProperties";
import { propertyPaths as paths } from "./propertyPaths";

export function BreakpointListEditor() {
const [{ breakpoints = [] }, setUIState] = useUIState();
type BreakpointListEditorProps = {
breakpoints?: Breakpoint[];
onValueChange?: (v: Breakpoint[]) => void;
layer?: string;
};

export function BreakpointListEditor({
layer: key,
}: BreakpointListEditorProps) {
const { layer, setLayer } = useLayer<DebugLayerData>(key);
const { breakpoints } = layer?.source ?? {};

function handleBreakpointsChange(updatedBreakpoints: Breakpoint[]) {
layer &&
setLayer(
produce(layer, (layer) =>
set(layer, "source.breakpoints", updatedBreakpoints)
)
);
}

const properties = uniq([
...intrinsicProperties,
Expand All @@ -26,18 +46,17 @@ export function BreakpointListEditor() {
value={breakpoints}
useDelete
useEdit={false}
editor={(v) => <BreakpointEditor value={v} properties={properties} />}
editor={(v) => <BreakpointEditor value={v} properties={properties} />} //v = a breakpoint
create={() => ({
active: true,
property: properties?.[0],
condition: comparators?.[0],
type: undefined,
reference: 0,
})}
onChange={debounce(
(v) => setUIState(() => ({ breakpoints: v })),
1000
)}
onChange={(updatedBreakpoints) =>
handleBreakpointsChange(updatedBreakpoints)
}
addItemLabel="Breakpoint"
placeholderText="Click the button below to add a breakpoint."
/>
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/inspector/EventInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ export function EventInspector({
);
}

export function Skeleton() {
export function Skeleton({ event }: EventInspectorProps) {
const { spacing } = useTheme();
return (
<>
<ListItem
sx={{
height: 80,
borderLeft: `${spacing(0.5)} solid transparent`,
borderLeft: `${spacing(0.5)} solid ${getColorHex(event?.type)}`,
}}
>
<ListItemIcon>
Expand Down
141 changes: 83 additions & 58 deletions client/src/hooks/useBreakpoints.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,85 @@
import { useCallback } from "react";
import { call } from "components/script-editor/call";
import { get, keyBy, toLower as lower, startCase } from "lodash";
import memoizee from "memoizee";
import { TraceEventType } from "protocol";
import { useMemo } from "react";
import { UploadedTrace } from "slices/UIState";
import { useLayer } from "slices/layers";


export type Comparator = {
key: string;
apply: (value: number, reference: number) => boolean;
};

export type Breakpoint = {
key: string;
property?: string;
reference?: number;
condition?: Comparator;
active?: boolean;
type?: TraceEventType;
};

export type DebugLayerData = {
code?: string;
monotonicF?: boolean;
monotonicG?: boolean;
breakpoints?: Breakpoint[];
trace?: UploadedTrace;
};
export function useBreakpoints(key?: string) {
const { layer } = useLayer<DebugLayerData>(key);
const {monotonicF, monotonicG,breakpoints ,code,trace} = layer?.source??{}
// TODO:
return useMemo(() => {
const memo = keyBy(trace?.content?.events, "id");
return memoizee((step: number) => {
const event = trace?.content?.events?.[step];
if (event) {
try {
// Check monotonic f or g values
if (step) {
for (const p of [monotonicF && "f", monotonicG && "g"]) {
if (p && get(memo[`${event.pId}`], p) > get(event, p)) {
return { result: `Monotonicity violation on ${p}` };
}
}
}
// Check breakpoints in the breakpoints section
for (const {
active,
condition,
type,
property = "",
reference = 0,
} of breakpoints??[]) {
const isType = !type || type === event.type;
const match = condition?.apply?.(get(event, property), reference);
if (active && isType && match) {
return {
result: `${property} ${lower(
startCase(condition?.key)
)} ${reference}`,
};
}
}
// Check breakpoints in the script editor section
if (
call(code ?? "", "shouldBreak", [
step,
event,
trace?.content?.events?? [],
])
) {
return { result: "Script editor" };
}
} catch (e) {
return { error: `${e}` };
}
}
return { result: "" };
});
}, [code, trace?.content, breakpoints, monotonicF, monotonicG]);

export function useBreakpoints() {
//TODO:
// const [{ specimen }] = useSpecimen();
// const [{ code, breakpoints = [], monotonicF, monotonicG }] = useUIState();
// return useMemo(() => {
// const memo = keyBy(specimen?.eventList, "id");
// return memoize((step: number) => {
// const event = specimen?.eventList?.[step];
// if (event) {
// try {
// // Check monotonic f or g values
// if (step) {
// for (const p of [monotonicF && "f", monotonicG && "g"]) {
// if (p && get(memo[`${event.pId}`], p) > get(event, p)) {
// return { result: `Monotonicity violation on ${p}` };
// }
// }
// }
// // Check breakpoints in the breakpoints section
// for (const {
// active,
// condition,
// type,
// property = "",
// reference = 0,
// } of breakpoints) {
// const isType = !type || type === event.type;
// const match = condition?.apply?.(get(event, property), reference);
// if (active && isType && match) {
// return {
// result: `${property} ${lower(
// startCase(condition?.key)
// )} ${reference}`,
// };
// }
// }
// // Check breakpoints in the script editor section
// if (
// call(code ?? "", "shouldBreak", [
// step,
// event,
// specimen?.eventList ?? [],
// ])
// ) {
// return { result: "Script editor" };
// }
// } catch (e) {
// return { error: `${e}` };
// }
// }
// return { result: "" };
// });
// }, [code, specimen, breakpoints, monotonicF, monotonicG]);
return useCallback(
(_i: number) => ({ result: "", error: undefined, offset: 0 }),
[]
);
}
4 changes: 2 additions & 2 deletions client/src/hooks/usePlaybackState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ export function usePlaybackState(key?: string) {

const callbacks = {
play: () => {
notify("Playback started");
// notify("Playback started");
setPlaybackState({ playback: "playing", step: stepBy(1) });
},
pause: (n = 0) => {
notify("Playback paused");
// notify("Playback paused");
setPlaybackState({ playback: "paused", step: stepBy(n) });
},
stepTo: (n = 0) => setPlaybackState({ step: n }),
Expand Down
3 changes: 2 additions & 1 deletion client/src/layers/trace/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { colorsHex, getColorHex } from "components/renderer/colors";
import { parseString } from "components/renderer/parser/parseString";
import { useTraceParser } from "components/renderer/parser/parseTrace";
import { ParseTraceWorkerReturnType } from "components/renderer/parser/parseTraceSlave.worker";
import { DebugLayerData } from "hooks/useBreakpoints";
import { useEffectWhen } from "hooks/useEffectWhen";
import { LayerController, inferLayerName } from "layers";
import {
Expand Down Expand Up @@ -99,7 +100,7 @@ export type TraceLayerData = {
trace?: UploadedTrace;
parsedTrace?: ParseTraceWorkerReturnType;
onion?: "off" | "transparent" | "solid";
} & PlaybackLayerData;
} & PlaybackLayerData & DebugLayerData;

export type TraceLayer = Layer<TraceLayerData>;

Expand Down
Loading

0 comments on commit 0ec934d

Please sign in to comment.