@opalkelly/frontpanel-react-components 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/FrontPanel/FrontPanel.props.d.ts +4 -4
- package/dist/cjs/types/contexts/FrontPanelContext.d.ts +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/FrontPanel/FrontPanel.props.d.ts +4 -4
- package/dist/esm/types/contexts/FrontPanelContext.d.ts +3 -3
- package/dist/index.d.ts +6 -6
- package/package.json +14 -13
- package/src/components/FrontPanel/FrontPanel.props.ts +5 -5
- package/src/components/FrontPanel/FrontPanel.tsx +2 -2
- package/src/components/FrontPanelIndicator/FrontPanelIndicator.tsx +5 -5
- package/src/components/FrontPanelNumberDisplay/FrontPanelNumberDisplay.tsx +5 -5
- package/src/components/FrontPanelNumberEntry/FrontPanelNumberEntry.stories.tsx +3 -6
- package/src/components/FrontPanelNumberEntry/FrontPanelNumberEntry.tsx +12 -12
- package/src/components/FrontPanelPushButton/FrontPanelPushButton.tsx +10 -10
- package/src/components/FrontPanelRangeSlider/FrontPanelRangeSlider.stories.tsx +4 -6
- package/src/components/FrontPanelRangeSlider/FrontPanelRangeSlider.tsx +10 -10
- package/src/components/FrontPanelSelectEntry/FrontPanelSelectEntry.stories.tsx +3 -6
- package/src/components/FrontPanelSelectEntry/FrontPanelSelectEntryRoot.tsx +12 -12
- package/src/components/FrontPanelToggleSwitch/FrontPanelToggleSwitch.tsx +11 -11
- package/src/components/FrontPanelTriggerButton/FrontPanelTriggerButton.tsx +5 -5
- package/src/contexts/FrontPanelContext.ts +4 -4
- package/src/stories/decorators/FrontPanel.decorator.tsx +10 -8
package/package.json
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
{
|
2
2
|
"name": "@opalkelly/frontpanel-react-components",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0",
|
4
4
|
"description": "React Component Library for OpalKelly FrontPanel application development",
|
5
|
+
"private": false,
|
5
6
|
"keywords": [
|
6
7
|
"FPGA",
|
7
8
|
"FrontPanel",
|
@@ -42,16 +43,16 @@
|
|
42
43
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
43
44
|
"@rollup/plugin-terser": "^0.4.4",
|
44
45
|
"@rollup/plugin-typescript": "^11.1.5",
|
45
|
-
"@storybook/addon-essentials": "^8.
|
46
|
-
"@storybook/addon-interactions": "^8.
|
47
|
-
"@storybook/addon-links": "^8.
|
48
|
-
"@storybook/addon-webpack5-compiler-swc": "^1.0
|
49
|
-
"@storybook/blocks": "^8.
|
50
|
-
"@storybook/manager-api": "^8.
|
51
|
-
"@storybook/react": "^8.
|
52
|
-
"@storybook/react-webpack5": "^8.
|
53
|
-
"@storybook/test": "^8.
|
54
|
-
"@storybook/theming": "^8.
|
46
|
+
"@storybook/addon-essentials": "^8.6.4",
|
47
|
+
"@storybook/addon-interactions": "^8.6.4",
|
48
|
+
"@storybook/addon-links": "^8.6.4",
|
49
|
+
"@storybook/addon-webpack5-compiler-swc": "^2.1.0",
|
50
|
+
"@storybook/blocks": "^8.6.4",
|
51
|
+
"@storybook/manager-api": "^8.6.4",
|
52
|
+
"@storybook/react": "^8.6.4",
|
53
|
+
"@storybook/react-webpack5": "^8.6.4",
|
54
|
+
"@storybook/test": "^8.6.4",
|
55
|
+
"@storybook/theming": "^8.6.4",
|
55
56
|
"@types/react": "^18.2.45",
|
56
57
|
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
57
58
|
"@typescript-eslint/parser": "^7.1.1",
|
@@ -64,12 +65,12 @@
|
|
64
65
|
"rollup-plugin-dts": "^6.1.0",
|
65
66
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
66
67
|
"rollup-plugin-postcss": "^4.0.2",
|
67
|
-
"storybook": "^8.
|
68
|
+
"storybook": "^8.6.4",
|
68
69
|
"tslib": "^2.6.2",
|
69
70
|
"typescript": "^5.3.3"
|
70
71
|
},
|
71
72
|
"peerDependencies": {
|
72
|
-
"@opalkelly/frontpanel-platform-api": "^0.
|
73
|
+
"@opalkelly/frontpanel-platform-api": "^0.5.0",
|
73
74
|
"@radix-ui/react-scroll-area": "^1.0.5",
|
74
75
|
"@radix-ui/react-select": "^2.0.0",
|
75
76
|
"@radix-ui/react-slider": "^1.1.2",
|
@@ -6,16 +6,16 @@
|
|
6
6
|
*/
|
7
7
|
|
8
8
|
import {
|
9
|
-
|
10
|
-
|
9
|
+
IFPGADataPortClassic,
|
10
|
+
IFPGADataPortClassicEventSource,
|
11
11
|
WorkQueue
|
12
12
|
} from "@opalkelly/frontpanel-platform-api";
|
13
13
|
|
14
14
|
interface FrontPanelProps extends React.PropsWithChildren<NonNullable<unknown>> {
|
15
15
|
/**
|
16
|
-
* The
|
16
|
+
* The FPGA data port to be used
|
17
17
|
*/
|
18
|
-
|
18
|
+
fpgaDataPort?: IFPGADataPortClassic;
|
19
19
|
/**
|
20
20
|
* Optional work queue to be used
|
21
21
|
*/
|
@@ -23,7 +23,7 @@ interface FrontPanelProps extends React.PropsWithChildren<NonNullable<unknown>>
|
|
23
23
|
/**
|
24
24
|
* Optional event source to be used
|
25
25
|
*/
|
26
|
-
eventSource?:
|
26
|
+
eventSource?: IFPGADataPortClassicEventSource;
|
27
27
|
}
|
28
28
|
|
29
29
|
export { FrontPanelProps };
|
@@ -12,11 +12,11 @@ import { FrontPanelProps } from "./FrontPanel.props";
|
|
12
12
|
import { FrontPanelContext } from "../../contexts";
|
13
13
|
|
14
14
|
const FrontPanel: React.FC<FrontPanelProps> = (props) => {
|
15
|
-
const {
|
15
|
+
const { fpgaDataPort, workQueue, eventSource } = props;
|
16
16
|
|
17
17
|
return (
|
18
18
|
<FrontPanelContext.Provider
|
19
|
-
value={{
|
19
|
+
value={{ fpgaDataPort: fpgaDataPort, workQueue: workQueue, eventSource: eventSource }}>
|
20
20
|
{props.children}
|
21
21
|
</FrontPanelContext.Provider>
|
22
22
|
);
|
@@ -13,7 +13,7 @@ import FrontPanelIndicatorProps from "./FrontPanelIndicator.props";
|
|
13
13
|
|
14
14
|
import { FrontPanelContext } from "../../contexts";
|
15
15
|
|
16
|
-
import {
|
16
|
+
import { IFPGADataPortClassic } from "@opalkelly/frontpanel-platform-api";
|
17
17
|
|
18
18
|
type FrontPanelIndicatorElement = React.ElementRef<typeof Indicator>;
|
19
19
|
|
@@ -45,14 +45,14 @@ const FrontPanelIndicator = React.forwardRef<
|
|
45
45
|
>((props, forwardedRef) => {
|
46
46
|
const [bitValue, setBitValue] = React.useState<boolean>(false);
|
47
47
|
|
48
|
-
const {
|
48
|
+
const { fpgaDataPort, workQueue, eventSource } = React.useContext(FrontPanelContext);
|
49
49
|
|
50
50
|
const { fpEndpoint, ...rootProps } = props;
|
51
51
|
|
52
52
|
const targetWireBitMask = 1 << fpEndpoint.bitOffset;
|
53
53
|
|
54
54
|
const onUpdateWireValue = React.useCallback(
|
55
|
-
(sender?:
|
55
|
+
(sender?: IFPGADataPortClassic): void => {
|
56
56
|
if ((sender != null) && (workQueue != null)) {
|
57
57
|
const sourceWireValue = sender.getWireOutValue(fpEndpoint.epAddress);
|
58
58
|
const sourceBitValue = (sourceWireValue & targetWireBitMask) === targetWireBitMask;
|
@@ -65,14 +65,14 @@ const FrontPanelIndicator = React.forwardRef<
|
|
65
65
|
);
|
66
66
|
|
67
67
|
React.useEffect(() => {
|
68
|
-
onUpdateWireValue(
|
68
|
+
onUpdateWireValue(fpgaDataPort);
|
69
69
|
|
70
70
|
const subscription = eventSource?.wireOutValuesChangedEvent.subscribe(onUpdateWireValue);
|
71
71
|
|
72
72
|
return () => {
|
73
73
|
subscription?.cancel();
|
74
74
|
};
|
75
|
-
}, [
|
75
|
+
}, [fpgaDataPort, eventSource, onUpdateWireValue]);
|
76
76
|
|
77
77
|
return <Indicator {...rootProps} ref={forwardedRef} state={bitValue} />;
|
78
78
|
});
|
@@ -17,7 +17,7 @@ import { FrontPanelContext } from "../../contexts";
|
|
17
17
|
|
18
18
|
import { CalculateBitLength } from "../../core";
|
19
19
|
|
20
|
-
import {
|
20
|
+
import { IFPGADataPortClassic, WIREOUT_ADDRESS_RANGE } from "@opalkelly/frontpanel-platform-api";
|
21
21
|
|
22
22
|
type FrontPanelNumberDisplayElement = React.ElementRef<typeof NumberDisplay>;
|
23
23
|
|
@@ -54,7 +54,7 @@ const FrontPanelNumberDisplay = React.forwardRef<
|
|
54
54
|
>((props, forwardedRef) => {
|
55
55
|
const [value, setValue] = React.useState<bigint>(0n);
|
56
56
|
|
57
|
-
const {
|
57
|
+
const { fpgaDataPort, workQueue, eventSource } = React.useContext(FrontPanelContext);
|
58
58
|
|
59
59
|
const { maximumValue, fpEndpoint, ...rootProps } = props;
|
60
60
|
|
@@ -66,7 +66,7 @@ const FrontPanelNumberDisplay = React.forwardRef<
|
|
66
66
|
((1n << BigInt(targetBitLength)) - 1n) << BigInt(fpEndpoint.bitOffset);
|
67
67
|
|
68
68
|
const onUpdateWireValue = React.useCallback(
|
69
|
-
(sender?:
|
69
|
+
(sender?: IFPGADataPortClassic): void => {
|
70
70
|
if ((sender != null) && (workQueue != null)) {
|
71
71
|
// Get the wire value for the endpoint
|
72
72
|
let sourceWireValue = sender.getWireOutValue(fpEndpoint.epAddress);
|
@@ -106,14 +106,14 @@ const FrontPanelNumberDisplay = React.forwardRef<
|
|
106
106
|
);
|
107
107
|
|
108
108
|
React.useEffect(() => {
|
109
|
-
onUpdateWireValue(
|
109
|
+
onUpdateWireValue(fpgaDataPort);
|
110
110
|
|
111
111
|
const subscription = eventSource?.wireOutValuesChangedEvent.subscribe(onUpdateWireValue);
|
112
112
|
|
113
113
|
return () => {
|
114
114
|
subscription?.cancel();
|
115
115
|
};
|
116
|
-
}, [
|
116
|
+
}, [fpgaDataPort, eventSource, onUpdateWireValue]);
|
117
117
|
|
118
118
|
return (
|
119
119
|
<NumberDisplay
|
@@ -64,10 +64,8 @@ export const Primary: Story = {
|
|
64
64
|
render: (props) => {
|
65
65
|
const { device, workQueue } = useContext(FrontPanelContext);
|
66
66
|
|
67
|
-
const setWireInPromises: Promise<void>[] = [];
|
68
|
-
|
69
67
|
// Initialize the WireIns with unique values.
|
70
|
-
workQueue
|
68
|
+
workQueue?.post(async (): Promise<void> => {
|
71
69
|
let byteId = 0;
|
72
70
|
|
73
71
|
for (let address = 0x0; address < 0x20; address++) {
|
@@ -75,11 +73,10 @@ export const Primary: Story = {
|
|
75
73
|
for (let byteIndex = 1; byteIndex < 4; byteIndex++) {
|
76
74
|
wireValue |= byteId++ << (8 * byteIndex);
|
77
75
|
}
|
78
|
-
|
76
|
+
device?.setWireInValue(address, wireValue, 0xffffffff);
|
79
77
|
}
|
80
78
|
|
81
|
-
await
|
82
|
-
await device.updateWireIns();
|
79
|
+
await device?.updateWireIns();
|
83
80
|
});
|
84
81
|
|
85
82
|
return <FrontPanelNumberEntry {...props} />;
|
@@ -17,7 +17,7 @@ import { FrontPanelContext } from "../../contexts";
|
|
17
17
|
|
18
18
|
import { CalculateBitLength } from "../../core";
|
19
19
|
|
20
|
-
import {
|
20
|
+
import { IFPGADataPortClassic, WIREIN_ADDRESS_RANGE } from "@opalkelly/frontpanel-platform-api";
|
21
21
|
|
22
22
|
type FrontPanelNumberEntryElement = React.ElementRef<typeof NumberEntry>;
|
23
23
|
|
@@ -54,7 +54,7 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
54
54
|
>((props, forwardedRef) => {
|
55
55
|
const [value, setValue] = React.useState<bigint>(props.minimumValue ?? 0n);
|
56
56
|
|
57
|
-
const {
|
57
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
58
58
|
|
59
59
|
const { maximumValue, minimumValue, fpEndpoint, disabled, ...rootProps } = props;
|
60
60
|
|
@@ -72,7 +72,7 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
72
72
|
((1n << BigInt(targetBitLength)) - 1n) << BigInt(fpEndpoint.bitOffset);
|
73
73
|
|
74
74
|
const onUpdateWireValue = React.useCallback(
|
75
|
-
(sender?:
|
75
|
+
(sender?: IFPGADataPortClassic): void => {
|
76
76
|
if ((sender != null) && (workQueue != null)) {
|
77
77
|
// Get the wire value for the endpoint
|
78
78
|
let sourceWireValue = sender.getWireInValue(fpEndpoint.epAddress);
|
@@ -112,12 +112,12 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
112
112
|
);
|
113
113
|
|
114
114
|
React.useEffect(() => {
|
115
|
-
onUpdateWireValue(
|
116
|
-
}, [
|
115
|
+
onUpdateWireValue(fpgaDataPort);
|
116
|
+
}, [fpgaDataPort, onUpdateWireValue]);
|
117
117
|
|
118
118
|
const onNumberEntryValueChange = React.useCallback(
|
119
119
|
async (value: bigint): Promise<void> => {
|
120
|
-
if ((
|
120
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
121
121
|
await workQueue.post(async () => {
|
122
122
|
let targetWireBitMask = targetWireSpanBitMask & 0xffffffffn;
|
123
123
|
let targetWireValue = Number(
|
@@ -125,7 +125,7 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
125
125
|
);
|
126
126
|
|
127
127
|
// Set the wire value for the endpoint
|
128
|
-
|
128
|
+
fpgaDataPort.setWireInValue(
|
129
129
|
fpEndpoint.epAddress,
|
130
130
|
targetWireValue,
|
131
131
|
Number(targetWireBitMask)
|
@@ -148,7 +148,7 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
148
148
|
);
|
149
149
|
|
150
150
|
// Set the wire value for the next endpoint
|
151
|
-
|
151
|
+
fpgaDataPort.setWireInValue(
|
152
152
|
targetWireAddress,
|
153
153
|
targetWireValue,
|
154
154
|
Number(targetWireBitMask)
|
@@ -159,20 +159,20 @@ const FrontPanelNumberEntry = React.forwardRef<
|
|
159
159
|
}
|
160
160
|
}
|
161
161
|
|
162
|
-
await
|
162
|
+
await fpgaDataPort.updateWireIns();
|
163
163
|
});
|
164
164
|
}
|
165
165
|
|
166
|
-
onUpdateWireValue(
|
166
|
+
onUpdateWireValue(fpgaDataPort);
|
167
167
|
},
|
168
|
-
[
|
168
|
+
[fpgaDataPort, workQueue, fpEndpoint, targetWireSpanBitMask, onUpdateWireValue]
|
169
169
|
);
|
170
170
|
|
171
171
|
return (
|
172
172
|
<NumberEntry
|
173
173
|
{...rootProps}
|
174
174
|
ref={forwardedRef}
|
175
|
-
disabled={disabled || (
|
175
|
+
disabled={disabled || (fpgaDataPort === null)}
|
176
176
|
maximumValue={maximumValue}
|
177
177
|
minimumValue={clampedMinimumValue}
|
178
178
|
value={value}
|
@@ -45,35 +45,35 @@ const FrontPanelPushButton = React.forwardRef<
|
|
45
45
|
FrontPanelPushButtonElement,
|
46
46
|
FrontPanelPushButtonCombinedProps
|
47
47
|
>((props, forwardedRef) => {
|
48
|
-
const {
|
48
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
49
49
|
|
50
50
|
const { fpEndpoint, disabled, ...buttonProps } = props;
|
51
51
|
|
52
52
|
const targetWireBitMask = 1 << fpEndpoint.bitOffset;
|
53
53
|
|
54
54
|
const onButtonUp = React.useCallback(async (): Promise<void> => {
|
55
|
-
if ((
|
55
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
56
56
|
await workQueue.post(async () => {
|
57
|
-
|
58
|
-
await
|
57
|
+
fpgaDataPort.setWireInValue(fpEndpoint.epAddress, 0, targetWireBitMask);
|
58
|
+
await fpgaDataPort.updateWireIns();
|
59
59
|
});
|
60
60
|
}
|
61
|
-
}, [
|
61
|
+
}, [fpgaDataPort, workQueue, fpEndpoint, targetWireBitMask]);
|
62
62
|
|
63
63
|
const onButtonDown = React.useCallback(async (): Promise<void> => {
|
64
|
-
if ((
|
64
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
65
65
|
await workQueue.post(async () => {
|
66
|
-
|
67
|
-
await
|
66
|
+
fpgaDataPort.setWireInValue(fpEndpoint.epAddress, 0xffffffff, targetWireBitMask);
|
67
|
+
await fpgaDataPort.updateWireIns();
|
68
68
|
});
|
69
69
|
}
|
70
|
-
}, [
|
70
|
+
}, [fpgaDataPort, workQueue, fpEndpoint, targetWireBitMask, workQueue]);
|
71
71
|
|
72
72
|
return (
|
73
73
|
<Button
|
74
74
|
{...buttonProps}
|
75
75
|
ref={forwardedRef}
|
76
|
-
disabled={disabled || (
|
76
|
+
disabled={disabled || (fpgaDataPort == null)}
|
77
77
|
onButtonUp={onButtonUp}
|
78
78
|
onButtonDown={onButtonDown}
|
79
79
|
/>
|
@@ -57,9 +57,8 @@ export const Primary: Story = {
|
|
57
57
|
render: (props) => {
|
58
58
|
const { device, workQueue } = useContext(FrontPanelContext);
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
workQueue.Post(async (): Promise<void> => {
|
60
|
+
// Initialize the WireIns with unique values.
|
61
|
+
workQueue?.post(async (): Promise<void> => {
|
63
62
|
let byteId = 0;
|
64
63
|
|
65
64
|
for (let address = 0x0; address < 0x20; address++) {
|
@@ -67,11 +66,10 @@ export const Primary: Story = {
|
|
67
66
|
for (let byteIndex = 1; byteIndex < 4; byteIndex++) {
|
68
67
|
wireValue |= byteId++ << (8 * byteIndex);
|
69
68
|
}
|
70
|
-
|
69
|
+
device?.setWireInValue(address, wireValue, 0xffffffff);
|
71
70
|
}
|
72
71
|
|
73
|
-
await
|
74
|
-
await device.updateWireIns();
|
72
|
+
await device?.updateWireIns();
|
75
73
|
});
|
76
74
|
|
77
75
|
return <FrontPanelRangeSlider {...props} />;
|
@@ -15,7 +15,7 @@ import { FrontPanelContext } from "../../contexts";
|
|
15
15
|
|
16
16
|
import { CalculateBitLength } from "../../core";
|
17
17
|
|
18
|
-
import {
|
18
|
+
import { IFPGADataPortClassic } from "@opalkelly/frontpanel-platform-api";
|
19
19
|
|
20
20
|
type FrontPanelRangeSliderElement = React.ElementRef<typeof RangeSlider>;
|
21
21
|
|
@@ -51,7 +51,7 @@ const FrontPanelRangeSlider = React.forwardRef<
|
|
51
51
|
>((props, forwardedRef) => {
|
52
52
|
const [value, setValue] = React.useState<bigint>(0n);
|
53
53
|
|
54
|
-
const {
|
54
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
55
55
|
|
56
56
|
const { fpEndpoint, maximumValue, disabled, ...rootProps } = props;
|
57
57
|
|
@@ -63,7 +63,7 @@ const FrontPanelRangeSlider = React.forwardRef<
|
|
63
63
|
((1n << BigInt(targetBitLength)) - 1n) << BigInt(fpEndpoint.bitOffset);
|
64
64
|
|
65
65
|
const onUpdateWireValue = React.useCallback(
|
66
|
-
(sender?:
|
66
|
+
(sender?: IFPGADataPortClassic): void => {
|
67
67
|
if ((sender != null) && (workQueue != null)) {
|
68
68
|
const sourceWireValue = sender.getWireInValue(fpEndpoint.epAddress);
|
69
69
|
const sourceValue =
|
@@ -78,29 +78,29 @@ const FrontPanelRangeSlider = React.forwardRef<
|
|
78
78
|
|
79
79
|
const onSelectedValueChangeHandler = React.useCallback(
|
80
80
|
(value: number) => {
|
81
|
-
if ((
|
81
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
82
82
|
workQueue.post(async () => {
|
83
|
-
|
83
|
+
fpgaDataPort.setWireInValue(
|
84
84
|
fpEndpoint.epAddress,
|
85
85
|
value << fpEndpoint.bitOffset,
|
86
86
|
Number(targetWireBitMask)
|
87
87
|
);
|
88
|
-
await
|
88
|
+
await fpgaDataPort.updateWireIns();
|
89
89
|
});
|
90
90
|
}
|
91
91
|
},
|
92
|
-
[
|
92
|
+
[fpgaDataPort, workQueue, fpEndpoint, targetWireBitMask]
|
93
93
|
);
|
94
94
|
|
95
95
|
React.useEffect(() => {
|
96
|
-
onUpdateWireValue(
|
97
|
-
}, [
|
96
|
+
onUpdateWireValue(fpgaDataPort);
|
97
|
+
}, [fpgaDataPort, onUpdateWireValue]);
|
98
98
|
|
99
99
|
return (
|
100
100
|
<RangeSlider
|
101
101
|
{...rootProps}
|
102
102
|
ref={forwardedRef}
|
103
|
-
disabled={disabled || (
|
103
|
+
disabled={disabled || (fpgaDataPort == null)}
|
104
104
|
defaultValue={Number(value)}
|
105
105
|
maximumValue={maximumValue}
|
106
106
|
onValueChange={onSelectedValueChangeHandler}
|
@@ -43,10 +43,8 @@ export const Primary: Story = {
|
|
43
43
|
render: ({ ...args }) => {
|
44
44
|
const { device, workQueue } = useContext(FrontPanelContext);
|
45
45
|
|
46
|
-
const setWireInPromises: Promise<void>[] = [];
|
47
|
-
|
48
46
|
// Initialize the WireIns with unique values.
|
49
|
-
workQueue
|
47
|
+
workQueue?.post(async (): Promise<void> => {
|
50
48
|
let byteId = 0;
|
51
49
|
|
52
50
|
for (let address = 0x0; address < 0x20; address++) {
|
@@ -54,11 +52,10 @@ export const Primary: Story = {
|
|
54
52
|
for (let byteIndex = 1; byteIndex < 4; byteIndex++) {
|
55
53
|
wireValue |= byteId++ << (8 * byteIndex);
|
56
54
|
}
|
57
|
-
|
55
|
+
device?.setWireInValue(address, wireValue, 0xffffffff);
|
58
56
|
}
|
59
57
|
|
60
|
-
await
|
61
|
-
await device.updateWireIns();
|
58
|
+
await device?.updateWireIns();
|
62
59
|
});
|
63
60
|
|
64
61
|
const { maximumValue, ...props } = args;
|
@@ -15,7 +15,7 @@ import { FrontPanelContext } from "../../contexts";
|
|
15
15
|
|
16
16
|
import { CalculateBitLength } from "../../core";
|
17
17
|
|
18
|
-
import {
|
18
|
+
import { IFPGADataPortClassic, WIREIN_ADDRESS_RANGE } from "@opalkelly/frontpanel-platform-api";
|
19
19
|
|
20
20
|
interface FrontPanelSelectEntryRootCombinedProps
|
21
21
|
extends React.ComponentPropsWithoutRef<typeof SelectEntry.Root>,
|
@@ -55,7 +55,7 @@ export type { FrontPanelSelectEntryRootCombinedProps };
|
|
55
55
|
const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps> = (props) => {
|
56
56
|
const [value, setValue] = React.useState<bigint>(0n);
|
57
57
|
|
58
|
-
const {
|
58
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
59
59
|
|
60
60
|
const { fpEndpoint, maximumValue, disabled, ...rootProps } = props;
|
61
61
|
|
@@ -67,7 +67,7 @@ const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps
|
|
67
67
|
((1n << BigInt(targetBitLength)) - 1n) << BigInt(fpEndpoint.bitOffset);
|
68
68
|
|
69
69
|
const onUpdateWireValue = React.useCallback(
|
70
|
-
(sender?:
|
70
|
+
(sender?: IFPGADataPortClassic): void => {
|
71
71
|
if ((sender != null) && (workQueue != null)) {
|
72
72
|
// Get the wire value for the endpoint
|
73
73
|
let sourceWireValue = sender.getWireInValue(fpEndpoint.epAddress);
|
@@ -108,7 +108,7 @@ const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps
|
|
108
108
|
|
109
109
|
const onSelectedValueChangeHandler = React.useCallback(
|
110
110
|
(value: string) => {
|
111
|
-
if ((
|
111
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
112
112
|
const targetWireSpanValue = BigInt(value);
|
113
113
|
workQueue.post(async () => {
|
114
114
|
let targetWireBitMask = targetWireSpanBitMask & 0xffffffffn;
|
@@ -117,7 +117,7 @@ const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps
|
|
117
117
|
);
|
118
118
|
|
119
119
|
// Set the wire value for the endpoint
|
120
|
-
|
120
|
+
fpgaDataPort.setWireInValue(
|
121
121
|
fpEndpoint.epAddress,
|
122
122
|
targetWireValue,
|
123
123
|
Number(targetWireBitMask)
|
@@ -142,7 +142,7 @@ const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps
|
|
142
142
|
);
|
143
143
|
|
144
144
|
// Set the wire value for the next endpoint
|
145
|
-
|
145
|
+
fpgaDataPort.setWireInValue(
|
146
146
|
fpEndpoint.epAddress + wireIndex,
|
147
147
|
targetWireValue,
|
148
148
|
Number(targetWireBitMask)
|
@@ -153,23 +153,23 @@ const FrontPanelSelectEntryRoot: React.FC<FrontPanelSelectEntryRootCombinedProps
|
|
153
153
|
}
|
154
154
|
}
|
155
155
|
|
156
|
-
await
|
156
|
+
await fpgaDataPort.updateWireIns();
|
157
157
|
});
|
158
158
|
}
|
159
159
|
|
160
|
-
onUpdateWireValue(
|
160
|
+
onUpdateWireValue(fpgaDataPort);
|
161
161
|
},
|
162
|
-
[
|
162
|
+
[fpgaDataPort, workQueue, fpEndpoint, onUpdateWireValue]
|
163
163
|
);
|
164
164
|
|
165
165
|
React.useEffect(() => {
|
166
|
-
onUpdateWireValue(
|
167
|
-
}, [
|
166
|
+
onUpdateWireValue(fpgaDataPort);
|
167
|
+
}, [fpgaDataPort, onUpdateWireValue]);
|
168
168
|
|
169
169
|
return (
|
170
170
|
<SelectEntry.Root
|
171
171
|
{...rootProps}
|
172
|
-
disabled={disabled || (
|
172
|
+
disabled={disabled || (fpgaDataPort == null)}
|
173
173
|
value={value.toString()}
|
174
174
|
onValueChange={onSelectedValueChangeHandler}
|
175
175
|
/>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
import React from "react";
|
9
9
|
|
10
|
-
import {
|
10
|
+
import { IFPGADataPortClassic, WireValue } from "@opalkelly/frontpanel-platform-api";
|
11
11
|
|
12
12
|
import { ToggleState } from "../../core";
|
13
13
|
|
@@ -51,14 +51,14 @@ const FrontPanelToggleSwitch = React.forwardRef<
|
|
51
51
|
>((props, forwardedRef) => {
|
52
52
|
const [state, setState] = React.useState<ToggleState>(ToggleState.Off);
|
53
53
|
|
54
|
-
const {
|
54
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
55
55
|
|
56
56
|
const { fpEndpoint, disabled, ...buttonProps } = props;
|
57
57
|
|
58
58
|
const targetWireBitMask = 1 << fpEndpoint.bitOffset;
|
59
59
|
|
60
60
|
const onUpdateWireValue = React.useCallback(
|
61
|
-
(sender?:
|
61
|
+
(sender?: IFPGADataPortClassic): void => {
|
62
62
|
if ((sender != null) && (workQueue != null)) {
|
63
63
|
// Set the toggle state based on the value of the target bit of the Wire endpoint
|
64
64
|
const sourceWireValue = sender.getWireInValue(fpEndpoint.epAddress);
|
@@ -74,31 +74,31 @@ const FrontPanelToggleSwitch = React.forwardRef<
|
|
74
74
|
|
75
75
|
const onToggleStateChanged = React.useCallback(
|
76
76
|
async (state: ToggleState): Promise<void> => {
|
77
|
-
if ((
|
77
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
78
78
|
await workQueue.post(async () => {
|
79
79
|
// Set the value of the target bit of the Wire endpoint based on the toggle state
|
80
80
|
const targetWireValue: WireValue = state === ToggleState.On ? 0xffffffff : 0;
|
81
81
|
|
82
|
-
|
82
|
+
fpgaDataPort.setWireInValue(fpEndpoint.epAddress, targetWireValue, targetWireBitMask);
|
83
83
|
|
84
|
-
await
|
84
|
+
await fpgaDataPort.updateWireIns();
|
85
85
|
});
|
86
86
|
}
|
87
87
|
|
88
|
-
onUpdateWireValue(
|
88
|
+
onUpdateWireValue(fpgaDataPort);
|
89
89
|
},
|
90
|
-
[
|
90
|
+
[fpgaDataPort, workQueue, fpEndpoint, targetWireBitMask]
|
91
91
|
);
|
92
92
|
|
93
93
|
React.useEffect(() => {
|
94
|
-
onUpdateWireValue(
|
95
|
-
}, [
|
94
|
+
onUpdateWireValue(fpgaDataPort);
|
95
|
+
}, [fpgaDataPort, onUpdateWireValue]);
|
96
96
|
|
97
97
|
return (
|
98
98
|
<ToggleSwitch
|
99
99
|
ref={forwardedRef}
|
100
100
|
{...buttonProps}
|
101
|
-
disabled={disabled || (
|
101
|
+
disabled={disabled || (fpgaDataPort == null)}
|
102
102
|
state={state}
|
103
103
|
onToggleStateChanged={onToggleStateChanged}
|
104
104
|
/>
|
@@ -47,23 +47,23 @@ const FrontPanelTriggerButton = React.forwardRef<
|
|
47
47
|
FrontPanelTriggerButtonElement,
|
48
48
|
FrontPanelTriggerButtonCombinedProps
|
49
49
|
>((props, forwardedRef) => {
|
50
|
-
const {
|
50
|
+
const { fpgaDataPort, workQueue } = React.useContext(FrontPanelContext);
|
51
51
|
|
52
52
|
const { fpEndpoint, disabled, ...buttonProps } = props;
|
53
53
|
|
54
54
|
const onButtonDown = React.useCallback(async (): Promise<void> => {
|
55
|
-
if ((
|
55
|
+
if ((fpgaDataPort != null) && (workQueue != null)) {
|
56
56
|
await workQueue.post(async () => {
|
57
|
-
await
|
57
|
+
await fpgaDataPort.activateTriggerIn(fpEndpoint.epAddress, fpEndpoint.bitOffset);
|
58
58
|
});
|
59
59
|
}
|
60
|
-
}, [
|
60
|
+
}, [fpgaDataPort, workQueue, fpEndpoint]);
|
61
61
|
|
62
62
|
return (
|
63
63
|
<Button
|
64
64
|
{...buttonProps}
|
65
65
|
ref={forwardedRef}
|
66
|
-
disabled={disabled || (
|
66
|
+
disabled={disabled || (fpgaDataPort == null)}
|
67
67
|
onButtonDown={onButtonDown}
|
68
68
|
/>
|
69
69
|
);
|
@@ -8,15 +8,15 @@
|
|
8
8
|
import React from "react";
|
9
9
|
|
10
10
|
import {
|
11
|
-
|
12
|
-
|
11
|
+
IFPGADataPortClassic,
|
12
|
+
IFPGADataPortClassicEventSource,
|
13
13
|
WorkQueue
|
14
14
|
} from "@opalkelly/frontpanel-platform-api";
|
15
15
|
|
16
16
|
export type FrontPanelContextValue = {
|
17
|
-
|
17
|
+
fpgaDataPort?: IFPGADataPortClassic;
|
18
18
|
workQueue?: WorkQueue;
|
19
|
-
eventSource?:
|
19
|
+
eventSource?: IFPGADataPortClassicEventSource;
|
20
20
|
};
|
21
21
|
|
22
22
|
const FrontPanelContext = React.createContext<FrontPanelContextValue>({});
|