feat: optimize segment

This commit is contained in:
alivender 2025-05-20 16:25:02 +08:00
parent 09b8f676ba
commit b6d8612e8c
1 changed files with 65 additions and 57 deletions

View File

@ -78,7 +78,8 @@ const pinRefs = ref<Record<string, any>>({});
interface SevenSegmentDisplayProps { interface SevenSegmentDisplayProps {
size?: number; size?: number;
color?: string; color?: string;
AFTERGLOW_DURATION?: number; // AFTERGLOW_BUFFER_SIZE?: number; //
AFTERGLOW_UPDATE_INTERVAL?: number; //
pins?: { pins?: {
pinId: string; pinId: string;
constraint: string; constraint: string;
@ -91,6 +92,8 @@ interface SevenSegmentDisplayProps {
const props = withDefaults(defineProps<SevenSegmentDisplayProps>(), { const props = withDefaults(defineProps<SevenSegmentDisplayProps>(), {
size: 1, size: 1,
color: "red", color: "red",
AFTERGLOW_BUFFER_SIZE: 1, // 100
AFTERGLOW_UPDATE_INTERVAL: 1, // 2
cathodeType: "common", // cathodeType: "common", //
pins: () => [ pins: () => [
{ pinId: "a", constraint: "", x: 10, y: 170 }, // a { pinId: "a", constraint: "", x: 10, y: 170 }, // a
@ -122,7 +125,7 @@ watch(
{ deep: true }, { deep: true },
); );
// //
const segmentStates = ref({ const segmentStates = ref({
a: false, a: false,
b: false, b: false,
@ -134,26 +137,26 @@ const segmentStates = ref({
dp: false, dp: false,
}); });
// // -
const afterglowStates = ref({ const afterglowBuffers = ref<Record<string, boolean[]>>({
a: false, a: [],
b: false, b: [],
c: false, c: [],
d: false, d: [],
e: false, e: [],
f: false, f: [],
g: false, g: [],
dp: false, dp: [],
}); });
// //
const afterglowTimers = ref<Record<string, number>>({}); let updateIntervalTimer: number | null = null;
// // - true
function isSegmentActive( function isSegmentActive(
segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp", segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp",
): boolean { ): boolean {
return segmentStates.value[segment] || afterglowStates.value[segment]; return segmentStates.value[segment] || afterglowBuffers.value[segment].some(state => state);
} }
// //
@ -170,17 +173,16 @@ function updateSegmentStates() {
// //
} }
// COM
if (comActive) {
updateAfterglowBuffers();
}
for (const pin of props.pins) { for (const pin of props.pins) {
if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) { if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) {
// COM
if (!comActive) {
handleSegmentStateChange(pin.pinId, false);
continue;
}
// constraint // constraint
if (!pin.constraint) { if (!pin.constraint) {
handleSegmentStateChange(pin.pinId, false); segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = false;
continue; continue;
} }
@ -193,63 +195,69 @@ function updateSegmentStates() {
// : // :
newState = pinState === "low"; newState = pinState === "low";
} }
handleSegmentStateChange(pin.pinId, newState);
//
segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState && comActive;
} }
} }
} }
// // -
function handleSegmentStateChange(segmentId: string, newState: boolean) { function updateAfterglowBuffers() {
const typedSegmentId = segmentId as keyof typeof segmentStates.value; for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
const currentState = segmentStates.value[typedSegmentId]; const typedSegmentId = segmentId as keyof typeof segmentStates.value;
const currentState = segmentStates.value[typedSegmentId];
//
segmentStates.value[typedSegmentId] = newState; //
afterglowBuffers.value[segmentId].unshift(currentState);
//
if (currentState && !newState) { //
// if (afterglowBuffers.value[segmentId].length > props.AFTERGLOW_BUFFER_SIZE) {
if (afterglowTimers.value[segmentId]) { afterglowBuffers.value[segmentId].pop();
window.clearTimeout(afterglowTimers.value[segmentId]);
} }
afterglowStates.value[typedSegmentId] = true; }
afterglowTimers.value[segmentId] = window.setTimeout(() => { }
afterglowStates.value[typedSegmentId] = false;
delete afterglowTimers.value[segmentId]; //
}, props.AFTERGLOW_DURATION ?? 700); function startAfterglowUpdates() {
} else if (newState) { if (updateIntervalTimer) return;
//
if (afterglowTimers.value[segmentId]) { updateIntervalTimer = window.setInterval(() => {
window.clearTimeout(afterglowTimers.value[segmentId]); updateSegmentStates();
delete afterglowTimers.value[segmentId]; }, props.AFTERGLOW_UPDATE_INTERVAL);
} }
afterglowStates.value[typedSegmentId] = false;
//
function stopAfterglowUpdates() {
if (updateIntervalTimer) {
window.clearInterval(updateIntervalTimer);
updateIntervalTimer = null;
} }
} }
// //
function onConstraintChange(constraint: string, level: string) { function onConstraintChange(constraint: string, level: string) {
const affectedPin = props.pins.find((pin) => pin.constraint === constraint); const affectedPin = props.pins.find((pin) => pin.constraint === constraint);
if ( if (affectedPin) {
affectedPin &&
["a", "b", "c", "d", "e", "f", "g", "dp"].includes(affectedPin.pinId)
) {
updateSegmentStates(); updateSegmentStates();
} }
} }
// //
onMounted(() => { onMounted(() => {
//
for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
afterglowBuffers.value[segmentId] = Array(props.AFTERGLOW_BUFFER_SIZE).fill(false);
}
updateSegmentStates(); updateSegmentStates();
onConstraintStateChange(onConstraintChange); onConstraintStateChange(onConstraintChange);
startAfterglowUpdates();
}); });
onUnmounted(() => { onUnmounted(() => {
// //
// stopAfterglowUpdates();
Object.values(afterglowTimers.value).forEach(timerId => {
if (timerId) window.clearTimeout(timerId);
});
}); });
// //