perf(timer): perf
This commit is contained in:
@@ -48,7 +48,11 @@ import { useDescToolsStore } from "./useDescToolsStore"
|
|||||||
import { useKeyboardStore } from "./useKeyBoardStore"
|
import { useKeyboardStore } from "./useKeyBoardStore"
|
||||||
import { usePaperStore } from "./usePaperStore"
|
import { usePaperStore } from "./usePaperStore"
|
||||||
import { useRightToolsStore } from "./useRightToolsStore"
|
import { useRightToolsStore } from "./useRightToolsStore"
|
||||||
import { useIntervalStore, useTimerStore } from "./useTimerStore"
|
import {
|
||||||
|
useIntervalStore,
|
||||||
|
useLabelTimeStore,
|
||||||
|
useTimerStore,
|
||||||
|
} from "./useTimerStore"
|
||||||
import { useTopToolsStore } from "./useTopToolsStore"
|
import { useTopToolsStore } from "./useTopToolsStore"
|
||||||
import { findGroupKey } from "./util"
|
import { findGroupKey } from "./util"
|
||||||
import { safeClone } from "./utils/clone"
|
import { safeClone } from "./utils/clone"
|
||||||
@@ -157,19 +161,20 @@ const LabelPage = ({
|
|||||||
// Project.LabelSchemaList[]
|
// Project.LabelSchemaList[]
|
||||||
// >([]);
|
// >([]);
|
||||||
const topRef = useRef<any>(null)
|
const topRef = useRef<any>(null)
|
||||||
|
const autoSaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||||
|
const autoSaveInProgressRef = useRef(false)
|
||||||
const paperContainerRef = useRef<any>(null)
|
const paperContainerRef = useRef<any>(null)
|
||||||
const qaToolContainerRef = useRef<any>(null)
|
const qaToolContainerRef = useRef<any>(null)
|
||||||
const [isConfirmSave, setIsConfirmSave] = useState(false)
|
const [isConfirmSave, setIsConfirmSave] = useState(false)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [sizes, setSizes] = useState<number[]>([])
|
const [sizes, setSizes] = useState<number[]>([])
|
||||||
|
|
||||||
const {
|
const labelData = useLabelStore((state) => state.label)
|
||||||
label: labelData,
|
const setLabel = useLabelStore((state) => state.setLabel)
|
||||||
setLabel,
|
const setStateStack = useLabelStore((state) => state.setStateStack)
|
||||||
setStateStack,
|
const setLabelTime = useLabelTimeStore((state) => state.setLabelTime)
|
||||||
setLabelTime,
|
const isAutoSave = useIntervalStore((state) => state.isAutoSave)
|
||||||
} = useLabelStore()
|
const autoSaveGap = useIntervalStore((state) => state.autoSaveGap)
|
||||||
const { isAutoSave, autoSaveGap } = useIntervalStore()
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
editMode,
|
editMode,
|
||||||
@@ -1310,17 +1315,40 @@ const LabelPage = ({
|
|||||||
|
|
||||||
// auto save
|
// auto save
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAutoSave && !isView) {
|
let cancelled = false
|
||||||
const minute = 60 * 1000
|
if (autoSaveTimerRef.current !== null) {
|
||||||
useIntervalStore.getState().startTimer(() => {
|
clearTimeout(autoSaveTimerRef.current)
|
||||||
topRef.current.handleSave()
|
autoSaveTimerRef.current = null
|
||||||
}, autoSaveGap * minute)
|
|
||||||
} else {
|
|
||||||
useIntervalStore.getState().clearTimer()
|
|
||||||
}
|
}
|
||||||
|
if (!isAutoSave || isView) return
|
||||||
|
|
||||||
|
const minute = 60 * 1000
|
||||||
|
const delay = autoSaveGap * minute
|
||||||
|
const scheduleNext = () => {
|
||||||
|
autoSaveTimerRef.current = setTimeout(async () => {
|
||||||
|
if (cancelled) return
|
||||||
|
if (autoSaveInProgressRef.current) {
|
||||||
|
scheduleNext()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
autoSaveInProgressRef.current = true
|
||||||
|
try {
|
||||||
|
await topRef.current?.handleSave?.()
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[LabelNossr] auto save failed", error)
|
||||||
|
} finally {
|
||||||
|
autoSaveInProgressRef.current = false
|
||||||
|
if (!cancelled) scheduleNext()
|
||||||
|
}
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
scheduleNext()
|
||||||
return () => {
|
return () => {
|
||||||
useIntervalStore.getState().clearTimer()
|
cancelled = true
|
||||||
|
if (autoSaveTimerRef.current !== null) {
|
||||||
|
clearTimeout(autoSaveTimerRef.current)
|
||||||
|
autoSaveTimerRef.current = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [autoSaveGap, isAutoSave, isView])
|
}, [autoSaveGap, isAutoSave, isView])
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import { useDescToolsStore } from "../useDescToolsStore"
|
|||||||
import { useKeyboardStore } from "../useKeyBoardStore"
|
import { useKeyboardStore } from "../useKeyBoardStore"
|
||||||
import { useOtherToolsStore } from "../useOtherToolsStore"
|
import { useOtherToolsStore } from "../useOtherToolsStore"
|
||||||
import { usePaperStore } from "../usePaperStore"
|
import { usePaperStore } from "../usePaperStore"
|
||||||
|
import { useLabelTimeStore } from "../useTimerStore"
|
||||||
import { useTopToolsStore } from "../useTopToolsStore"
|
import { useTopToolsStore } from "../useTopToolsStore"
|
||||||
import { getSubAttrStatus } from "../util"
|
import { getSubAttrStatus } from "../util"
|
||||||
import { safeClone } from "../utils/clone"
|
import { safeClone } from "../utils/clone"
|
||||||
@@ -50,7 +51,9 @@ const BottomTools: React.FC<BottomToolsComponentProps> = (props) => {
|
|||||||
|
|
||||||
const itemRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
const itemRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
||||||
|
|
||||||
const { label: storeLabel, setLabel, pushStateStack } = useLabelStore()
|
const storeLabel = useLabelStore((state) => state.label)
|
||||||
|
const setLabel = useLabelStore((state) => state.setLabel)
|
||||||
|
const pushStateStack = useLabelStore((state) => state.pushStateStack)
|
||||||
const {
|
const {
|
||||||
inputNumber,
|
inputNumber,
|
||||||
setInputNumber,
|
setInputNumber,
|
||||||
@@ -521,17 +524,16 @@ const BottomTools: React.FC<BottomToolsComponentProps> = (props) => {
|
|||||||
review2_uid: 0,
|
review2_uid: 0,
|
||||||
}
|
}
|
||||||
data.key_frame = true
|
data.key_frame = true
|
||||||
|
const currentLabelTime =
|
||||||
|
useLabelTimeStore.getState().labelTime
|
||||||
if (taskDetail.label_status === 2) {
|
if (taskDetail.label_status === 2) {
|
||||||
data.label1_ts =
|
data.label1_ts = currentLabelTime.label
|
||||||
useLabelStore.getState().labelTime.label
|
|
||||||
data.label1_uid = usePermissionStore.getState().user_id
|
data.label1_uid = usePermissionStore.getState().user_id
|
||||||
} else if (taskDetail.label_status === 4) {
|
} else if (taskDetail.label_status === 4) {
|
||||||
data.review1_ts =
|
data.review1_ts = currentLabelTime.review1
|
||||||
useLabelStore.getState().labelTime.review1
|
|
||||||
data.review1_uid = usePermissionStore.getState().user_id
|
data.review1_uid = usePermissionStore.getState().user_id
|
||||||
} else if (taskDetail.label_status === 6) {
|
} else if (taskDetail.label_status === 6) {
|
||||||
data.review2_ts =
|
data.review2_ts = currentLabelTime.review2
|
||||||
useLabelStore.getState().labelTime.review2
|
|
||||||
data.review2_uid = usePermissionStore.getState().user_id
|
data.review2_uid = usePermissionStore.getState().user_id
|
||||||
}
|
}
|
||||||
setKeyFrameData(activeImage, data)
|
setKeyFrameData(activeImage, data)
|
||||||
|
|||||||
@@ -159,12 +159,12 @@ const PaperContainer = (
|
|||||||
|
|
||||||
const { activeImage } = useBottomToolsStore()
|
const { activeImage } = useBottomToolsStore()
|
||||||
|
|
||||||
const {
|
const storeLabel = useLabelStore((state) => state.label)
|
||||||
label: storeLabel,
|
const deleteOperation = useLabelStore((state) => state.deleteOperation)
|
||||||
deleteOperation,
|
const setOperation = useLabelStore((state) => state.setOperation)
|
||||||
setOperation,
|
const getLabelDetailDataByKeys = useLabelStore(
|
||||||
getLabelDetailDataByKeys,
|
(state) => state.getLabelDetailDataByKeys
|
||||||
} = useLabelStore()
|
)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
objectOperations,
|
objectOperations,
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ const RightGroupTools: React.FC<RightGroupToolsComponentProps> = (props) => {
|
|||||||
},
|
},
|
||||||
[projectDetail?.label_schema_list]
|
[projectDetail?.label_schema_list]
|
||||||
)
|
)
|
||||||
const { setLabel, pushStateStack } = useLabelStore()
|
const setLabel = useLabelStore((state) => state.setLabel)
|
||||||
|
const pushStateStack = useLabelStore((state) => state.pushStateStack)
|
||||||
const { pathGroupMap, groupPathVisible, setGroupPathVisible } =
|
const { pathGroupMap, groupPathVisible, setGroupPathVisible } =
|
||||||
useRightToolsStore()
|
useRightToolsStore()
|
||||||
const { activeImage } = useBottomToolsStore()
|
const { activeImage } = useBottomToolsStore()
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export const renderOperationIcon = (
|
|||||||
const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
||||||
const { labelState, projectDetail, taskDetail } = props
|
const { labelState, projectDetail, taskDetail } = props
|
||||||
|
|
||||||
const { label: storeLabel } = useLabelStore()
|
const storeLabel = useLabelStore((state) => state.label)
|
||||||
|
|
||||||
const { activeImage } = useBottomToolsStore()
|
const { activeImage } = useBottomToolsStore()
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ import { useBottomToolsStore } from "../useBottomToolsStore"
|
|||||||
import { useDescToolsStore } from "../useDescToolsStore"
|
import { useDescToolsStore } from "../useDescToolsStore"
|
||||||
import { usePaperStore } from "../usePaperStore"
|
import { usePaperStore } from "../usePaperStore"
|
||||||
import { useRightToolsStore } from "../useRightToolsStore"
|
import { useRightToolsStore } from "../useRightToolsStore"
|
||||||
import { useIntervalStore } from "../useTimerStore"
|
import { useIntervalStore, useLabelTimeStore } from "../useTimerStore"
|
||||||
import { useTopToolsStore } from "../useTopToolsStore"
|
import { useTopToolsStore } from "../useTopToolsStore"
|
||||||
import { getSubAttrStatus } from "../util"
|
import { getSubAttrStatus } from "../util"
|
||||||
import { labelTypeMap, TaskStatusEnum } from "../utils/constants"
|
import { labelTypeMap, TaskStatusEnum } from "../utils/constants"
|
||||||
@@ -133,6 +133,17 @@ const initialWorkLoad: WorkLoad = {
|
|||||||
question_size: {},
|
question_size: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TaskTimerDisplay = ({
|
||||||
|
currentTimeKey,
|
||||||
|
}: {
|
||||||
|
currentTimeKey: "label" | "review1" | "review2"
|
||||||
|
}) => {
|
||||||
|
const currentTime = useLabelTimeStore(
|
||||||
|
(state) => state.labelTime[currentTimeKey]
|
||||||
|
)
|
||||||
|
return <>{dayjs.duration(currentTime, "seconds").format("HH:mm:ss")}</>
|
||||||
|
}
|
||||||
|
|
||||||
const TopTools = (
|
const TopTools = (
|
||||||
props: TopToolsComponentProps,
|
props: TopToolsComponentProps,
|
||||||
ref: React.Ref<unknown> | undefined
|
ref: React.Ref<unknown> | undefined
|
||||||
@@ -157,13 +168,10 @@ const TopTools = (
|
|||||||
const [duplicateName, setDuplicateName] = useState("")
|
const [duplicateName, setDuplicateName] = useState("")
|
||||||
const [recoverOpen, setRecoverOpen] = useState(false)
|
const [recoverOpen, setRecoverOpen] = useState(false)
|
||||||
const [taskOpen, setTaskOpen] = useState(false)
|
const [taskOpen, setTaskOpen] = useState(false)
|
||||||
const {
|
const labelData = useLabelStore((state) => state.label)
|
||||||
label: labelData,
|
const setLabel = useLabelStore((state) => state.setLabel)
|
||||||
setLabel,
|
const pushStateStack = useLabelStore((state) => state.pushStateStack)
|
||||||
labelTime,
|
const setLabelTime = useLabelTimeStore((state) => state.setLabelTime)
|
||||||
setLabelTime,
|
|
||||||
pushStateStack,
|
|
||||||
} = useLabelStore()
|
|
||||||
const { activeImage } = useBottomToolsStore()
|
const { activeImage } = useBottomToolsStore()
|
||||||
const {
|
const {
|
||||||
isView,
|
isView,
|
||||||
@@ -212,8 +220,10 @@ const TopTools = (
|
|||||||
} = useTopToolsStore()
|
} = useTopToolsStore()
|
||||||
|
|
||||||
const { pathGroupMap } = useRightToolsStore()
|
const { pathGroupMap } = useRightToolsStore()
|
||||||
const { isAutoSave, setIsAutoSave, autoSaveGap, setAutoSaveGap } =
|
const isAutoSave = useIntervalStore((state) => state.isAutoSave)
|
||||||
useIntervalStore()
|
const setIsAutoSave = useIntervalStore((state) => state.setIsAutoSave)
|
||||||
|
const autoSaveGap = useIntervalStore((state) => state.autoSaveGap)
|
||||||
|
const setAutoSaveGap = useIntervalStore((state) => state.setAutoSaveGap)
|
||||||
|
|
||||||
// 当前是否可以操作功能按键
|
// 当前是否可以操作功能按键
|
||||||
const currentEditAuth = useMemo(() => {
|
const currentEditAuth = useMemo(() => {
|
||||||
@@ -723,10 +733,11 @@ const TopTools = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentLabelTime = useLabelTimeStore.getState().labelTime
|
||||||
const workTime = {
|
const workTime = {
|
||||||
label_work_time: labelTime.label,
|
label_work_time: currentLabelTime.label,
|
||||||
first_review_work_time: labelTime.review1,
|
first_review_work_time: currentLabelTime.review1,
|
||||||
second_review_work_time: labelTime.review2,
|
second_review_work_time: currentLabelTime.review2,
|
||||||
}
|
}
|
||||||
// 生成新workload
|
// 生成新workload
|
||||||
let time = 0
|
let time = 0
|
||||||
@@ -851,9 +862,6 @@ const TopTools = (
|
|||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
labelCategories,
|
labelCategories,
|
||||||
labelTime.label,
|
|
||||||
labelTime.review1,
|
|
||||||
labelTime.review2,
|
|
||||||
oldWorkLoad,
|
oldWorkLoad,
|
||||||
pathGroupMap,
|
pathGroupMap,
|
||||||
projectDetail,
|
projectDetail,
|
||||||
@@ -1257,22 +1265,23 @@ const TopTools = (
|
|||||||
console.log(error)
|
console.log(error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const currentLabelTime = useLabelTimeStore.getState().labelTime
|
||||||
const handleAction = (current_status: number) => {
|
const handleAction = (current_status: number) => {
|
||||||
switch (current_status) {
|
switch (current_status) {
|
||||||
case 2:
|
case 2:
|
||||||
return {
|
return {
|
||||||
commit_action: key || 1,
|
commit_action: key || 1,
|
||||||
work_time: labelTime.label,
|
work_time: currentLabelTime.label,
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
return {
|
return {
|
||||||
commit_action: key || 2,
|
commit_action: key || 2,
|
||||||
work_time: labelTime.review1,
|
work_time: currentLabelTime.review1,
|
||||||
}
|
}
|
||||||
case 6:
|
case 6:
|
||||||
return {
|
return {
|
||||||
commit_action: key || 3,
|
commit_action: key || 3,
|
||||||
work_time: labelTime.review2,
|
work_time: currentLabelTime.review2,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
@@ -1345,15 +1354,15 @@ const TopTools = (
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let timer = setInterval(() => {
|
let timer = setInterval(() => {
|
||||||
if (isView) return
|
if (isView) return
|
||||||
setLabelTime({
|
setLabelTime((prev) => ({
|
||||||
...labelTime,
|
...prev,
|
||||||
[currentTimeKey]: labelTime[currentTimeKey] + 1,
|
[currentTimeKey]: prev[currentTimeKey] + 1,
|
||||||
})
|
}))
|
||||||
}, 1000)
|
}, 1000)
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
}
|
}
|
||||||
}, [currentTimeKey, isView, labelTime, setLabelTime])
|
}, [currentTimeKey, isView, setLabelTime])
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
@@ -1748,9 +1757,7 @@ const TopTools = (
|
|||||||
{isLabelTask && (
|
{isLabelTask && (
|
||||||
<Flex justify="space-between" align="center" gap="md" px="md">
|
<Flex justify="space-between" align="center" gap="md" px="md">
|
||||||
<Timer style={{ width: 20, height: 20 }} />
|
<Timer style={{ width: 20, height: 20 }} />
|
||||||
{dayjs
|
<TaskTimerDisplay currentTimeKey={currentTimeKey} />
|
||||||
.duration(labelTime[currentTimeKey], "seconds")
|
|
||||||
.format("HH:mm:ss")}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
<Flex justify="flex-end" align="center" gap="md" px="0" flex={1}>
|
<Flex justify="flex-end" align="center" gap="md" px="0" flex={1}>
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import { safeClone } from "./utils/clone"
|
|||||||
|
|
||||||
type LabelData = Map<string, Map<string, [number, any[], any, any[]][]>>
|
type LabelData = Map<string, Map<string, [number, any[], any, any[]][]>>
|
||||||
type LabelPathTuple = [number, any[], any, any[]]
|
type LabelPathTuple = [number, any[], any, any[]]
|
||||||
|
type LabelTime = {
|
||||||
|
label: number
|
||||||
|
review1: number
|
||||||
|
review2: number
|
||||||
|
}
|
||||||
|
|
||||||
const isPaperPointLike = (value: any) => {
|
const isPaperPointLike = (value: any) => {
|
||||||
return (
|
return (
|
||||||
@@ -53,11 +58,7 @@ const normalizeLabelPathTuple = (path: LabelPathTuple): LabelPathTuple => {
|
|||||||
interface LabelState {
|
interface LabelState {
|
||||||
// pathId pathPoints detail hollowPathPoints
|
// pathId pathPoints detail hollowPathPoints
|
||||||
label: LabelData
|
label: LabelData
|
||||||
labelTime: {
|
labelTime: LabelTime
|
||||||
label: number
|
|
||||||
review1: number
|
|
||||||
review2: number
|
|
||||||
}
|
|
||||||
labelDefaultComments: Comment[]
|
labelDefaultComments: Comment[]
|
||||||
setLabel: (label: LabelData) => void
|
setLabel: (label: LabelData) => void
|
||||||
stateStack: LabelData[]
|
stateStack: LabelData[]
|
||||||
@@ -83,11 +84,9 @@ interface LabelState {
|
|||||||
[keys: string]: any
|
[keys: string]: any
|
||||||
}
|
}
|
||||||
) => void
|
) => void
|
||||||
setLabelTime: (labelTime: {
|
setLabelTime: (
|
||||||
label: number
|
labelTime: LabelTime | ((prev: LabelTime) => LabelTime)
|
||||||
review1: number
|
) => void
|
||||||
review2: number
|
|
||||||
}) => void
|
|
||||||
setLabelDefaultComments: (arr: Comment[]) => void
|
setLabelDefaultComments: (arr: Comment[]) => void
|
||||||
setImage: (
|
setImage: (
|
||||||
imageId: string,
|
imageId: string,
|
||||||
@@ -312,7 +311,10 @@ export const useLabelStore = create(
|
|||||||
storeSet((state) => {
|
storeSet((state) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
labelTime,
|
labelTime:
|
||||||
|
typeof labelTime === "function"
|
||||||
|
? labelTime(state.labelTime)
|
||||||
|
: labelTime,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
setLabelDefaultComments: (labelDefaultComments) =>
|
setLabelDefaultComments: (labelDefaultComments) =>
|
||||||
|
|||||||
@@ -65,3 +65,40 @@ export const useIntervalStore = create<IntervalStore>((set, get) => ({
|
|||||||
set((state) => ({ ...state, autoSaveGap: value }))
|
set((state) => ({ ...state, autoSaveGap: value }))
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
export interface LabelTimeState {
|
||||||
|
label: number
|
||||||
|
review1: number
|
||||||
|
review2: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LabelTimeStore {
|
||||||
|
labelTime: LabelTimeState
|
||||||
|
setLabelTime: (
|
||||||
|
labelTime: LabelTimeState | ((prev: LabelTimeState) => LabelTimeState)
|
||||||
|
) => void
|
||||||
|
resetLabelTime: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialLabelTimeState: LabelTimeState = {
|
||||||
|
label: 0,
|
||||||
|
review1: 0,
|
||||||
|
review2: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useLabelTimeStore = create<LabelTimeStore>((set) => ({
|
||||||
|
labelTime: initialLabelTimeState,
|
||||||
|
setLabelTime: (labelTime) =>
|
||||||
|
set((state) => ({
|
||||||
|
...state,
|
||||||
|
labelTime:
|
||||||
|
typeof labelTime === "function"
|
||||||
|
? labelTime(state.labelTime)
|
||||||
|
: labelTime,
|
||||||
|
})),
|
||||||
|
resetLabelTime: () =>
|
||||||
|
set((state) => ({
|
||||||
|
...state,
|
||||||
|
labelTime: initialLabelTimeState,
|
||||||
|
})),
|
||||||
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user