integerated product context to scene context
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useProductContext } from "../../../modules/simulation/products/productContext";
|
||||
import { useCompareProductDataStore, useLoadingProgress, useSaveVersion } from "../../../store/builder/store";
|
||||
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
@@ -16,17 +15,15 @@ function ComparisonScene() {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { versionHistory, selectedVersion, setSelectedVersion, setVersions } = versionStore();
|
||||
const { products } = productStore();
|
||||
const { products, selectedProduct } = productStore();
|
||||
const { isVersionSaved } = useSaveVersion();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||
const { mainProduct } = useMainProduct();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const { compareProductsData } = useCompareProductDataStore();
|
||||
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
|
||||
const { projectId } = useParams()
|
||||
const { projectId } = useParams();
|
||||
|
||||
const handleSelectVersion = (option: string) => {
|
||||
const version = versionHistory.find((version) => version.versionName === option);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useLoadingProgress, useRenameModeStore, useSaveVersion, useSelectedComment, useSocketStore, useWidgetSubOption } from "../../../store/builder/store";
|
||||
import useModuleStore, { useThreeDStore } from "../../../store/ui/useModuleStore";
|
||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
@@ -7,11 +8,8 @@ import { useFloatingWidget } from "../../../store/visualization/useDroppedObject
|
||||
import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore";
|
||||
import { createHandleDrop } from "../../../modules/visualization/functions/handleUiDrop";
|
||||
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
||||
import { useProductContext } from "../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
||||
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
||||
import { getUserData } from "../../../functions/getUserData";
|
||||
import useRestStates from "../../../hooks/useResetStates";
|
||||
import KeyPressListener from "../../../utils/shortcutkeys/handleShortcutKeys";
|
||||
import LoadingPage from "../../templates/LoadingPage";
|
||||
@@ -31,14 +29,13 @@ import Footer from "../../footer/Footer";
|
||||
import ThreadChat from "../../ui/collaboration/ThreadChat";
|
||||
import Scene from "../../../modules/scene/scene";
|
||||
|
||||
import { getUserData } from "../../../functions/getUserData";
|
||||
import { recentlyViewed } from "../../../services/dashboard/recentlyViewed";
|
||||
import { setAssetsApi } from "../../../services/factoryBuilder/asset/floorAsset/setAssetsApi";
|
||||
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
||||
|
||||
function MainScene() {
|
||||
const { setMainProduct } = useMainProduct();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { isVersionSaved, setIsVersionSaved } = useSaveVersion();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedUser } = useSelectedUserStore();
|
||||
@@ -52,7 +49,7 @@ function MainScene() {
|
||||
const { clearComparisonProduct } = useComparisonProduct();
|
||||
const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
|
||||
const { assetStore, productStore, versionStore } = useSceneContext();
|
||||
const { products } = productStore();
|
||||
const { products, selectedProduct } = productStore();
|
||||
const { versionHistory, setVersions, selectedVersion, setSelectedVersion } = versionStore();
|
||||
const { setName, selectedAssets, setSelectedAssets } = assetStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedEventSphere,
|
||||
} from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventData, useSelectedEventSphere } from "../../../../../store/simulation/useSimulationStore";
|
||||
import ConveyorMechanics from "./mechanics/conveyorMechanics";
|
||||
import VehicleMechanics from "./mechanics/vehicleMechanics";
|
||||
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
|
||||
@@ -11,19 +8,16 @@ import StorageMechanics from "./mechanics/storageMechanics";
|
||||
import HumanMechanics from "./mechanics/humanMechanics";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
||||
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../modules/scene/sceneContext";
|
||||
import CraneMechanics from "./mechanics/craneMechanics";
|
||||
|
||||
const EventProperties: React.FC = () => {
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { eventStore, productStore, versionStore } = useSceneContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
const { products, addEvent, getEventByModelUuid } = productStore();
|
||||
const { products, addEvent, getEventByModelUuid, selectedProduct } = productStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
@@ -39,12 +33,7 @@ const EventProperties: React.FC = () => {
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
return (
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
) ?? null
|
||||
);
|
||||
return getEventByModelUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid) ?? null;
|
||||
};
|
||||
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
@@ -75,9 +64,7 @@ const EventProperties: React.FC = () => {
|
||||
{currentEventData && (
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">
|
||||
{selectedEventData?.data.modelName}
|
||||
</div>
|
||||
<div className="header-value">{selectedEventData?.data.modelName}</div>
|
||||
</div>
|
||||
{assetType === "conveyor" && <ConveyorMechanics />}
|
||||
{assetType === "vehicle" && <VehicleMechanics />}
|
||||
@@ -91,9 +78,7 @@ const EventProperties: React.FC = () => {
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an
|
||||
event assigned yet. To continue, please link it to one of the
|
||||
products below.
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an event assigned yet. To continue, please link it to one of the products below.
|
||||
</p>
|
||||
|
||||
<div className="products-list">
|
||||
@@ -108,15 +93,11 @@ const EventProperties: React.FC = () => {
|
||||
onClick={() => {
|
||||
if (selectedEventData) {
|
||||
handleAddEventToProduct({
|
||||
event: eventStore
|
||||
.getState()
|
||||
.getEventByModelUuid(
|
||||
selectedEventData?.data.modelUuid
|
||||
),
|
||||
event: eventStore.getState().getEventByModelUuid(selectedEventData?.data.modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
projectId: projectId || '',
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || "",
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
}
|
||||
}}
|
||||
@@ -132,8 +113,7 @@ const EventProperties: React.FC = () => {
|
||||
{!selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event
|
||||
point yet. Please select an event to view its properties.
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event point yet. Please select an event to view its properties.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import React, { useRef } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../../../icons/ExportCommonIcons";
|
||||
import { AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import { handleResize } from "../../../../../../functions/handleResizePannel";
|
||||
import {
|
||||
useSelectedAction,
|
||||
} from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -21,31 +14,20 @@ interface ActionsListProps {
|
||||
handleDeleteAction?: (actionUuid: string) => void;
|
||||
}
|
||||
|
||||
const ActionsList: React.FC<ActionsListProps> = ({
|
||||
selectedPointData,
|
||||
multipleAction = false,
|
||||
handleAddAction,
|
||||
handleDeleteAction,
|
||||
}) => {
|
||||
const ActionsList: React.FC<ActionsListProps> = ({ selectedPointData, multipleAction = false, handleAddAction, handleDeleteAction }) => {
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// store
|
||||
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { renameAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { renameAction, selectedProduct } = productStore();
|
||||
const { selectedAction, setSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId) return;
|
||||
const event = renameAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
newName
|
||||
);
|
||||
const event = renameAction(selectedProduct.productUuid, selectedAction.actionId, newName);
|
||||
setSelectedAction(selectedAction.actionId, newName);
|
||||
if (event) {
|
||||
upsertProductOrEventApi({
|
||||
@@ -53,7 +35,7 @@ const ActionsList: React.FC<ActionsListProps> = ({
|
||||
productUuid: selectedProduct.productUuid,
|
||||
projectId,
|
||||
eventDatas: event,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -81,32 +63,13 @@ const ActionsList: React.FC<ActionsListProps> = ({
|
||||
<AddIcon /> Add
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="lists-main-container" ref={actionsContainerRef} style={{ height: "120px" }}>
|
||||
<div className="list-container">
|
||||
{multipleAction &&
|
||||
selectedPointData?.actions?.map((action: any) => (
|
||||
<div
|
||||
key={action.actionUuid}
|
||||
className={`list-item ${selectedAction.actionId === action.actionUuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
id="action-button"
|
||||
className="value"
|
||||
onClick={() =>
|
||||
handleActionSelect(action.actionUuid, action.actionName)
|
||||
}
|
||||
>
|
||||
<RenameInput
|
||||
value={action.actionName}
|
||||
onRename={(value) => handleRenameAction(value)}
|
||||
/>
|
||||
<div key={action.actionUuid} className={`list-item ${selectedAction.actionId === action.actionUuid ? "active" : ""}`}>
|
||||
<button id="action-button" className="value" onClick={() => handleActionSelect(action.actionUuid, action.actionName)}>
|
||||
<RenameInput value={action.actionName} onRename={(value) => handleRenameAction(value)} />
|
||||
</button>
|
||||
{selectedPointData?.actions?.length > 1 && (
|
||||
<button
|
||||
@@ -124,34 +87,15 @@ const ActionsList: React.FC<ActionsListProps> = ({
|
||||
</div>
|
||||
))}
|
||||
{!multipleAction && selectedPointData?.action && (
|
||||
<div
|
||||
key={selectedPointData.action.actionUuid}
|
||||
className={`list-item active`}
|
||||
>
|
||||
<button
|
||||
id="action-button"
|
||||
className="value"
|
||||
onClick={() =>
|
||||
handleActionSelect(
|
||||
selectedPointData.action.actionUuid,
|
||||
selectedPointData.action.actionName
|
||||
)
|
||||
}
|
||||
>
|
||||
<RenameInput
|
||||
value={selectedPointData.action.actionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
<div key={selectedPointData.action.actionUuid} className={`list-item active`}>
|
||||
<button id="action-button" className="value" onClick={() => handleActionSelect(selectedPointData.action.actionUuid, selectedPointData.action.actionName)}>
|
||||
<RenameInput value={selectedPointData.action.actionName} onRename={handleRenameAction} />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{multipleAction && (
|
||||
<button
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e: any) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<button className="resize-icon" id="action-resize" onMouseDown={(e: any) => handleResize(e, actionsContainerRef)}>
|
||||
<ResizeHeightIcon />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -11,7 +11,6 @@ import Trigger from "../trigger/Trigger";
|
||||
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -27,25 +26,16 @@ function ConveyorMechanics() {
|
||||
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, updateEvent, updateAction, getEventByModelUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, updateEvent, updateAction, getEventByModelUuid, selectedProduct } = productStore();
|
||||
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as ConveyorPointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData?.data.modelUuid, selectedEventData?.selectedPoint) as ConveyorPointSchema | undefined;
|
||||
|
||||
const event = getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid
|
||||
) as ConveyorEventSchema | undefined;
|
||||
const event = getEventByModelUuid(selectedProduct.productUuid, selectedEventData?.data.modelUuid) as ConveyorEventSchema | undefined;
|
||||
|
||||
if (point && "action" in point && event) {
|
||||
setSelectedPointData(point);
|
||||
@@ -63,12 +53,7 @@ function ConveyorMechanics() {
|
||||
}
|
||||
}, [selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -84,19 +69,10 @@ function ConveyorMechanics() {
|
||||
const numericValue = parseFloat(value);
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: numericValue }
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, { speed: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
setSpeed(value);
|
||||
};
|
||||
@@ -107,19 +83,10 @@ function ConveyorMechanics() {
|
||||
const validOption = option as "default" | "spawn" | "swap" | "delay" | "despawn";
|
||||
setActiveOption(validOption);
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionType: validOption });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,19 +97,10 @@ function ConveyorMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setSpawnCount(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ spawnCount: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { spawnCount: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,19 +111,10 @@ function ConveyorMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setSpawnInterval(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ spawnInterval: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { spawnInterval: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,19 +122,10 @@ function ConveyorMechanics() {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
setMaterial(selectedMaterial);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ material: selectedMaterial }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { material: selectedMaterial });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -196,19 +136,10 @@ function ConveyorMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setDelay(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ delay: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { delay: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -222,17 +153,7 @@ function ConveyorMechanics() {
|
||||
<div key={selectedPointData?.uuid} className="global-props section">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={speed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
<InputWithDropDown label="Speed" value={speed} min={0} step={0.1} defaultValue="0.5" max={10} activeOption="m/s" onClick={() => {}} onChange={handleSpeedChange} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -241,56 +162,19 @@ function ConveyorMechanics() {
|
||||
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={actionName}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={actionName} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
<LabledDropdown defaultOption={activeOption} options={availableActions.options} onSelect={handleActionTypeChange} />
|
||||
{activeOption === "default" && <DefaultAction />}
|
||||
{activeOption === "spawn" && (
|
||||
<SpawnAction
|
||||
onChangeCount={handleSpawnCountChange}
|
||||
options={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
defaultOption={material}
|
||||
onSelect={handleMaterialSelect}
|
||||
onChangeInterval={handleSpawnIntervalChange}
|
||||
intervalValue={spawnInterval}
|
||||
countValue={spawnCount}
|
||||
intervalMin={1}
|
||||
intervalMax={60}
|
||||
intervalDefaultValue="1"
|
||||
countMin={1}
|
||||
countMax={100}
|
||||
countDefaultValue="1"
|
||||
/>
|
||||
)}
|
||||
{activeOption === "swap" && (
|
||||
<SwapAction
|
||||
options={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
defaultOption={material}
|
||||
onSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "spawn" && <SpawnAction onChangeCount={handleSpawnCountChange} options={["Default material", "Material 1", "Material 2", "Material 3"]} defaultOption={material} onSelect={handleMaterialSelect} onChangeInterval={handleSpawnIntervalChange} intervalValue={spawnInterval} countValue={spawnCount} intervalMin={1} intervalMax={60} intervalDefaultValue="1" countMin={1} countMax={100} countDefaultValue="1" />}
|
||||
{activeOption === "swap" && <SwapAction options={["Default material", "Material 1", "Material 2", "Material 3"]} defaultOption={material} onSelect={handleMaterialSelect} />}
|
||||
{activeOption === "despawn" && <DespawnAction />}
|
||||
{activeOption === "delay" && (
|
||||
<DelayAction
|
||||
value={delay}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={60}
|
||||
onChange={handleDelayChange}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "delay" && <DelayAction value={delay} defaultValue="0" min={0} max={60} onChange={handleDelayChange} />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type={'Conveyor'} />
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"Conveyor"} />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
|
||||
@@ -6,7 +6,6 @@ import Trigger from "../trigger/Trigger";
|
||||
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -16,20 +15,14 @@ function CraneMechanics() {
|
||||
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, addAction, removeAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, addAction, removeAction, selectedProduct } = productStore();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as CranePointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as CranePointSchema | undefined;
|
||||
|
||||
if (point?.actions) {
|
||||
setSelectedPointData(point);
|
||||
@@ -45,12 +38,7 @@ function CraneMechanics() {
|
||||
}
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -71,20 +59,10 @@ function CraneMechanics() {
|
||||
triggers: [] as TriggerSchema[],
|
||||
};
|
||||
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
const event = addAction(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint, newAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData({
|
||||
@@ -97,22 +75,14 @@ function CraneMechanics() {
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
actionUuid
|
||||
);
|
||||
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
const index = selectedPointData.actions.findIndex(a => a.actionUuid === actionUuid);
|
||||
const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid);
|
||||
const index = selectedPointData.actions.findIndex((a) => a.actionUuid === actionUuid);
|
||||
const newActions = selectedPointData.actions.filter((a) => a.actionUuid !== actionUuid);
|
||||
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
@@ -134,39 +104,23 @@ function CraneMechanics() {
|
||||
options: ["pickAndDrop"],
|
||||
};
|
||||
|
||||
const currentAction = selectedPointData?.actions.find(a => a.actionUuid === selectedAction.actionId);
|
||||
const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
<ActionsList selectedPointData={selectedPointData} multipleAction handleAddAction={handleAddAction} handleDeleteAction={handleDeleteAction} />
|
||||
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName || ""}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={() => { }}
|
||||
disabled={true}
|
||||
/>
|
||||
<LabledDropdown defaultOption={activeOption} options={availableActions.options} onSelect={() => {}} disabled={true} />
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger
|
||||
selectedPointData={selectedPointData as any}
|
||||
type={"RoboticArm"}
|
||||
/>
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"RoboticArm"} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -175,4 +129,4 @@ function CraneMechanics() {
|
||||
);
|
||||
}
|
||||
|
||||
export default CraneMechanics
|
||||
export default CraneMechanics;
|
||||
|
||||
@@ -11,7 +11,6 @@ import ManufactureAction from "../actions/ManufactureAction";
|
||||
|
||||
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
@@ -27,32 +26,21 @@ function HumanMechanics() {
|
||||
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, updateEvent, updateAction, addAction, removeAction, getEventByModelUuid, getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, updateEvent, updateAction, addAction, removeAction, getEventByModelUuid, getActionByUuid, selectedProduct } = productStore();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "human") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as HumanPointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as HumanPointSchema | undefined;
|
||||
|
||||
if (point?.actions?.length) {
|
||||
setSelectedPointData(point);
|
||||
const firstAction = point.actions[0];
|
||||
setSelectedAction(firstAction.actionUuid, firstAction.actionName);
|
||||
setCurrentAction(firstAction);
|
||||
setSpeed((
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid || ""
|
||||
) as HumanEventSchema | undefined
|
||||
)?.speed?.toString() || "1");
|
||||
setSpeed((getEventByModelUuid(selectedProduct.productUuid, selectedEventData?.data.modelUuid || "") as HumanEventSchema | undefined)?.speed?.toString() || "1");
|
||||
setLoadCapacity(firstAction.loadCapacity.toString());
|
||||
setActiveOption(firstAction.actionType);
|
||||
setLoadCount(firstAction.loadCount || 0);
|
||||
@@ -67,17 +55,13 @@ function HumanMechanics() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "human") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as HumanPointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as HumanPointSchema | undefined;
|
||||
|
||||
const actionUuid = selectedAction.actionId || point?.actions[0].actionUuid || '';
|
||||
const actionUuid = selectedAction.actionId || point?.actions[0].actionUuid || "";
|
||||
|
||||
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (newCurrentAction && (newCurrentAction.actionType === 'manufacturer' || newCurrentAction?.actionType === 'worker' || newCurrentAction?.actionType === "operator")) {
|
||||
if (newCurrentAction && (newCurrentAction.actionType === "manufacturer" || newCurrentAction?.actionType === "worker" || newCurrentAction?.actionType === "operator")) {
|
||||
if (!selectedAction.actionId) {
|
||||
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
|
||||
}
|
||||
@@ -87,7 +71,7 @@ function HumanMechanics() {
|
||||
setLoadCount(newCurrentAction.loadCount || 0);
|
||||
setManufactureCount(newCurrentAction.manufactureCount || 0);
|
||||
|
||||
if (newCurrentAction.actionType === 'manufacturer') {
|
||||
if (newCurrentAction.actionType === "manufacturer") {
|
||||
setProcessTime(newCurrentAction.processTime || 10);
|
||||
setSwappedMaterial(newCurrentAction.swapMaterial || "Default material");
|
||||
}
|
||||
@@ -98,12 +82,7 @@ function HumanMechanics() {
|
||||
}
|
||||
}, [selectedAction, selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -117,17 +96,13 @@ function HumanMechanics() {
|
||||
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
|
||||
|
||||
const updatedAction = { ...currentAction, actionType: actionType as "worker" | "manufacturer" | "operator" | "assembler" };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -141,17 +116,13 @@ function HumanMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const updatedEvent = {
|
||||
speed: numericValue
|
||||
speed: numericValue,
|
||||
} as HumanEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, updatedEvent);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSpeed(value);
|
||||
@@ -161,17 +132,13 @@ function HumanMechanics() {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction, loadCapacity: parseInt(value) };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -183,17 +150,13 @@ function HumanMechanics() {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction, loadCount: value };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -205,17 +168,13 @@ function HumanMechanics() {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction, manufactureCount: value };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -227,17 +186,13 @@ function HumanMechanics() {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction, processTime: value };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -249,17 +204,13 @@ function HumanMechanics() {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction, swapMaterial: value };
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -272,24 +223,20 @@ function HumanMechanics() {
|
||||
|
||||
const updatedAction: HumanAction = JSON.parse(JSON.stringify(currentAction));
|
||||
|
||||
if (updatedAction.actionType === 'manufacturer') {
|
||||
updatedAction.manufacturePoint = { position: null, rotation: null, }
|
||||
if (updatedAction.actionType === "manufacturer") {
|
||||
updatedAction.manufacturePoint = { position: null, rotation: null };
|
||||
} else {
|
||||
updatedAction.pickUpPoint = { position: null, rotation: null, };
|
||||
updatedAction.dropPoint = { position: null, rotation: null, }
|
||||
updatedAction.pickUpPoint = { position: null, rotation: null };
|
||||
updatedAction.dropPoint = { position: null, rotation: null };
|
||||
}
|
||||
|
||||
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
|
||||
const updatedActions = selectedPointData.actions.map((action) => (action.actionUuid === updatedAction.actionUuid ? updatedAction : action));
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
@@ -306,8 +253,8 @@ function HumanMechanics() {
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
assemblyCondition: {
|
||||
conditionType: 'material',
|
||||
materialType: "Default material"
|
||||
conditionType: "material",
|
||||
materialType: "Default material",
|
||||
},
|
||||
manufactureCount: 1,
|
||||
loadCapacity: 1,
|
||||
@@ -318,15 +265,10 @@ function HumanMechanics() {
|
||||
const updatedActions = [...(selectedPointData.actions || []), newAction];
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
const event = addAction(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint, newAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
@@ -336,16 +278,13 @@ function HumanMechanics() {
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData || !actionUuid) return;
|
||||
|
||||
const updatedActions = selectedPointData.actions.filter(action => action.actionUuid !== actionUuid);
|
||||
const updatedActions = selectedPointData.actions.filter((action) => action.actionUuid !== actionUuid);
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
actionUuid
|
||||
);
|
||||
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
@@ -369,27 +308,12 @@ function HumanMechanics() {
|
||||
<div className="global-props section">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={speed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
<InputWithDropDown label="Speed" value={speed} min={0} step={0.1} defaultValue="0.5" max={10} activeOption="m/s" onClick={() => {}} onChange={handleSpeedChange} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction={true}
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
<ActionsList selectedPointData={selectedPointData} multipleAction={true} handleAddAction={handleAddAction} handleDeleteAction={handleDeleteAction} />
|
||||
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
@@ -397,15 +321,9 @@ function HumanMechanics() {
|
||||
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
label="Action Type"
|
||||
defaultOption={activeOption}
|
||||
options={["worker", "manufacturer", "operator"]}
|
||||
onSelect={handleSelectActionType}
|
||||
disabled={false}
|
||||
/>
|
||||
<LabledDropdown label="Action Type" defaultOption={activeOption} options={["worker", "manufacturer", "operator"]} onSelect={handleSelectActionType} disabled={false} />
|
||||
</div>
|
||||
{(currentAction.actionType === 'worker' || currentAction.actionType === "operator") &&
|
||||
{(currentAction.actionType === "worker" || currentAction.actionType === "operator") && (
|
||||
<WorkerAction
|
||||
loadCapacity={{
|
||||
value: loadCapacity,
|
||||
@@ -427,8 +345,8 @@ function HumanMechanics() {
|
||||
}}
|
||||
clearPoints={handleClearPoints}
|
||||
/>
|
||||
}
|
||||
{currentAction.actionType === 'manufacturer' &&
|
||||
)}
|
||||
{currentAction.actionType === "manufacturer" && (
|
||||
<ManufactureAction
|
||||
processTime={{
|
||||
value: processTime,
|
||||
@@ -450,7 +368,7 @@ function HumanMechanics() {
|
||||
onSwapSelect={handleMaterialChange}
|
||||
clearPoints={handleClearPoints}
|
||||
/>
|
||||
}
|
||||
)}
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type="Human" />
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { useSelectedAction, useSelectedEventData } from "../../../../../../store
|
||||
import ProcessAction from "../actions/ProcessAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -19,20 +18,14 @@ function MachineMechanics() {
|
||||
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, updateAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, updateAction, selectedProduct } = productStore();
|
||||
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as MachinePointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData?.data.modelUuid, selectedEventData?.selectedPoint) as MachinePointSchema | undefined;
|
||||
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
@@ -47,12 +40,7 @@ function MachineMechanics() {
|
||||
}
|
||||
}, [selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -68,19 +56,10 @@ function MachineMechanics() {
|
||||
const validOption = option as "process";
|
||||
setActiveOption(validOption);
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionType: validOption });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,19 +67,10 @@ function MachineMechanics() {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
setActionName(newName);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionName: newName });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -111,19 +81,10 @@ function MachineMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setProcessTime(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ processTime: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { processTime: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -131,19 +92,10 @@ function MachineMechanics() {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
setMaterial(selectedMaterial);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ swapMaterial: selectedMaterial }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { swapMaterial: selectedMaterial });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -158,34 +110,16 @@ function MachineMechanics() {
|
||||
<section>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={actionName}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={actionName} canEdit={false} />
|
||||
</div>
|
||||
<ActionsList selectedPointData={selectedPointData} />
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "process" && (
|
||||
<ProcessAction
|
||||
value={processTime}
|
||||
min={0.1}
|
||||
max={60}
|
||||
defaultValue="1"
|
||||
onChange={handleProcessTimeChange}
|
||||
swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
|
||||
swapDefaultOption={material}
|
||||
onSwapSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
<LabledDropdown defaultOption={activeOption} options={availableActions.options} onSelect={handleActionTypeChange} />
|
||||
{activeOption === "process" && <ProcessAction value={processTime} min={0.1} max={60} defaultValue="1" onChange={handleProcessTimeChange} swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]} swapDefaultOption={material} onSwapSelect={handleMaterialSelect} />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type={'Machine'} />
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"Machine"} />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useSelectedEventData, useSelectedAction } from "../../../../../../store
|
||||
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -19,29 +18,18 @@ function RoboticArmMechanics() {
|
||||
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction, selectedProduct } = productStore();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === 'roboticArm') {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as RoboticArmPointSchema | undefined;
|
||||
if (selectedEventData && selectedEventData.data.type === "roboticArm") {
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as RoboticArmPointSchema | undefined;
|
||||
|
||||
if (point?.actions) {
|
||||
setSelectedPointData(point);
|
||||
setSpeed(
|
||||
(getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
) as RoboticArmEventSchema | undefined)?.speed?.toString() || "0.5"
|
||||
);
|
||||
setSpeed((getEventByModelUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid) as RoboticArmEventSchema | undefined)?.speed?.toString() || "0.5");
|
||||
|
||||
if (point.actions.length > 0) {
|
||||
const firstAction = point.actions[0];
|
||||
@@ -54,12 +42,7 @@ function RoboticArmMechanics() {
|
||||
}
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -76,43 +59,25 @@ function RoboticArmMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setSpeed(value);
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: numericValue }
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, { speed: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClearPoints = () => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
{
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, {
|
||||
process: {
|
||||
startPoint: null,
|
||||
endPoint: null,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,20 +95,10 @@ function RoboticArmMechanics() {
|
||||
triggers: [] as TriggerSchema[],
|
||||
};
|
||||
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
const event = addAction(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint, newAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData({
|
||||
@@ -156,22 +111,14 @@ function RoboticArmMechanics() {
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
actionUuid
|
||||
);
|
||||
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
const index = selectedPointData.actions.findIndex(a => a.actionUuid === actionUuid);
|
||||
const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid);
|
||||
const index = selectedPointData.actions.findIndex((a) => a.actionUuid === actionUuid);
|
||||
const newActions = selectedPointData.actions.filter((a) => a.actionUuid !== actionUuid);
|
||||
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
@@ -193,57 +140,31 @@ function RoboticArmMechanics() {
|
||||
options: ["pickAndPlace"],
|
||||
};
|
||||
|
||||
const currentAction = selectedPointData?.actions.find(a => a.actionUuid === selectedAction.actionId);
|
||||
const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="global-props section">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={speed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
<InputWithDropDown label="Speed" value={speed} min={0} step={0.1} defaultValue="0.5" max={10} activeOption="m/s" onClick={() => {}} onChange={handleSpeedChange} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
<ActionsList selectedPointData={selectedPointData} multipleAction handleAddAction={handleAddAction} handleDeleteAction={handleDeleteAction} />
|
||||
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName || ""}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={() => { }}
|
||||
disabled={true}
|
||||
/>
|
||||
<LabledDropdown defaultOption={activeOption} options={availableActions.options} onSelect={() => {}} disabled={true} />
|
||||
<PickAndPlaceAction clearPoints={handleClearPoints} />
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger
|
||||
selectedPointData={selectedPointData as any}
|
||||
type={"RoboticArm"}
|
||||
/>
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"RoboticArm"} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -7,7 +7,6 @@ import StorageAction from "../actions/StorageAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -19,29 +18,20 @@ function StorageMechanics() {
|
||||
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, updateAction, updateEvent, getEventByModelUuid, getActionByUuid, addAction, removeAction } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, updateAction, updateEvent, getEventByModelUuid, getActionByUuid, addAction, removeAction, selectedProduct } = productStore();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "storageUnit") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as StoragePointSchema | undefined;
|
||||
|
||||
if (point?.actions?.length) {
|
||||
setSelectedPointData(point);
|
||||
const firstAction = point.actions[0];
|
||||
|
||||
const eventData = getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
) as StorageEventSchema | undefined;
|
||||
const eventData = getEventByModelUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid) as StorageEventSchema | undefined;
|
||||
|
||||
setCurrentCapacity(eventData?.storageCapacity?.toString() || "1");
|
||||
setSpawnedCount(eventData?.storageCount?.toString() || "0");
|
||||
@@ -56,17 +46,13 @@ function StorageMechanics() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "storageUnit" && selectedAction.actionId) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as StoragePointSchema | undefined;
|
||||
|
||||
const actionUuid = selectedAction.actionId || point?.actions[0].actionUuid || '';
|
||||
const actionUuid = selectedAction.actionId || point?.actions[0].actionUuid || "";
|
||||
|
||||
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (newCurrentAction && (newCurrentAction.actionType === 'store' || newCurrentAction.actionType === 'retrieve')) {
|
||||
if (newCurrentAction && (newCurrentAction.actionType === "store" || newCurrentAction.actionType === "retrieve")) {
|
||||
if (!selectedAction.actionId) {
|
||||
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
|
||||
}
|
||||
@@ -78,20 +64,15 @@ function StorageMechanics() {
|
||||
}
|
||||
}, [selectedAction, selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
})
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
@@ -99,31 +80,24 @@ function StorageMechanics() {
|
||||
const internalOption = option === "spawn" ? "retrieve" : "store";
|
||||
|
||||
const updatedAction = {
|
||||
actionType: internalOption as "store" | "retrieve"
|
||||
actionType: internalOption as "store" | "retrieve",
|
||||
};
|
||||
|
||||
const updatedActions = selectedPointData.actions.map(action =>
|
||||
action.actionUuid === selectedAction.actionId ? {
|
||||
const updatedActions = selectedPointData.actions.map((action) =>
|
||||
action.actionUuid === selectedAction.actionId
|
||||
? {
|
||||
...action,
|
||||
actionType: updatedAction.actionType
|
||||
} : action
|
||||
actionType: updatedAction.actionType,
|
||||
}
|
||||
: action
|
||||
);
|
||||
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedAction.actionId, updatedAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
@@ -137,7 +111,7 @@ function StorageMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const updatedEvent = {
|
||||
storageCapacity: numericValue
|
||||
storageCapacity: numericValue,
|
||||
} as StorageEventSchema;
|
||||
|
||||
const currentCount = parseInt(spawnedCount);
|
||||
@@ -146,19 +120,10 @@ function StorageMechanics() {
|
||||
setSpawnedCount(numericValue.toString());
|
||||
}
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, updatedEvent);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setCurrentCapacity(value);
|
||||
@@ -174,22 +139,13 @@ function StorageMechanics() {
|
||||
if (numericValue > maxCapacity) return;
|
||||
|
||||
const updatedEvent = {
|
||||
storageCount: numericValue
|
||||
storageCount: numericValue,
|
||||
} as StorageEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, updatedEvent);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSpawnedCount(value);
|
||||
@@ -199,22 +155,13 @@ function StorageMechanics() {
|
||||
if (!selectedEventData) return;
|
||||
|
||||
const updatedEvent = {
|
||||
materialType: value
|
||||
materialType: value,
|
||||
} as StorageEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, updatedEvent);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSpawnedMaterial(value);
|
||||
@@ -233,15 +180,10 @@ function StorageMechanics() {
|
||||
const updatedActions = [...(selectedPointData.actions || []), newAction];
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
const event = addAction(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint, newAction);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
@@ -251,16 +193,13 @@ function StorageMechanics() {
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData || !actionUuid) return;
|
||||
|
||||
const updatedActions = selectedPointData.actions.filter(action => action.actionUuid !== actionUuid);
|
||||
const updatedActions = selectedPointData.actions.filter((action) => action.actionUuid !== actionUuid);
|
||||
const updatedPoint = { ...selectedPointData, actions: updatedActions };
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
actionUuid
|
||||
);
|
||||
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
setSelectedPointData(updatedPoint);
|
||||
@@ -279,45 +218,21 @@ function StorageMechanics() {
|
||||
{selectedEventData && selectedEventData.data.type === "storageUnit" && (
|
||||
<>
|
||||
<section>
|
||||
<StorageAction
|
||||
maxCapacity={currentCapacity}
|
||||
spawnedCount={spawnedCount}
|
||||
maxCapacityDefault="0"
|
||||
spawnedCountCefault="0"
|
||||
min={0}
|
||||
currentMaterialType={spawnedMaterial}
|
||||
handleCapacityChange={handleCapacityChange}
|
||||
handleSpawnCountChange={handleSpawnCountChange}
|
||||
handleMaterialTypeChange={handleMaterialTypeChange}
|
||||
/>
|
||||
<StorageAction maxCapacity={currentCapacity} spawnedCount={spawnedCount} maxCapacityDefault="0" spawnedCountCefault="0" min={0} currentMaterialType={spawnedMaterial} handleCapacityChange={handleCapacityChange} handleSpawnCountChange={handleSpawnCountChange} handleMaterialTypeChange={handleMaterialTypeChange} />
|
||||
</section>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction={true}
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
<ActionsList selectedPointData={selectedPointData} multipleAction={true} handleAddAction={handleAddAction} handleDeleteAction={handleDeleteAction} />
|
||||
|
||||
{selectedAction.actionId && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName || ""}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
label="Action Type"
|
||||
defaultOption={activeOption}
|
||||
options={["store", "spawn"]}
|
||||
onSelect={handleActionTypeChange}
|
||||
disabled={false}
|
||||
/>
|
||||
<LabledDropdown label="Action Type" defaultOption={activeOption} options={["store", "spawn"]} onSelect={handleActionTypeChange} disabled={false} />
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type={'StorageUnit'} />
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"StorageUnit"} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -7,7 +7,6 @@ import { useSelectedAction, useSelectedEventData } from "../../../../../../store
|
||||
import TravelAction from "../actions/TravelAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
import { useSelectedPath } from "../../../../../../store/builder/store";
|
||||
@@ -22,9 +21,7 @@ function VehicleMechanics() {
|
||||
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getPointByUuid, updateEvent, updateAction, getEventByModelUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getPointByUuid, updateEvent, updateAction, getEventByModelUuid, selectedProduct } = productStore();
|
||||
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
@@ -32,22 +29,13 @@ function VehicleMechanics() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "vehicle") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as VehiclePointSchema | undefined;
|
||||
const point = getPointByUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid, selectedEventData.selectedPoint) as VehiclePointSchema | undefined;
|
||||
|
||||
if (point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "travel");
|
||||
setActionName(point.action.actionName);
|
||||
setSpeed(
|
||||
(getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
) as VehicleEventSchema | undefined)?.speed?.toString() || "0.5"
|
||||
);
|
||||
setSpeed((getEventByModelUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid) as VehicleEventSchema | undefined)?.speed?.toString() || "0.5");
|
||||
setLoadCapacity(point.action.loadCapacity?.toString() || "1");
|
||||
setUnloadDuration(point.action.unLoadDuration?.toString() || "1");
|
||||
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||
@@ -57,12 +45,7 @@ function VehicleMechanics() {
|
||||
}
|
||||
}, [selectedProduct, selectedEventData]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
@@ -79,19 +62,10 @@ function VehicleMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setSpeed(value);
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: numericValue }
|
||||
);
|
||||
const event = updateEvent(selectedProduct.productUuid, selectedEventData.data.modelUuid, { speed: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,19 +75,10 @@ function VehicleMechanics() {
|
||||
const validOption = option as "travel";
|
||||
setActiveOption(validOption);
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { actionType: validOption });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,19 +89,10 @@ function VehicleMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setLoadCapacity(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ loadCapacity: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { loadCapacity: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,42 +103,24 @@ function VehicleMechanics() {
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
setUnloadDuration(value);
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{ unLoadDuration: numericValue }
|
||||
);
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, { unLoadDuration: numericValue });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClearPoints = () => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid,
|
||||
{
|
||||
const event = updateAction(selectedProduct.productUuid, selectedPointData.action.actionUuid, {
|
||||
pickUpPoint: null,
|
||||
unLoadPoint: null,
|
||||
steeringAngle: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -198,17 +136,7 @@ function VehicleMechanics() {
|
||||
<div className="global-props section">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={speed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
<InputWithDropDown label="Speed" value={speed} min={0} step={0.1} defaultValue="0.5" max={10} activeOption="m/s" onClick={() => {}} onChange={handleSpeedChange} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,17 +144,10 @@ function VehicleMechanics() {
|
||||
<ActionsList selectedPointData={selectedPointData} />
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={actionName}
|
||||
canEdit={false}
|
||||
/>
|
||||
<RenameInput value={actionName} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
<LabledDropdown defaultOption={activeOption} options={availableActions.options} onSelect={handleActionTypeChange} />
|
||||
|
||||
{activeOption === "travel" && (
|
||||
<TravelAction
|
||||
@@ -250,17 +171,16 @@ function VehicleMechanics() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger
|
||||
selectedPointData={selectedPointData as any}
|
||||
type={"Vehicle"}
|
||||
/>
|
||||
<Trigger selectedPointData={selectedPointData as any} type={"Vehicle"} />
|
||||
</div>
|
||||
<div style={{
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
flexDirection: "column",
|
||||
alignItems: "center"
|
||||
}}>
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
style={{
|
||||
backgroundColor: "#6f42c1",
|
||||
|
||||
@@ -6,7 +6,6 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import { handleResize } from "../../../../../../functions/handleResizePannel";
|
||||
import { useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -17,10 +16,8 @@ type TriggerProps = {
|
||||
|
||||
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
const [currentAction, setCurrentAction] = useState<string | undefined>();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getActionByUuid, getEventByModelUuid, getPointByUuid, getTriggerByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById, } = productStore();
|
||||
const { getActionByUuid, getEventByModelUuid, getPointByUuid, getTriggerByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById, selectedProduct } = productStore();
|
||||
const [triggers, setTriggers] = useState<TriggerSchema[]>([]);
|
||||
const [selectedTrigger, setSelectedTrigger] = useState<TriggerSchema | undefined>();
|
||||
const [activeOption, setActiveOption] = useState<"onComplete" | "onStart" | "onStop" | "delay" | "onError">("onComplete");
|
||||
@@ -35,26 +32,21 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
let actionUuid: string | undefined;
|
||||
|
||||
if (type === "Conveyor" || type === "Vehicle" || type === "Machine") {
|
||||
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema).action?.actionUuid;
|
||||
} else if ((type === "RoboticArm" || type === "Human" || type === "StorageUnit" || type === 'Crane') && selectedAction.actionId) {
|
||||
actionUuid = (selectedPointData as ConveyorPointSchema | VehiclePointSchema | MachinePointSchema).action?.actionUuid;
|
||||
} else if ((type === "RoboticArm" || type === "Human" || type === "StorageUnit" || type === "Crane") && selectedAction.actionId) {
|
||||
actionUuid = selectedAction.actionId;
|
||||
}
|
||||
|
||||
setCurrentAction(actionUuid);
|
||||
}, [selectedPointData, selectedProduct, type, selectedAction]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
@@ -70,31 +62,18 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
}, [currentAction, selectedProduct, selectedTrigger, selectedPointData]);
|
||||
|
||||
const triggeredModel = useMemo(() => {
|
||||
if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredModel?.modelUuid)
|
||||
return undefined;
|
||||
return getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedTrigger.triggeredAsset.triggeredModel.modelUuid
|
||||
);
|
||||
if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredModel?.modelUuid) return undefined;
|
||||
return getEventByModelUuid(selectedProduct.productUuid, selectedTrigger.triggeredAsset.triggeredModel.modelUuid);
|
||||
}, [selectedProduct, selectedTrigger]);
|
||||
|
||||
const triggeredPoint = useMemo(() => {
|
||||
if (!selectedProduct || !triggeredModel || !selectedTrigger?.triggeredAsset?.triggeredPoint?.pointUuid)
|
||||
return undefined;
|
||||
return getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
triggeredModel.modelUuid,
|
||||
selectedTrigger.triggeredAsset.triggeredPoint.pointUuid
|
||||
);
|
||||
if (!selectedProduct || !triggeredModel || !selectedTrigger?.triggeredAsset?.triggeredPoint?.pointUuid) return undefined;
|
||||
return getPointByUuid(selectedProduct.productUuid, triggeredModel.modelUuid, selectedTrigger.triggeredAsset.triggeredPoint.pointUuid);
|
||||
}, [selectedProduct, triggeredModel, selectedTrigger]);
|
||||
|
||||
const triggeredAction = useMemo(() => {
|
||||
if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredAction?.actionUuid)
|
||||
return undefined;
|
||||
return getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedTrigger.triggeredAsset.triggeredAction.actionUuid
|
||||
);
|
||||
if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredAction?.actionUuid) return undefined;
|
||||
return getActionByUuid(selectedProduct.productUuid, selectedTrigger.triggeredAsset.triggeredAction.actionUuid);
|
||||
}, [selectedProduct, selectedTrigger]);
|
||||
|
||||
const modelOptions = getProductById(selectedProduct.productUuid)?.eventDatas || [];
|
||||
@@ -106,7 +85,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
if (!model) return [];
|
||||
|
||||
if ("points" in model) {
|
||||
return (model).points;
|
||||
return model.points;
|
||||
} else if ("point" in model) {
|
||||
return [model.point];
|
||||
}
|
||||
@@ -146,18 +125,10 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
});
|
||||
|
||||
if (event) {
|
||||
const updatedTrigger = getTriggerByUuid(
|
||||
selectedProduct.productUuid,
|
||||
triggerUuid
|
||||
);
|
||||
const updatedTrigger = getTriggerByUuid(selectedProduct.productUuid, triggerUuid);
|
||||
setSelectedTrigger(updatedTrigger);
|
||||
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -180,18 +151,10 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
});
|
||||
|
||||
if (event) {
|
||||
const updatedTrigger = getTriggerByUuid(
|
||||
selectedProduct.productUuid,
|
||||
triggerUuid
|
||||
);
|
||||
const updatedTrigger = getTriggerByUuid(selectedProduct.productUuid, triggerUuid);
|
||||
setSelectedTrigger(updatedTrigger);
|
||||
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -215,12 +178,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -236,25 +194,13 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
triggeredAsset: null,
|
||||
};
|
||||
|
||||
const event = addTrigger(
|
||||
selectedProduct.productUuid,
|
||||
currentAction,
|
||||
newTrigger
|
||||
);
|
||||
const event = addTrigger(selectedProduct.productUuid, currentAction, newTrigger);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
const updatedAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
currentAction
|
||||
);
|
||||
const updatedAction = getActionByUuid(selectedProduct.productUuid, currentAction);
|
||||
const updatedTriggers = updatedAction?.triggers || [];
|
||||
|
||||
setTriggers(updatedTriggers);
|
||||
@@ -267,12 +213,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
const event = removeTrigger(selectedProduct.productUuid, triggerUuid);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
const index = triggers.findIndex((t) => t.triggerUuid === triggerUuid);
|
||||
@@ -287,44 +228,26 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
|
||||
const handleTriggerRename = (triggerUuid: string, newName: string) => {
|
||||
if (!selectedProduct) return;
|
||||
const event = renameTrigger(
|
||||
selectedProduct.productUuid,
|
||||
triggerUuid,
|
||||
newName
|
||||
);
|
||||
const event = renameTrigger(selectedProduct.productUuid, triggerUuid, newName);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTriggerTypeChange = (option: string) => {
|
||||
if (!selectedTrigger || !selectedProduct) return;
|
||||
|
||||
const validTypes: Array<TriggerSchema["triggerType"]> = ["onComplete", "onStart", "onStop", "delay", "onError",];
|
||||
const validTypes: Array<TriggerSchema["triggerType"]> = ["onComplete", "onStart", "onStop", "delay", "onError"];
|
||||
if (!validTypes.includes(option as TriggerSchema["triggerType"])) return;
|
||||
|
||||
setActiveOption(option as TriggerSchema["triggerType"]);
|
||||
const event = updateTrigger(
|
||||
selectedProduct.productUuid,
|
||||
selectedTrigger.triggerUuid,
|
||||
{
|
||||
const event = updateTrigger(selectedProduct.productUuid, selectedTrigger.triggerUuid, {
|
||||
triggerType: option as TriggerSchema["triggerType"],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -332,39 +255,17 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
<div className="trigger-wrapper">
|
||||
<div className="header">
|
||||
<div className="title">Trigger</div>
|
||||
<button
|
||||
id="add-trigger-button"
|
||||
className="add-button"
|
||||
onClick={handleAddTrigger}
|
||||
style={{ cursor: "pointer" }}
|
||||
disabled={!currentAction}
|
||||
>
|
||||
<button id="add-trigger-button" className="add-button" onClick={handleAddTrigger} style={{ cursor: "pointer" }} disabled={!currentAction}>
|
||||
<AddIcon /> Add
|
||||
</button>
|
||||
</div>
|
||||
<div className="trigger-list">
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={triggersContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="lists-main-container" ref={triggersContainerRef} style={{ height: "120px" }}>
|
||||
<div className="list-container">
|
||||
{triggers.map((trigger) => (
|
||||
<div
|
||||
key={trigger.triggerUuid}
|
||||
className={`list-item ${selectedTrigger?.triggerUuid === trigger.triggerUuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
onClick={() => setSelectedTrigger(trigger)}
|
||||
>
|
||||
<div key={trigger.triggerUuid} className={`list-item ${selectedTrigger?.triggerUuid === trigger.triggerUuid ? "active" : ""}`} onClick={() => setSelectedTrigger(trigger)}>
|
||||
<button id="trigger" className="value">
|
||||
<RenameInput
|
||||
value={trigger.triggerName}
|
||||
onRename={(newName) =>
|
||||
handleTriggerRename(trigger.triggerUuid, newName)
|
||||
}
|
||||
/>
|
||||
<RenameInput value={trigger.triggerName} onRename={(newName) => handleTriggerRename(trigger.triggerUuid, newName)} />
|
||||
</button>
|
||||
<button
|
||||
id="remove-trigger-button"
|
||||
@@ -379,11 +280,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e: any) => handleResize(e, triggersContainerRef)}
|
||||
>
|
||||
<button className="resize-icon" id="action-resize" onMouseDown={(e: any) => handleResize(e, triggersContainerRef)}>
|
||||
<ResizeHeightIcon />
|
||||
</button>
|
||||
</div>
|
||||
@@ -410,16 +307,8 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
/>
|
||||
<LabledDropdown
|
||||
label="Triggered Point"
|
||||
defaultOption={
|
||||
triggeredPoint?.uuid
|
||||
? `Point ${triggeredPoint?.uuid.slice(0, 4)}`
|
||||
: ""
|
||||
}
|
||||
options={[
|
||||
...pointOptions.map(
|
||||
(option) => `Point ${option.uuid.slice(0, 4)}`
|
||||
),
|
||||
]}
|
||||
defaultOption={triggeredPoint?.uuid ? `Point ${triggeredPoint?.uuid.slice(0, 4)}` : ""}
|
||||
options={[...pointOptions.map((option) => `Point ${option.uuid.slice(0, 4)}`)]}
|
||||
onSelect={(option) => {
|
||||
handlePointSelect(option, selectedTrigger.triggerUuid);
|
||||
}}
|
||||
@@ -427,9 +316,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
<LabledDropdown
|
||||
label="Triggered Action"
|
||||
defaultOption={triggeredAction?.actionName || ""}
|
||||
options={[
|
||||
...actionOptions.map((option: any) => option.actionName),
|
||||
]}
|
||||
options={[...actionOptions.map((option: any) => option.actionName)]}
|
||||
onSelect={(option) => {
|
||||
handleActionSelect(option, selectedTrigger.triggerUuid);
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon, } from "../../../icons/ExportCommonIcons";
|
||||
import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
import { useMainProduct, useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||
@@ -13,9 +13,8 @@ import { deleteProductApi } from "../../../../services/simulation/products/delet
|
||||
import { renameProductApi } from "../../../../services/simulation/products/renameProductApi";
|
||||
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
|
||||
import ComparePopUp from "../../../ui/compareVersion/Compare";
|
||||
import { useCompareStore, useSaveVersion, } from "../../../../store/builder/store";
|
||||
import { useCompareStore, useSaveVersion } from "../../../../store/builder/store";
|
||||
import { useToggleStore } from "../../../../store/ui/useUIToggleStore";
|
||||
import { useProductContext } from "../../../../modules/simulation/products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||
|
||||
@@ -39,9 +38,7 @@ const List: React.FC<ListProps> = ({ val }) => {
|
||||
const Simulations: React.FC = () => {
|
||||
const productsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const { eventStore, productStore, versionStore } = useSceneContext();
|
||||
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, getProductById, } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct, setSelectedProduct } = selectedProductStore();
|
||||
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, getProductById, selectedProduct, setSelectedProduct } = productStore();
|
||||
const { getEventByModelUuid } = eventStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const [openObjects, setOpenObjects] = useState(true);
|
||||
@@ -67,7 +64,7 @@ const Simulations: React.FC = () => {
|
||||
productName: name,
|
||||
productUuid: id,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
@@ -83,14 +80,8 @@ const Simulations: React.FC = () => {
|
||||
if (currentIndex >= updatedProducts.length) {
|
||||
newSelectedIndex = updatedProducts.length - 1;
|
||||
}
|
||||
setSelectedProduct(
|
||||
updatedProducts[newSelectedIndex].productUuid,
|
||||
updatedProducts[newSelectedIndex].productName
|
||||
);
|
||||
setMainProduct(
|
||||
updatedProducts[newSelectedIndex].productUuid,
|
||||
updatedProducts[newSelectedIndex].productName
|
||||
);
|
||||
setSelectedProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName);
|
||||
setMainProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName);
|
||||
} else {
|
||||
setSelectedProduct("", "");
|
||||
setMainProduct("", "");
|
||||
@@ -100,14 +91,14 @@ const Simulations: React.FC = () => {
|
||||
removeProduct(productUuid);
|
||||
deleteProductApi({
|
||||
productUuid,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameProduct = (productUuid: string, newName: string) => {
|
||||
renameProduct(productUuid, newName);
|
||||
renameProductApi({ productName: newName, productUuid, projectId: projectId || '', versionId: selectedVersion?.versionId || '' });
|
||||
renameProductApi({ productName: newName, productUuid, projectId: projectId || "", versionId: selectedVersion?.versionId || "" });
|
||||
if (selectedProduct.productUuid === productUuid) {
|
||||
setSelectedProduct(productUuid, newName);
|
||||
setMainProduct(productUuid, newName);
|
||||
@@ -116,11 +107,10 @@ const Simulations: React.FC = () => {
|
||||
|
||||
const handleRemoveEventFromProduct = () => {
|
||||
if (selectedAsset) {
|
||||
|
||||
deleteEventDataApi({
|
||||
productUuid: selectedProduct.productUuid,
|
||||
modelUuid: selectedAsset.modelUuid,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
removeEvent(selectedProduct.productUuid, selectedAsset.modelUuid);
|
||||
@@ -133,8 +123,7 @@ const Simulations: React.FC = () => {
|
||||
const selectedProductData = getProductById(selectedProduct.productUuid);
|
||||
|
||||
if (selectedProductData) {
|
||||
determineExecutionMachineSequences([selectedProductData]).then(
|
||||
(sequences) => {
|
||||
determineExecutionMachineSequences([selectedProductData]).then((sequences) => {
|
||||
sequences.forEach((sequence) => {
|
||||
const events: Event[] =
|
||||
sequence.map((event) => ({
|
||||
@@ -144,10 +133,8 @@ const Simulations: React.FC = () => {
|
||||
processes.push(events);
|
||||
});
|
||||
setProcesses(processes);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}, [selectedProduct.productUuid, products]);
|
||||
|
||||
return (
|
||||
@@ -157,77 +144,41 @@ const Simulations: React.FC = () => {
|
||||
<div className="actions section">
|
||||
<div className="header">
|
||||
<div className="header-value">Products</div>
|
||||
<button
|
||||
id="add-simulation"
|
||||
className="add-button"
|
||||
onClick={handleAddProduct}
|
||||
>
|
||||
<button id="add-simulation" className="add-button" onClick={handleAddProduct}>
|
||||
<AddIcon /> Add
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={productsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="lists-main-container" ref={productsContainerRef} style={{ height: "120px" }}>
|
||||
<div className="list-container">
|
||||
{products.map((product, index) => (
|
||||
<div
|
||||
key={product.productUuid}
|
||||
className={`list-item ${selectedProduct.productUuid === product.productUuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div key={product.productUuid} className={`list-item ${selectedProduct.productUuid === product.productUuid ? "active" : ""}`}>
|
||||
{/* eslint-disable-next-line */}
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => {
|
||||
setSelectedProduct(product.productUuid, product.productName)
|
||||
setMainProduct(product.productUuid, product.productName)
|
||||
setSelectedProduct(product.productUuid, product.productName);
|
||||
setMainProduct(product.productUuid, product.productName);
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="products"
|
||||
checked={selectedProduct.productUuid === product.productUuid}
|
||||
readOnly
|
||||
/>
|
||||
<RenameInput
|
||||
value={product.productName}
|
||||
onRename={(newName) =>
|
||||
handleRenameProduct(product.productUuid, newName)
|
||||
}
|
||||
/>
|
||||
<input type="radio" name="products" checked={selectedProduct.productUuid === product.productUuid} readOnly />
|
||||
<RenameInput value={product.productName} onRename={(newName) => handleRenameProduct(product.productUuid, newName)} />
|
||||
</div>
|
||||
{products.length > 1 && (
|
||||
<button
|
||||
id="remove-product-button"
|
||||
className="remove-button"
|
||||
onClick={() => handleRemoveProduct(product.productUuid)}
|
||||
>
|
||||
<button id="remove-product-button" className="remove-button" onClick={() => handleRemoveProduct(product.productUuid)}>
|
||||
<RemoveIcon />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e: any) => handleResize(e, productsContainerRef)}
|
||||
>
|
||||
<button className="resize-icon" id="action-resize" onMouseDown={(e: any) => handleResize(e, productsContainerRef)}>
|
||||
<ResizeHeightIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="simulation-process section">
|
||||
<button
|
||||
id="collapse-header"
|
||||
className="collapse-header-container"
|
||||
onClick={() => setOpenObjects(!openObjects)}
|
||||
>
|
||||
<button id="collapse-header" className="collapse-header-container" onClick={() => setOpenObjects(!openObjects)}>
|
||||
<div className="header">Process Flow</div>
|
||||
<div className="arrow-container">
|
||||
<ArrowIcon />
|
||||
@@ -244,12 +195,9 @@ const Simulations: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="compare-simulations-container">
|
||||
<div className="compare-simulations-header">
|
||||
Need to Compare Layout?
|
||||
</div>
|
||||
<div className="compare-simulations-header">Need to Compare Layout?</div>
|
||||
<div className="content">
|
||||
Click '<span>Compare</span>' to review and analyze the layout
|
||||
differences between them.
|
||||
Click '<span>Compare</span>' to review and analyze the layout differences between them.
|
||||
</div>
|
||||
<button className="input" onClick={() => setComparePopUp(true)}>
|
||||
<input type="button" value={"Compare"} className="submit" />
|
||||
@@ -268,8 +216,8 @@ const Simulations: React.FC = () => {
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
clearSelectedAsset,
|
||||
projectId: projectId || '',
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || "",
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
} else {
|
||||
handleRemoveEventFromProduct();
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import { useSceneContext } from "../modules/scene/sceneContext";
|
||||
import { useProductContext } from "../modules/simulation/products/productContext";
|
||||
|
||||
const useRestStates = () => {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { clearSelectedProduct } = selectedProductStore();
|
||||
const { clearStores } = useSceneContext();
|
||||
|
||||
const resetStates = () => {
|
||||
clearSelectedProduct();
|
||||
clearStores();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
import * as THREE from 'three';
|
||||
import { CameraControls } from '@react-three/drei';
|
||||
import { ThreeEvent, useThree } from '@react-three/fiber';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import * as THREE from "three";
|
||||
import { CameraControls } from "@react-three/drei";
|
||||
import { ThreeEvent, useThree } from "@react-three/fiber";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
|
||||
import { useActiveTool, useResourceManagementId, useToggleView, useZoneAssetId, useSocketStore } from '../../../../../../store/builder/store';
|
||||
import useModuleStore, { useSubModuleStore } from '../../../../../../store/ui/useModuleStore';
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../../../simulation/products/productContext';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { getUserData } from '../../../../../../functions/getUserData';
|
||||
import { useLeftData, useTopData } from '../../../../../../store/visualization/useZone3DWidgetStore';
|
||||
import { useSelectedAsset } from '../../../../../../store/simulation/useSimulationStore';
|
||||
import { useBuilderStore } from '../../../../../../store/builder/useBuilderStore';
|
||||
import { useActiveTool, useResourceManagementId, useToggleView, useZoneAssetId, useSocketStore } from "../../../../../../store/builder/store";
|
||||
import useModuleStore, { useSubModuleStore } from "../../../../../../store/ui/useModuleStore";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../../functions/getUserData";
|
||||
import { useLeftData, useTopData } from "../../../../../../store/visualization/useZone3DWidgetStore";
|
||||
import { useSelectedAsset } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useBuilderStore } from "../../../../../../store/builder/useBuilderStore";
|
||||
|
||||
import { upsertProductOrEventApi } from '../../../../../../services/simulation/products/UpsertProductOrEventApi';
|
||||
import { deleteFloorAssetApi } from '../../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi';
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { deleteFloorAssetApi } from "../../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi";
|
||||
|
||||
export function useModelEventHandlers({
|
||||
boundingBox,
|
||||
groupRef,
|
||||
asset
|
||||
}: {
|
||||
boundingBox: THREE.Box3 | null,
|
||||
groupRef: React.RefObject<THREE.Group>,
|
||||
asset: Asset
|
||||
}) {
|
||||
export function useModelEventHandlers({ boundingBox, groupRef, asset }: { boundingBox: THREE.Box3 | null; groupRef: React.RefObject<THREE.Group>; asset: Asset }) {
|
||||
const { controls, gl, camera } = useThree();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { activeModule } = useModuleStore();
|
||||
@@ -37,11 +28,9 @@ export function useModelEventHandlers({
|
||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||
const { resourceManagementId, setResourceManagementId } = useResourceManagementId();
|
||||
const { removeEvent, getEventByModelUuid } = eventStore();
|
||||
const { getIsEventInProduct, addPoint, deleteEvent } = productStore();
|
||||
const { getIsEventInProduct, addPoint, deleteEvent, selectedProduct } = productStore();
|
||||
const { setSelectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const { deletableFloorAsset, setDeletableFloorAsset, selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
const { userId, organization } = getUserData();
|
||||
@@ -52,47 +41,38 @@ export function useModelEventHandlers({
|
||||
const { setTop } = useTopData();
|
||||
const { setLeft } = useLeftData();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!zoneAssetId) return
|
||||
if (!zoneAssetId) return;
|
||||
if (zoneAssetId.id === asset.modelUuid) {
|
||||
handleDblClick(asset);
|
||||
}
|
||||
|
||||
}, [zoneAssetId])
|
||||
}, [zoneAssetId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!resourceManagementId) return
|
||||
if (!resourceManagementId) return;
|
||||
if (resourceManagementId === asset.modelUuid) {
|
||||
|
||||
|
||||
handleDblClick(asset);
|
||||
}
|
||||
|
||||
}, [resourceManagementId])
|
||||
}, [resourceManagementId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedFloorAsset) {
|
||||
setZoneAssetId(null);
|
||||
}
|
||||
}, [selectedFloorAsset])
|
||||
}, [selectedFloorAsset]);
|
||||
|
||||
const handleDblClick = (asset: Asset) => {
|
||||
if (asset && activeTool === "cursor" && boundingBox && groupRef.current && (activeModule === 'builder' || (activeModule === 'simulation' && resourceManagementId))) {
|
||||
if (asset && activeTool === "cursor" && boundingBox && groupRef.current && (activeModule === "builder" || (activeModule === "simulation" && resourceManagementId))) {
|
||||
const frontView = false;
|
||||
if (frontView) {
|
||||
const size = boundingBox.getSize(new THREE.Vector3());
|
||||
@@ -114,9 +94,7 @@ export function useModelEventHandlers({
|
||||
paddingBottom: 5,
|
||||
paddingRight: 5,
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
const collisionPos = new THREE.Vector3();
|
||||
groupRef.current.getWorldPosition(collisionPos);
|
||||
|
||||
@@ -141,18 +119,16 @@ export function useModelEventHandlers({
|
||||
|
||||
const handleClick = async (evt: ThreeEvent<MouseEvent>, asset: Asset) => {
|
||||
if (leftDrag.current || toggleView) return;
|
||||
if (activeTool === 'delete' && deletableFloorAsset && deletableFloorAsset.uuid === asset.modelUuid) {
|
||||
|
||||
if (activeTool === "delete" && deletableFloorAsset && deletableFloorAsset.uuid === asset.modelUuid) {
|
||||
if (!socket?.connected) {
|
||||
// REST
|
||||
|
||||
deleteFloorAssetApi({
|
||||
modelUuid: asset.modelUuid,
|
||||
modelName: asset.modelName,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || ''
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
});
|
||||
|
||||
} else {
|
||||
// SOCKET
|
||||
|
||||
@@ -162,29 +138,24 @@ export function useModelEventHandlers({
|
||||
modelName: asset.modelName,
|
||||
socketId: socket.id,
|
||||
userId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
};
|
||||
|
||||
socket.emit('v1:model-asset:delete', data)
|
||||
socket.emit("v1:model-asset:delete", data);
|
||||
}
|
||||
|
||||
removeEvent(asset.modelUuid);
|
||||
const updatedEvents = deleteEvent(asset.modelUuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
})
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(asset.modelUuid);
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
type: "Scene",
|
||||
actions: [
|
||||
{
|
||||
module: "builder",
|
||||
@@ -192,16 +163,15 @@ export function useModelEventHandlers({
|
||||
asset: {
|
||||
type: "Asset",
|
||||
assetData: asset,
|
||||
timeStap: new Date().toISOString()
|
||||
}
|
||||
}
|
||||
]
|
||||
timeStap: new Date().toISOString(),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
echo.success("Model Removed!");
|
||||
|
||||
} else if (activeModule === 'simulation' && subModule === "simulations" && activeTool === 'pen') {
|
||||
if (asset.eventData && asset.eventData.type === 'Conveyor') {
|
||||
} else if (activeModule === "simulation" && subModule === "simulations" && activeTool === "pen") {
|
||||
if (asset.eventData && asset.eventData.type === "Conveyor") {
|
||||
const intersectedPoint = evt.point;
|
||||
const localPosition = groupRef.current?.worldToLocal(intersectedPoint.clone());
|
||||
if (localPosition) {
|
||||
@@ -212,49 +182,50 @@ export function useModelEventHandlers({
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action 1`,
|
||||
actionType: 'default',
|
||||
material: 'Default Material',
|
||||
actionType: "default",
|
||||
material: "Default Material",
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
triggers: [],
|
||||
},
|
||||
};
|
||||
|
||||
const event = addPoint(selectedProduct.productUuid, asset.modelUuid, conveyorPoint);
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerOver = useCallback((asset: Asset) => {
|
||||
if (activeTool === "delete" && activeModule === 'builder') {
|
||||
const handlePointerOver = useCallback(
|
||||
(asset: Asset) => {
|
||||
if (activeTool === "delete" && activeModule === "builder") {
|
||||
if (deletableFloorAsset && deletableFloorAsset.uuid === asset.modelUuid) {
|
||||
return;
|
||||
} else {
|
||||
setDeletableFloorAsset(groupRef.current);
|
||||
}
|
||||
}
|
||||
}, [activeTool, activeModule, deletableFloorAsset]);
|
||||
},
|
||||
[activeTool, activeModule, deletableFloorAsset]
|
||||
);
|
||||
|
||||
const handlePointerOut = useCallback((evt: ThreeEvent<MouseEvent>, asset: Asset) => {
|
||||
const handlePointerOut = useCallback(
|
||||
(evt: ThreeEvent<MouseEvent>, asset: Asset) => {
|
||||
if (evt.intersections.length === 0 && activeTool === "delete" && deletableFloorAsset && deletableFloorAsset.uuid === asset.modelUuid) {
|
||||
setDeletableFloorAsset(null);
|
||||
}
|
||||
}, [activeTool, deletableFloorAsset]);
|
||||
},
|
||||
[activeTool, deletableFloorAsset]
|
||||
);
|
||||
|
||||
const handleContextMenu = (asset: Asset, evt: ThreeEvent<MouseEvent>) => {
|
||||
if (rightDrag.current || toggleView) return;
|
||||
if (activeTool === "cursor" && subModule === 'simulations') {
|
||||
if (activeTool === "cursor" && subModule === "simulations") {
|
||||
if (asset.modelUuid) {
|
||||
const canvasElement = gl.domElement;
|
||||
const isInProduct = getIsEventInProduct(selectedProduct.productUuid, asset.modelUuid);
|
||||
@@ -270,12 +241,12 @@ export function useModelEventHandlers({
|
||||
clearSelectedAsset();
|
||||
}
|
||||
} else {
|
||||
clearSelectedAsset()
|
||||
clearSelectedAsset();
|
||||
}
|
||||
} else {
|
||||
clearSelectedAsset()
|
||||
}
|
||||
clearSelectedAsset();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
@@ -309,23 +280,22 @@ export function useModelEventHandlers({
|
||||
}
|
||||
};
|
||||
|
||||
canvasElement.addEventListener('pointerdown', onPointerDown);
|
||||
canvasElement.addEventListener('pointermove', onPointerMove);
|
||||
canvasElement.addEventListener('pointerup', onPointerUp);
|
||||
canvasElement.addEventListener("pointerdown", onPointerDown);
|
||||
canvasElement.addEventListener("pointermove", onPointerMove);
|
||||
canvasElement.addEventListener("pointerup", onPointerUp);
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener('pointerdown', onPointerDown);
|
||||
canvasElement.removeEventListener('pointermove', onPointerMove);
|
||||
canvasElement.removeEventListener('pointerup', onPointerUp);
|
||||
}
|
||||
|
||||
}, [gl])
|
||||
canvasElement.removeEventListener("pointerdown", onPointerDown);
|
||||
canvasElement.removeEventListener("pointermove", onPointerMove);
|
||||
canvasElement.removeEventListener("pointerup", onPointerUp);
|
||||
};
|
||||
}, [gl]);
|
||||
|
||||
return {
|
||||
handleDblClick,
|
||||
handleClick,
|
||||
handlePointerOver,
|
||||
handlePointerOut,
|
||||
handleContextMenu
|
||||
handleContextMenu,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { upsertProductOrEventApi } from "../../../../../services/simulation/prod
|
||||
import { handleAssetPositionSnap } from "./functions/handleAssetPositionSnap";
|
||||
import DistanceFindingControls from "./distanceFindingControls";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import useModuleStore from "../../../../../store/ui/useModuleStore";
|
||||
@@ -22,8 +21,6 @@ function MoveControls3D({ boundingBoxRef }: any) {
|
||||
const { toggleView } = useToggleView();
|
||||
const { toolMode } = useToolMode();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { socket } = useSocketStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
@@ -172,7 +169,7 @@ function MoveControls3D({ boundingBoxRef }: any) {
|
||||
canvasElement?.removeEventListener("keyup", onKeyUp);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [camera, controls, scene, toggleView, toolMode, selectedAssets, socket, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, keyEvent, initialStates]);
|
||||
}, [camera, controls, scene, toggleView, toolMode, selectedAssets, socket, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, keyEvent, initialStates, productStore]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeModule !== "builder" || toolMode !== "cursor" || toggleView) {
|
||||
@@ -345,7 +342,7 @@ function MoveControls3D({ boundingBoxRef }: any) {
|
||||
|
||||
if (movedAsset.userData.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(movedAsset.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, movedAsset.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(productStore.getState().selectedProduct.productUuid, movedAsset.userData.modelUuid);
|
||||
|
||||
if (eventData) {
|
||||
eventStore.getState().updateEvent(movedAsset.userData.modelUuid, {
|
||||
@@ -355,13 +352,13 @@ function MoveControls3D({ boundingBoxRef }: any) {
|
||||
}
|
||||
|
||||
if (productData) {
|
||||
const event = productStore.getState().updateEvent(selectedProduct.productUuid, movedAsset.userData.modelUuid, {
|
||||
const event = productStore.getState().updateEvent(productStore.getState().selectedProduct.productUuid, movedAsset.userData.modelUuid, {
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z],
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
updateBackend(productStore.getState().selectedProduct.productName, productStore.getState().selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
newFloorItem.eventData = eventData;
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useContextActionStore, useSocketStore, useToggleView, useToolMode } fro
|
||||
import * as Types from "../../../../../types/world/worldTypes";
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
@@ -19,8 +18,6 @@ function RotateControls3D() {
|
||||
const { toggleView } = useToggleView();
|
||||
const { toolMode } = useToolMode();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { socket } = useSocketStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
@@ -302,7 +299,7 @@ function RotateControls3D() {
|
||||
|
||||
if (obj.userData.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(obj.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, obj.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(productStore.getState().selectedProduct.productUuid, obj.userData.modelUuid);
|
||||
|
||||
if (eventData) {
|
||||
eventStore.getState().updateEvent(obj.userData.modelUuid, {
|
||||
@@ -312,13 +309,13 @@ function RotateControls3D() {
|
||||
}
|
||||
|
||||
if (productData) {
|
||||
const event = productStore.getState().updateEvent(selectedProduct.productUuid, obj.userData.modelUuid, {
|
||||
const event = productStore.getState().updateEvent(productStore.getState().selectedProduct.productUuid, obj.userData.modelUuid, {
|
||||
position: positionArray,
|
||||
rotation: rotationArray,
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
updateBackend(productStore.getState().selectedProduct.productName, productStore.getState().selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
|
||||
newFloorItem.eventData = eventData;
|
||||
@@ -391,7 +388,7 @@ function RotateControls3D() {
|
||||
setIsRotating(false);
|
||||
setIsIndividualRotating(false);
|
||||
clearSelection();
|
||||
}, [rotatedObjects, eventStore, productStore, selectedProduct, updateBackend, projectId, updateAsset, organization, socket, selectedVersion, userId, initialPositions, initialRotations]);
|
||||
}, [rotatedObjects, eventStore, productStore, updateBackend, projectId, updateAsset, organization, socket, selectedVersion, userId, initialPositions, initialRotations]);
|
||||
|
||||
const clearSelection = () => {
|
||||
setPastedObjects([]);
|
||||
|
||||
@@ -8,7 +8,6 @@ import useModuleStore from "../../../../../store/ui/useModuleStore";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { useContextActionStore, useSocketStore, useToggleView, useToolMode } from "../../../../../store/builder/store";
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import DuplicationControls3D from "./duplicationControls3D";
|
||||
@@ -34,8 +33,6 @@ const SelectionControls3D: React.FC = () => {
|
||||
const { removeAsset, getAssetById, selectedAssets, setSelectedAssets, movedObjects, rotatedObjects, copiedObjects, pastedObjects, duplicatedObjects, setPastedObjects, setDuplicatedObjects } = assetStore();
|
||||
const selectionBox = useMemo(() => new SelectionBox(camera, scene), [camera, scene]);
|
||||
const { selectedVersion } = versionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const isDragging = useRef(false);
|
||||
@@ -206,7 +203,7 @@ const SelectionControls3D: React.FC = () => {
|
||||
helper.dispose();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, movedObjects, socket, rotatedObjects, activeModule, toolMode, selectedDecal, selectedWall, selectedAisle, selectedFloor, selectedFloorAsset, selectedWallAsset]);
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, copiedObjects, pastedObjects, duplicatedObjects, movedObjects, socket, rotatedObjects, activeModule, toolMode, selectedDecal, selectedWall, selectedAisle, selectedFloor, selectedFloorAsset, selectedWallAsset, productStore]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeModule !== "builder" || (toolMode !== "cursor" && toolMode !== "Move-Asset" && toolMode !== "Rotate-Asset") || toggleView) {
|
||||
@@ -294,7 +291,7 @@ const SelectionControls3D: React.FC = () => {
|
||||
const updatedEvents = productStore.getState().deleteEvent(selectedMesh.uuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
updateBackend(productStore.getState().selectedProduct.productName, productStore.getState().selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(selectedMesh.uuid);
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useRef, useEffect, useState, useCallback } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { TransformControls } from "@react-three/drei";
|
||||
import { useSocketStore, useToolMode } from "../../../../../store/builder/store";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
@@ -19,8 +18,6 @@ function TransformControls3D() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
|
||||
const { socket } = useSocketStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore, versionStore } = useSceneContext();
|
||||
const { push3D, subscribeUndoRedo } = undoRedo3DStore();
|
||||
const { updateAsset, getAssetById, selectedAssets, setSelectedAssets } = assetStore();
|
||||
@@ -93,7 +90,7 @@ function TransformControls3D() {
|
||||
|
||||
if (asset.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(asset.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, asset.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(productStore.getState().selectedProduct.productUuid, asset.modelUuid);
|
||||
|
||||
if (eventData) {
|
||||
eventStore.getState().updateEvent(asset.modelUuid, {
|
||||
@@ -103,13 +100,13 @@ function TransformControls3D() {
|
||||
}
|
||||
|
||||
if (productData) {
|
||||
const event = productStore.getState().updateEvent(selectedProduct.productUuid, asset.modelUuid, {
|
||||
const event = productStore.getState().updateEvent(productStore.getState().selectedProduct.productUuid, asset.modelUuid, {
|
||||
position: [obj.position.x, obj.position.y, obj.position.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
updateBackend(productStore.getState().selectedProduct.productName, productStore.getState().selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,7 +146,7 @@ function TransformControls3D() {
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
});
|
||||
}, [selectedAssets, setSelectedAssets, getAssetById, updateAsset, eventStore, productStore, selectedProduct, updateBackend, projectId, organization, socket, selectedVersion, userId, push3D]);
|
||||
}, [selectedAssets, setSelectedAssets, getAssetById, updateAsset, eventStore, productStore, updateBackend, projectId, organization, socket, selectedVersion, userId, push3D]);
|
||||
|
||||
useEffect(() => {
|
||||
const temp = tempObjectRef.current;
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useParams } from "react-router-dom";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { TransformControls } from "@react-three/drei";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useProductContext } from "../../../simulation/products/productContext";
|
||||
import { getUserData } from "../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../sceneContext";
|
||||
import { useObjectPosition, useObjectRotation, useActiveTool, useSocketStore } from "../../../../store/builder/store";
|
||||
@@ -22,8 +21,6 @@ export default function TransformControl() {
|
||||
const { setObjectRotation } = useObjectRotation();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { socket } = useSocketStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore, versionStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { updateAsset, getAssetById } = assetStore();
|
||||
@@ -53,7 +50,7 @@ export default function TransformControl() {
|
||||
}
|
||||
|
||||
function handleMouseUp() {
|
||||
if (!selectedProduct || !selectedFloorAsset) return;
|
||||
if (!productStore.getState().selectedProduct || !selectedFloorAsset) return;
|
||||
if (selectedFloorAsset) {
|
||||
setObjectPosition(selectedFloorAsset.position);
|
||||
setObjectRotation({
|
||||
@@ -66,7 +63,7 @@ export default function TransformControl() {
|
||||
if (asset) {
|
||||
if (asset.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(asset.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, asset.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(productStore.getState().selectedProduct.productUuid, asset.modelUuid);
|
||||
|
||||
if (eventData) {
|
||||
eventStore.getState().updateEvent(asset.modelUuid, {
|
||||
@@ -76,13 +73,13 @@ export default function TransformControl() {
|
||||
}
|
||||
|
||||
if (productData) {
|
||||
const event = productStore.getState().updateEvent(selectedProduct.productUuid, asset.modelUuid, {
|
||||
const event = productStore.getState().updateEvent(productStore.getState().selectedProduct.productUuid, asset.modelUuid, {
|
||||
position: [selectedFloorAsset.position.x, 0, selectedFloorAsset.position.z] as [number, number, number],
|
||||
rotation: [selectedFloorAsset.rotation.x, selectedFloorAsset.rotation.y, selectedFloorAsset.rotation.z] as [number, number, number],
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
updateBackend(productStore.getState().selectedProduct.productName, productStore.getState().selectedProduct.productUuid, projectId || "", event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { useSocketStore } from "../../../../../store/builder/store";
|
||||
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
@@ -11,29 +10,22 @@ import { deleteFloorAssetApi } from "../../../../../services/factoryBuilder/asse
|
||||
|
||||
function use3DRedoHandler() {
|
||||
const { undoRedo3DStore, assetStore, productStore, eventStore, versionStore } = useSceneContext();
|
||||
const { deleteEvent } = productStore();
|
||||
const { deleteEvent, selectedProduct } = productStore();
|
||||
const { addEvent, removeEvent } = eventStore();
|
||||
const { updateAsset, removeAsset, addAsset } = assetStore();
|
||||
const { redo3D, peekRedo3D } = undoRedo3DStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { socket } = useSocketStore();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
@@ -41,87 +33,104 @@ function use3DRedoHandler() {
|
||||
const redoData = peekRedo3D();
|
||||
if (!redoData) return;
|
||||
|
||||
if (redoData.type === 'Scene') {
|
||||
if (redoData.type === "Scene") {
|
||||
const { actions } = redoData;
|
||||
|
||||
actions.forEach(action => {
|
||||
actions.forEach((action) => {
|
||||
const { actionType } = action;
|
||||
|
||||
if ('asset' in action) {
|
||||
if ("asset" in action) {
|
||||
const asset = action.asset;
|
||||
|
||||
if (actionType === 'Asset-Add') {
|
||||
if (actionType === "Asset-Add") {
|
||||
handleAdd(asset);
|
||||
} else if (actionType === 'Asset-Delete') {
|
||||
} else if (actionType === "Asset-Delete") {
|
||||
handleDelete(asset);
|
||||
} else if (actionType === 'Asset-Update') {
|
||||
} else if (actionType === "Asset-Update") {
|
||||
handleUpdate(asset);
|
||||
} else if (actionType === 'Asset-Copied') {
|
||||
} else if (actionType === "Asset-Copied") {
|
||||
handleCopy(asset);
|
||||
} else if (actionType === 'Asset-Duplicated') {
|
||||
} else if (actionType === "Asset-Duplicated") {
|
||||
handleDuplicate(asset);
|
||||
}
|
||||
|
||||
} else if ('assets' in action) {
|
||||
} else if ("assets" in action) {
|
||||
const assets = action.assets;
|
||||
|
||||
if (actionType === 'Assets-Add') {
|
||||
if (actionType === "Assets-Add") {
|
||||
assets.forEach(handleAdd);
|
||||
} else if (actionType === 'Assets-Delete') {
|
||||
} else if (actionType === "Assets-Delete") {
|
||||
assets.forEach(handleDelete);
|
||||
} else if (actionType === 'Assets-Update') {
|
||||
} else if (actionType === "Assets-Update") {
|
||||
assets.forEach(handleUpdate);
|
||||
} else if (actionType === 'Assets-Copied') {
|
||||
} else if (actionType === "Assets-Copied") {
|
||||
assets.forEach(handleCopy);
|
||||
} else if (actionType === 'Assets-Duplicated') {
|
||||
} else if (actionType === "Assets-Duplicated") {
|
||||
assets.forEach(handleDuplicate);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (redoData.type === 'UI') {
|
||||
} else if (redoData.type === "UI") {
|
||||
// Handle UI actions if needed
|
||||
}
|
||||
|
||||
redo3D();
|
||||
};
|
||||
|
||||
|
||||
const handleAdd = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': addAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': addWallAssetToBackend(asset.assetData); break;
|
||||
case "Asset":
|
||||
addAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
addWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': deleteAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': deleteWallAssetToBackend(asset.assetData); break;
|
||||
}
|
||||
case "Asset":
|
||||
deleteAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
deleteWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdate = (asset: AssetData) => {
|
||||
if (!asset.newData) return;
|
||||
switch (asset.type) {
|
||||
case 'Asset': updateAssetToBackend(asset.newData.modelUuid, asset.newData); break;
|
||||
case 'WallAsset': updateWallAssetToBackend(asset.newData.modelUuid, asset.newData); break;
|
||||
}
|
||||
case "Asset":
|
||||
updateAssetToBackend(asset.newData.modelUuid, asset.newData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
updateWallAssetToBackend(asset.newData.modelUuid, asset.newData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': copyAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': copyWallAssetToBackend(asset.assetData); break;
|
||||
}
|
||||
case "Asset":
|
||||
copyAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
copyWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDuplicate = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': duplicateAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': duplicateWallAssetToBackend(asset.assetData); break;
|
||||
case "Asset":
|
||||
duplicateAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
duplicateWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const addAssetToBackend = (assetData: Asset) => {
|
||||
addAsset(assetData);
|
||||
@@ -137,9 +146,9 @@ function use3DRedoHandler() {
|
||||
isVisible: true,
|
||||
eventData: {},
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (assetData.eventData) {
|
||||
@@ -159,17 +168,16 @@ function use3DRedoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: data.eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteAssetToBackend = (assetData: Asset) => {
|
||||
if (!socket?.connected) {
|
||||
@@ -178,11 +186,10 @@ function use3DRedoHandler() {
|
||||
deleteFloorAssetApi({
|
||||
modelUuid: assetData.modelUuid,
|
||||
modelName: assetData.modelName,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || ''
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
@@ -191,27 +198,22 @@ function use3DRedoHandler() {
|
||||
modelName: assetData.modelName,
|
||||
socketId: socket.id,
|
||||
userId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
};
|
||||
|
||||
socket.emit('v1:model-asset:delete', data)
|
||||
socket.emit("v1:model-asset:delete", data);
|
||||
}
|
||||
|
||||
removeEvent(assetData.modelUuid);
|
||||
const updatedEvents = deleteEvent(assetData.modelUuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
})
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(assetData.modelUuid);
|
||||
}
|
||||
};
|
||||
|
||||
const updateAssetToBackend = (modelUuid: string, updatedData: Asset) => {
|
||||
updateAsset(modelUuid, updatedData);
|
||||
@@ -226,9 +228,9 @@ function use3DRedoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (!socket?.connected) {
|
||||
@@ -242,17 +244,16 @@ function use3DRedoHandler() {
|
||||
rotation: { x: updatedData.rotation[0], y: updatedData.rotation[1], z: updatedData.rotation[2] },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const copyAssetToBackend = (assetData: Asset) => {
|
||||
addAsset(assetData);
|
||||
@@ -268,9 +269,9 @@ function use3DRedoHandler() {
|
||||
isVisible: true,
|
||||
eventData: {},
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (assetData.eventData) {
|
||||
@@ -290,17 +291,16 @@ function use3DRedoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: data.eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const duplicateAssetToBackend = (assetData: Asset) => {
|
||||
addAsset(assetData);
|
||||
@@ -316,9 +316,9 @@ function use3DRedoHandler() {
|
||||
isVisible: true,
|
||||
eventData: {},
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (assetData.eventData) {
|
||||
@@ -338,37 +338,26 @@ function use3DRedoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: data.eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
//SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const addWallAssetToBackend = (assetData: WallAsset) => {
|
||||
const addWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
}
|
||||
const deleteWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
const deleteWallAssetToBackend = (assetData: WallAsset) => {
|
||||
const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => {};
|
||||
|
||||
}
|
||||
const copyWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => {
|
||||
|
||||
}
|
||||
|
||||
const copyWallAssetToBackend = (assetData: WallAsset) => {
|
||||
|
||||
}
|
||||
|
||||
const duplicateWallAssetToBackend = (assetData: WallAsset) => {
|
||||
|
||||
}
|
||||
const duplicateWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
return { handleRedo };
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
import { useSocketStore } from "../../../../../store/builder/store";
|
||||
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
@@ -11,29 +10,22 @@ import { deleteFloorAssetApi } from "../../../../../services/factoryBuilder/asse
|
||||
|
||||
function use3DUndoHandler() {
|
||||
const { undoRedo3DStore, assetStore, productStore, eventStore, versionStore } = useSceneContext();
|
||||
const { deleteEvent } = productStore();
|
||||
const { deleteEvent, selectedProduct } = productStore();
|
||||
const { addEvent, removeEvent } = eventStore();
|
||||
const { updateAsset, removeAsset, addAsset } = assetStore();
|
||||
const { undo3D, peekUndo3D } = undoRedo3DStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { socket } = useSocketStore();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
@@ -41,86 +33,103 @@ function use3DUndoHandler() {
|
||||
const unDoData = peekUndo3D();
|
||||
if (!unDoData) return;
|
||||
|
||||
if (unDoData.type === 'Scene') {
|
||||
if (unDoData.type === "Scene") {
|
||||
const { actions } = unDoData;
|
||||
|
||||
actions.forEach(action => {
|
||||
actions.forEach((action) => {
|
||||
const { actionType } = action;
|
||||
|
||||
if ('asset' in action) {
|
||||
if ("asset" in action) {
|
||||
const asset = action.asset;
|
||||
|
||||
if (actionType === 'Asset-Add') {
|
||||
if (actionType === "Asset-Add") {
|
||||
handleDelete(asset);
|
||||
} else if (actionType === 'Asset-Delete') {
|
||||
} else if (actionType === "Asset-Delete") {
|
||||
handleAdd(asset);
|
||||
} else if (actionType === 'Asset-Update') {
|
||||
} else if (actionType === "Asset-Update") {
|
||||
handleUpdate(asset);
|
||||
} else if (actionType === 'Asset-Copied') {
|
||||
} else if (actionType === "Asset-Copied") {
|
||||
handleCopy(asset);
|
||||
} else if (actionType === 'Asset-Duplicated') {
|
||||
} else if (actionType === "Asset-Duplicated") {
|
||||
handleDuplicate(asset);
|
||||
}
|
||||
|
||||
} else if ('assets' in action) {
|
||||
} else if ("assets" in action) {
|
||||
const assets = action.assets;
|
||||
|
||||
if (actionType === 'Assets-Add') {
|
||||
if (actionType === "Assets-Add") {
|
||||
assets.forEach(handleDelete);
|
||||
} else if (actionType === 'Assets-Delete') {
|
||||
} else if (actionType === "Assets-Delete") {
|
||||
assets.forEach(handleAdd);
|
||||
} else if (actionType === 'Assets-Update') {
|
||||
} else if (actionType === "Assets-Update") {
|
||||
assets.forEach(handleUpdate);
|
||||
} else if (actionType === 'Assets-Copied') {
|
||||
} else if (actionType === "Assets-Copied") {
|
||||
assets.forEach(handleCopy);
|
||||
} else if (actionType === 'Assets-Duplicated') {
|
||||
} else if (actionType === "Assets-Duplicated") {
|
||||
assets.forEach(handleDuplicate);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (unDoData.type === 'UI') {
|
||||
} else if (unDoData.type === "UI") {
|
||||
// Handle UI actions if needed
|
||||
}
|
||||
|
||||
undo3D();
|
||||
};
|
||||
|
||||
|
||||
const handleAdd = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': addAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': addWallAssetToBackend(asset.assetData); break;
|
||||
case "Asset":
|
||||
addAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
addWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': deleteAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': deleteWallAssetToBackend(asset.assetData); break;
|
||||
}
|
||||
case "Asset":
|
||||
deleteAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
deleteWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdate = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': updateAssetToBackend(asset.assetData.modelUuid, asset.assetData); break;
|
||||
case 'WallAsset': updateWallAssetToBackend(asset.assetData.modelUuid, asset.assetData); break;
|
||||
}
|
||||
case "Asset":
|
||||
updateAssetToBackend(asset.assetData.modelUuid, asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
updateWallAssetToBackend(asset.assetData.modelUuid, asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': copyAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': copyWallAssetToBackend(asset.assetData); break;
|
||||
}
|
||||
case "Asset":
|
||||
copyAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
copyWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDuplicate = (asset: AssetData) => {
|
||||
switch (asset.type) {
|
||||
case 'Asset': duplicateAssetToBackend(asset.assetData); break;
|
||||
case 'WallAsset': duplicateWallAssetToBackend(asset.assetData); break;
|
||||
case "Asset":
|
||||
duplicateAssetToBackend(asset.assetData);
|
||||
break;
|
||||
case "WallAsset":
|
||||
duplicateWallAssetToBackend(asset.assetData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const addAssetToBackend = (assetData: Asset) => {
|
||||
addAsset(assetData);
|
||||
@@ -136,9 +145,9 @@ function use3DUndoHandler() {
|
||||
isVisible: true,
|
||||
eventData: {},
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (assetData.eventData) {
|
||||
@@ -158,17 +167,16 @@ function use3DUndoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
eventData: data.eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteAssetToBackend = (assetData: Asset) => {
|
||||
if (!socket?.connected) {
|
||||
@@ -177,11 +185,10 @@ function use3DUndoHandler() {
|
||||
deleteFloorAssetApi({
|
||||
modelUuid: assetData.modelUuid,
|
||||
modelName: assetData.modelName,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || ''
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
@@ -190,27 +197,22 @@ function use3DUndoHandler() {
|
||||
modelName: assetData.modelName,
|
||||
socketId: socket.id,
|
||||
userId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
};
|
||||
|
||||
socket.emit('v1:model-asset:delete', data)
|
||||
socket.emit("v1:model-asset:delete", data);
|
||||
}
|
||||
|
||||
removeEvent(assetData.modelUuid);
|
||||
const updatedEvents = deleteEvent(assetData.modelUuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
})
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(assetData.modelUuid);
|
||||
}
|
||||
};
|
||||
|
||||
const updateAssetToBackend = (modelUuid: string, updatedData: Asset) => {
|
||||
updateAsset(modelUuid, updatedData);
|
||||
@@ -225,9 +227,9 @@ function use3DUndoHandler() {
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket?.id,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId
|
||||
userId,
|
||||
};
|
||||
|
||||
if (!socket?.connected) {
|
||||
@@ -241,17 +243,16 @@ function use3DUndoHandler() {
|
||||
rotation: { x: updatedData.rotation[0], y: updatedData.rotation[1], z: updatedData.rotation[2] },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId,
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const copyAssetToBackend = (assetData: Asset) => {
|
||||
if (!socket?.connected) {
|
||||
@@ -260,11 +261,10 @@ function use3DUndoHandler() {
|
||||
deleteFloorAssetApi({
|
||||
modelUuid: assetData.modelUuid,
|
||||
modelName: assetData.modelName,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || ''
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
@@ -273,27 +273,22 @@ function use3DUndoHandler() {
|
||||
modelName: assetData.modelName,
|
||||
socketId: socket.id,
|
||||
userId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
};
|
||||
|
||||
socket.emit('v1:model-asset:delete', data)
|
||||
socket.emit("v1:model-asset:delete", data);
|
||||
}
|
||||
|
||||
removeEvent(assetData.modelUuid);
|
||||
const updatedEvents = deleteEvent(assetData.modelUuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
})
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(assetData.modelUuid);
|
||||
}
|
||||
};
|
||||
|
||||
const duplicateAssetToBackend = (assetData: Asset) => {
|
||||
if (!socket?.connected) {
|
||||
@@ -302,11 +297,10 @@ function use3DUndoHandler() {
|
||||
deleteFloorAssetApi({
|
||||
modelUuid: assetData.modelUuid,
|
||||
modelName: assetData.modelName,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId: projectId || ''
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId: projectId || "",
|
||||
});
|
||||
} else {
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
@@ -315,47 +309,32 @@ function use3DUndoHandler() {
|
||||
modelName: assetData.modelName,
|
||||
socketId: socket.id,
|
||||
userId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
projectId
|
||||
}
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
};
|
||||
|
||||
socket.emit('v1:model-asset:delete', data)
|
||||
socket.emit("v1:model-asset:delete", data);
|
||||
}
|
||||
|
||||
removeEvent(assetData.modelUuid);
|
||||
const updatedEvents = deleteEvent(assetData.modelUuid);
|
||||
|
||||
updatedEvents.forEach((event) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
})
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || "", event);
|
||||
});
|
||||
|
||||
removeAsset(assetData.modelUuid);
|
||||
}
|
||||
};
|
||||
|
||||
const addWallAssetToBackend = (assetData: WallAsset) => {
|
||||
const addWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
}
|
||||
const deleteWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
const deleteWallAssetToBackend = (assetData: WallAsset) => {
|
||||
const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => {};
|
||||
|
||||
}
|
||||
const copyWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
const updateWallAssetToBackend = (modelUuid: string, updatedData: WallAsset) => {
|
||||
|
||||
}
|
||||
|
||||
const copyWallAssetToBackend = (assetData: WallAsset) => {
|
||||
|
||||
}
|
||||
|
||||
const duplicateWallAssetToBackend = (assetData: WallAsset) => {
|
||||
|
||||
}
|
||||
const duplicateWallAssetToBackend = (assetData: WallAsset) => {};
|
||||
|
||||
return { handleUndo };
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import * as THREE from 'three';
|
||||
import * as THREE from "three";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { usePlayButtonStore, useAnimationPlaySpeed, usePauseButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
interface SpawnInstance {
|
||||
lastSpawnTime: number | null;
|
||||
@@ -24,28 +23,32 @@ export function useSpawnHandler() {
|
||||
const { materialStore, conveyorStore, productStore } = useSceneContext();
|
||||
const { addMaterial } = materialStore();
|
||||
const { getConveyorById } = conveyorStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid } = productStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct } = productStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
const [activeSpawns, setActiveSpawns] = useState<Map<string, SpawnInstance>>(new Map());
|
||||
|
||||
const getConveyorPausedState = useCallback((action: ConveyorAction) => {
|
||||
const getConveyorPausedState = useCallback(
|
||||
(action: ConveyorAction) => {
|
||||
const modelUuid = getModelUuidByActionUuid(selectedProduct.productUuid, action.actionUuid);
|
||||
if (!modelUuid) return false;
|
||||
|
||||
const conveyor = getConveyorById(modelUuid);
|
||||
if (!conveyor) return false;
|
||||
return conveyor.isPaused;
|
||||
}, [getConveyorById, getModelUuidByActionUuid, selectedProduct.productUuid]);
|
||||
},
|
||||
[getConveyorById, getModelUuidByActionUuid, selectedProduct.productUuid]
|
||||
);
|
||||
|
||||
const shouldPauseSpawn = useCallback((action: ConveyorAction) => {
|
||||
const shouldPauseSpawn = useCallback(
|
||||
(action: ConveyorAction) => {
|
||||
return isPaused || getConveyorPausedState(action);
|
||||
}, [isPaused, getConveyorPausedState]);
|
||||
},
|
||||
[isPaused, getConveyorPausedState]
|
||||
);
|
||||
|
||||
const clearAllSpawns = useCallback(() => {
|
||||
setActiveSpawns(new Map());
|
||||
@@ -59,9 +62,10 @@ export function useSpawnHandler() {
|
||||
|
||||
const spawnLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const createNewMaterial = useCallback((materialType: string, action: ConveyorAction) => {
|
||||
const createNewMaterial = useCallback(
|
||||
(materialType: string, action: ConveyorAction) => {
|
||||
const modelUuid = getModelUuidByActionUuid(selectedProduct.productUuid, action.actionUuid);
|
||||
const pointUuid = getPointUuidByActionUuid(selectedProduct.productUuid, action.actionUuid);
|
||||
if (!modelUuid || !pointUuid) return;
|
||||
@@ -79,37 +83,36 @@ export function useSpawnHandler() {
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
actionUuid: action.actionUuid,
|
||||
},
|
||||
};
|
||||
|
||||
if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid
|
||||
) {
|
||||
if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid && action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid && action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid) {
|
||||
newMaterial.next = {
|
||||
modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
|
||||
pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}, [addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]);
|
||||
},
|
||||
[addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]
|
||||
);
|
||||
|
||||
useFrame(() => {
|
||||
const currentTime = performance.now();
|
||||
const completedActions: string[] = [];
|
||||
let hasChanges = false;
|
||||
|
||||
activeSpawns.forEach(spawn => {
|
||||
activeSpawns.forEach((spawn) => {
|
||||
const isPausedNow = shouldPauseSpawn(spawn.params.action);
|
||||
|
||||
if (isPausedNow && !spawn.isPaused) {
|
||||
if (spawn.lastSpawnTime === null) {
|
||||
spawn.remainingTime = Math.max(0, (spawn.params.intervalMs / speed) - (currentTime - spawn.startTime));
|
||||
spawn.remainingTime = Math.max(0, spawn.params.intervalMs / speed - (currentTime - spawn.startTime));
|
||||
} else {
|
||||
spawn.remainingTime = Math.max(0, (spawn.params.intervalMs / speed) - (currentTime - spawn.lastSpawnTime));
|
||||
spawn.remainingTime = Math.max(0, spawn.params.intervalMs / speed - (currentTime - spawn.lastSpawnTime));
|
||||
}
|
||||
spawn.pauseStartTime = currentTime;
|
||||
spawn.isPaused = true;
|
||||
@@ -177,10 +180,10 @@ export function useSpawnHandler() {
|
||||
}
|
||||
|
||||
if (hasChanges || completedActions.length > 0) {
|
||||
setActiveSpawns(prevSpawns => {
|
||||
setActiveSpawns((prevSpawns) => {
|
||||
const newSpawns = new Map(prevSpawns);
|
||||
|
||||
completedActions.forEach(actionUuid => {
|
||||
completedActions.forEach((actionUuid) => {
|
||||
newSpawns.delete(actionUuid);
|
||||
});
|
||||
|
||||
@@ -190,12 +193,12 @@ export function useSpawnHandler() {
|
||||
});
|
||||
|
||||
const handleSpawn = useCallback((action: ConveyorAction) => {
|
||||
if (!action || action.actionType !== 'spawn') return;
|
||||
if (!action || action.actionType !== "spawn") return;
|
||||
|
||||
const { material, spawnInterval = 0, spawnCount = 1, actionUuid } = action;
|
||||
const intervalMs = spawnInterval * 1000;
|
||||
|
||||
setActiveSpawns(prevSpawns => {
|
||||
setActiveSpawns((prevSpawns) => {
|
||||
const newSpawns = new Map(prevSpawns);
|
||||
|
||||
if (newSpawns.has(actionUuid)) {
|
||||
@@ -210,11 +213,11 @@ export function useSpawnHandler() {
|
||||
material,
|
||||
intervalMs,
|
||||
totalCount: spawnCount,
|
||||
action: action
|
||||
action: action,
|
||||
},
|
||||
pauseStartTime: 0,
|
||||
remainingTime: 0,
|
||||
isPaused: false
|
||||
isPaused: false,
|
||||
});
|
||||
|
||||
return newSpawns;
|
||||
@@ -229,6 +232,6 @@ export function useSpawnHandler() {
|
||||
|
||||
return {
|
||||
handleSpawn,
|
||||
clearAllSpawns
|
||||
clearAllSpawns,
|
||||
};
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function usePickAndDropHandler() {
|
||||
const { materialStore, craneStore, productStore } = useSceneContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
const { incrementCraneLoad, addCurrentMaterial, addCurrentAction } = craneStore();
|
||||
|
||||
const pickAndDropLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePickAndDrop = useCallback((action: CraneAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'pickAndDrop' || !materialId) return;
|
||||
const handlePickAndDrop = useCallback(
|
||||
(action: CraneAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "pickAndDrop" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -28,8 +26,9 @@ export function usePickAndDropHandler() {
|
||||
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
|
||||
|
||||
pickAndDropLogStatus(material.materialName, `performing pickAndDrop action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
},
|
||||
[getMaterialById]
|
||||
);
|
||||
|
||||
return {
|
||||
handlePickAndDrop,
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useManufacturerHandler() {
|
||||
const { materialStore, humanStore, productStore } = useSceneContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore();
|
||||
|
||||
const manufactureLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleManufacturer = useCallback((action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'manufacturer' || !materialId) return;
|
||||
const handleManufacturer = useCallback(
|
||||
(action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "manufacturer" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -28,8 +26,9 @@ export function useManufacturerHandler() {
|
||||
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
|
||||
|
||||
manufactureLogStatus(material.materialName, `performing manufacturer action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
},
|
||||
[getMaterialById]
|
||||
);
|
||||
|
||||
return {
|
||||
handleManufacturer,
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useWorkerHandler() {
|
||||
const { materialStore, humanStore, productStore } = useSceneContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
const { incrementHumanLoad, addCurrentMaterial, addCurrentAction } = humanStore();
|
||||
|
||||
const workerLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleWorker = useCallback((action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'worker' || !materialId) return;
|
||||
const handleWorker = useCallback(
|
||||
(action: HumanAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "worker" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -28,8 +26,9 @@ export function useWorkerHandler() {
|
||||
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
|
||||
|
||||
workerLogStatus(material.materialName, `performing worker action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
},
|
||||
[getMaterialById]
|
||||
);
|
||||
|
||||
return {
|
||||
handleWorker,
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useProcessHandler() {
|
||||
const { materialStore, machineStore, productStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { getMaterialById, setMaterial } = materialStore();
|
||||
const { addCurrentAction } = machineStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
|
||||
const processLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.log(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleProcess = useCallback((action: MachineAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'process' || !materialId) return;
|
||||
const handleProcess = useCallback(
|
||||
(action: MachineAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "process" || !materialId) return;
|
||||
|
||||
const { swapMaterial: newMaterialType } = action;
|
||||
|
||||
@@ -31,10 +29,11 @@ export function useProcessHandler() {
|
||||
|
||||
processLogStatus(material.materialName, `Swapped to ${newMaterialType}`);
|
||||
processLogStatus(material.materialName, `starts Process action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
},
|
||||
[getMaterialById]
|
||||
);
|
||||
|
||||
return {
|
||||
handleProcess
|
||||
handleProcess,
|
||||
};
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function usePickAndPlaceHandler() {
|
||||
const { materialStore, armBotStore, productStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { addCurrentAction } = armBotStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
|
||||
const pickAndPlaceLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.warn(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePickAndPlace = useCallback((action: RoboticArmAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'pickAndPlace' || !materialId) return;
|
||||
const handlePickAndPlace = useCallback(
|
||||
(action: RoboticArmAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "pickAndPlace" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -24,16 +22,12 @@ export function usePickAndPlaceHandler() {
|
||||
|
||||
if (!modelUuid) return;
|
||||
|
||||
addCurrentAction(
|
||||
modelUuid,
|
||||
action.actionUuid,
|
||||
material.materialType,
|
||||
material.materialId
|
||||
);
|
||||
addCurrentAction(modelUuid, action.actionUuid, material.materialType, material.materialId);
|
||||
|
||||
pickAndPlaceLogStatus(material.materialName, `is going to be picked by armBot ${modelUuid}`);
|
||||
|
||||
}, [getMaterialById, getModelUuidByActionUuid, selectedProduct.productUuid, addCurrentAction]);
|
||||
},
|
||||
[getMaterialById, getModelUuidByActionUuid, selectedProduct.productUuid, addCurrentAction]
|
||||
);
|
||||
|
||||
return {
|
||||
handlePickAndPlace,
|
||||
|
||||
@@ -2,21 +2,18 @@ import { useCallback, useState, useEffect, useRef } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore, useAnimationPlaySpeed } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useHumanEventManager } from "../../../human/eventManager/useHumanEventManager";
|
||||
|
||||
export function useRetrieveHandler() {
|
||||
const { materialStore, armBotStore, machineStore, vehicleStore, storageUnitStore, conveyorStore, craneStore, productStore, humanStore, assetStore, humanEventManagerRef } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { addMaterial } = materialStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid, selectedProduct } = productStore();
|
||||
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore();
|
||||
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
|
||||
const { getConveyorById } = conveyorStore();
|
||||
const { getHumanById, incrementHumanLoad, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore();
|
||||
const { getCraneById, incrementCraneLoad, addCurrentMaterial: addCurrentMaterialToCrane, addCurrentAction: addCurrentActionToCrane } = craneStore();
|
||||
const { getAssetById, setCurrentAnimation } = assetStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getArmBotById, addCurrentAction } = armBotStore();
|
||||
const { getMachineById } = machineStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
@@ -25,7 +22,7 @@ export function useRetrieveHandler() {
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { addHumanToMonitor } = useHumanEventManager();
|
||||
|
||||
const [activeRetrievals, setActiveRetrievals] = useState<Map<string, { action: StorageAction, isProcessing: boolean, lastCheckTime: number }>>(new Map());
|
||||
const [activeRetrievals, setActiveRetrievals] = useState<Map<string, { action: StorageAction; isProcessing: boolean; lastCheckTime: number }>>(new Map());
|
||||
const retrievalTimeRef = useRef<Map<string, number>>(new Map());
|
||||
const retrievalCountRef = useRef<Map<string, number>>(new Map());
|
||||
const monitoredHumansRef = useRef<Set<string>>(new Set());
|
||||
@@ -36,9 +33,10 @@ export function useRetrieveHandler() {
|
||||
|
||||
const retrieveLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const createNewMaterial = useCallback((materialId: string, materialType: string, action: StorageAction, visible: boolean = false) => {
|
||||
const createNewMaterial = useCallback(
|
||||
(materialId: string, materialType: string, action: StorageAction, visible: boolean = false) => {
|
||||
const modelUuid = getModelUuidByActionUuid(selectedProduct.productUuid, action.actionUuid);
|
||||
const pointUuid = getPointUuidByActionUuid(selectedProduct.productUuid, action.actionUuid);
|
||||
if (!modelUuid || !pointUuid) return null;
|
||||
@@ -56,18 +54,20 @@ export function useRetrieveHandler() {
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
actionUuid: action.actionUuid,
|
||||
},
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
actionUuid: action.actionUuid,
|
||||
},
|
||||
};
|
||||
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}, [addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]);
|
||||
},
|
||||
[addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying && !initialDelayComplete) {
|
||||
@@ -102,9 +102,7 @@ export function useRetrieveHandler() {
|
||||
activeRetrievals.forEach((retrieval, actionUuid) => {
|
||||
if (retrieval.isProcessing) return;
|
||||
|
||||
const storageUnit = getStorageUnitById(
|
||||
getModelUuidByActionUuid(selectedProduct.productUuid, retrieval.action.actionUuid) ?? ''
|
||||
);
|
||||
const storageUnit = getStorageUnitById(getModelUuidByActionUuid(selectedProduct.productUuid, retrieval.action.actionUuid) ?? "");
|
||||
|
||||
if (!storageUnit) {
|
||||
completedActions.push(actionUuid);
|
||||
@@ -120,18 +118,15 @@ export function useRetrieveHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
const triggeredModel = getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
retrieval.action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid
|
||||
);
|
||||
const triggeredModel = getEventByModelUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid);
|
||||
|
||||
if (!triggeredModel) return;
|
||||
|
||||
let isIdle = false;
|
||||
|
||||
if (triggeredModel.type === 'roboticArm') {
|
||||
if (triggeredModel.type === "roboticArm") {
|
||||
const armBot = getArmBotById(triggeredModel.modelUuid);
|
||||
isIdle = (armBot && !armBot.isActive && armBot.state === 'idle' && !armBot.currentAction) || false;
|
||||
isIdle = (armBot && !armBot.isActive && armBot.state === "idle" && !armBot.currentAction) || false;
|
||||
|
||||
if (!armBot) return;
|
||||
if (!retrievalTimeRef.current.has(actionUuid) && isIdle) {
|
||||
@@ -143,73 +138,49 @@ export function useRetrieveHandler() {
|
||||
const minIdleTimeBeforeFirstRetrieval = 5000 / speed;
|
||||
const minDelayBetweenRetrievals = 5000 / speed;
|
||||
|
||||
const canProceedFirstRetrieval = idleStartTime !== undefined &&
|
||||
(currentTime - idleStartTime) >= minIdleTimeBeforeFirstRetrieval;
|
||||
const canProceedFirstRetrieval = idleStartTime !== undefined && currentTime - idleStartTime >= minIdleTimeBeforeFirstRetrieval;
|
||||
|
||||
const lastRetrievalTime = retrievalTimeRef.current.get(`${actionUuid}_last`) ?? null;
|
||||
const canProceedSubsequent = lastRetrievalTime === null ||
|
||||
(currentTime - lastRetrievalTime) >= minDelayBetweenRetrievals;
|
||||
const canProceedSubsequent = lastRetrievalTime === null || currentTime - lastRetrievalTime >= minDelayBetweenRetrievals;
|
||||
|
||||
const canProceed = lastRetrievalTime === null ? canProceedFirstRetrieval : canProceedSubsequent;
|
||||
|
||||
if (isIdle && canProceed) {
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: true,
|
||||
lastCheckTime: currentTime
|
||||
lastCheckTime: currentTime,
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
|
||||
if (retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid);
|
||||
const storageAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
if (action && action.triggers.length > 0 && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || "");
|
||||
if (model && storageAction) {
|
||||
if (model.type === 'vehicle') {
|
||||
if (model.type === "vehicle") {
|
||||
const vehicle = getVehicleById(model.modelUuid);
|
||||
if (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
if (vehicle && !vehicle.isActive && vehicle.state === "idle" && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
|
||||
addCurrentAction(
|
||||
triggeredModel.modelUuid,
|
||||
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||
material.materialType,
|
||||
material.materialId
|
||||
);
|
||||
addCurrentAction(triggeredModel.modelUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? "", material.materialType, material.materialId);
|
||||
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
|
||||
addCurrentAction(
|
||||
triggeredModel.modelUuid,
|
||||
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
|
||||
material.materialType,
|
||||
material.materialId
|
||||
);
|
||||
addCurrentAction(triggeredModel.modelUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? "", material.materialType, material.materialId);
|
||||
retrieveLogStatus(material.materialName, `is being picked by ${armBot?.modelName}`);
|
||||
}
|
||||
}
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
@@ -220,19 +191,16 @@ export function useRetrieveHandler() {
|
||||
});
|
||||
|
||||
retrievalTimeRef.current.set(actionUuid, currentTime);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else if (!isIdle) {
|
||||
retrievalTimeRef.current.delete(actionUuid);
|
||||
}
|
||||
|
||||
} else if (triggeredModel.type === 'vehicle') {
|
||||
} else if (triggeredModel.type === "vehicle") {
|
||||
const vehicle = getVehicleById(triggeredModel.modelUuid);
|
||||
isIdle = (vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) || false;
|
||||
isIdle = (vehicle && !vehicle.isActive && vehicle.state === "idle" && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) || false;
|
||||
|
||||
if (!vehicle) return;
|
||||
|
||||
@@ -248,21 +216,19 @@ export function useRetrieveHandler() {
|
||||
const idleStartTime = retrievalTimeRef.current.get(actionUuid);
|
||||
const lastRetrievalTime = retrievalTimeRef.current.get(`${actionUuid}_last`) ?? null;
|
||||
|
||||
const canProceedFirstRetrieval = idleStartTime !== undefined &&
|
||||
(currentTime - idleStartTime) >= minIdleTimeBeforeFirstRetrieval;
|
||||
const canProceedFirstRetrieval = idleStartTime !== undefined && currentTime - idleStartTime >= minIdleTimeBeforeFirstRetrieval;
|
||||
|
||||
const canProceedSubsequent = lastRetrievalTime === null ||
|
||||
(currentTime - lastRetrievalTime) >= minDelayBetweenRetrievals;
|
||||
const canProceedSubsequent = lastRetrievalTime === null || currentTime - lastRetrievalTime >= minDelayBetweenRetrievals;
|
||||
|
||||
const canProceed = lastRetrievalTime === null ? canProceedFirstRetrieval : canProceedSubsequent;
|
||||
|
||||
if (isIdle && canProceed) {
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: true,
|
||||
lastCheckTime: currentTime
|
||||
lastCheckTime: currentTime,
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
@@ -270,16 +236,9 @@ export function useRetrieveHandler() {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
if (vehicle?.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
const triggeredAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid || ''
|
||||
);
|
||||
const triggeredAction = getActionByUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid || "");
|
||||
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, triggeredAction as StorageAction);
|
||||
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
@@ -291,7 +250,7 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
@@ -307,12 +266,12 @@ export function useRetrieveHandler() {
|
||||
retrievalTimeRef.current.delete(actionUuid);
|
||||
retrievalTimeRef.current.delete(`${actionUuid}_last`);
|
||||
}
|
||||
} else if (triggeredModel.type === 'human') {
|
||||
} else if (triggeredModel.type === "human") {
|
||||
const human = getHumanById(triggeredModel.modelUuid);
|
||||
const humanAsset = getAssetById(triggeredModel.modelUuid);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
|
||||
if (!action || action.actionType !== 'worker') return;
|
||||
if (!action || action.actionType !== "worker") return;
|
||||
|
||||
const currentCount = retrievalCountRef.current.get(actionUuid) ?? 0;
|
||||
|
||||
@@ -322,26 +281,20 @@ export function useRetrieveHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (human && !human.isScheduled && human.state === 'idle' && human.currentLoad < action.loadCapacity) {
|
||||
const triggeredModel = action.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid
|
||||
? getEventByModelUuid(selectedProduct.productUuid, action.triggers[0].triggeredAsset.triggeredModel.modelUuid)
|
||||
: null;
|
||||
if (human && !human.isScheduled && human.state === "idle" && human.currentLoad < action.loadCapacity) {
|
||||
const triggeredModel = action.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid ? getEventByModelUuid(selectedProduct.productUuid, action.triggers[0].triggeredAsset.triggeredModel.modelUuid) : null;
|
||||
|
||||
const storageAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
|
||||
if (triggeredModel?.type === 'vehicle') {
|
||||
if (triggeredModel?.type === "vehicle") {
|
||||
const model = getVehicleById(triggeredModel.modelUuid);
|
||||
if (model && !model.isActive && model.state === 'idle' && model.isPicking && model.currentLoad < model.point.action.loadCapacity) {
|
||||
if (humanAsset?.animationState?.current === 'idle') {
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === 'pickup' && humanAsset.animationState.isCompleted) {
|
||||
if (model && !model.isActive && model.state === "idle" && model.isPicking && model.currentLoad < model.point.action.loadCapacity) {
|
||||
if (humanAsset?.animationState?.current === "idle") {
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === "pickup" && humanAsset.animationState.isCompleted) {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -355,19 +308,15 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (triggeredModel?.type === 'roboticArm') {
|
||||
} else if (triggeredModel?.type === "roboticArm") {
|
||||
const armBot = getArmBotById(triggeredModel.modelUuid);
|
||||
if (armBot && !armBot.isActive && armBot.state === 'idle' && !armBot.currentAction) {
|
||||
if (humanAsset?.animationState?.current === 'idle') {
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === 'pickup' && humanAsset.animationState.isCompleted) {
|
||||
if (armBot && !armBot.isActive && armBot.state === "idle" && !armBot.currentAction) {
|
||||
if (humanAsset?.animationState?.current === "idle") {
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === "pickup" && humanAsset.animationState.isCompleted) {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -381,19 +330,15 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (triggeredModel?.type === 'transfer') {
|
||||
} else if (triggeredModel?.type === "transfer") {
|
||||
const model = getConveyorById(triggeredModel.modelUuid);
|
||||
if (model && !model.isPaused) {
|
||||
if (humanAsset?.animationState?.current === 'idle') {
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === 'pickup' && humanAsset.animationState.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "idle") {
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
} else if (humanAsset?.animationState?.current === "pickup" && humanAsset.animationState.isCompleted) {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -407,25 +352,25 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (triggeredModel?.type === 'machine') {
|
||||
} else if (triggeredModel?.type === "machine") {
|
||||
const machine = getMachineById(triggeredModel.modelUuid);
|
||||
if (machine && !machine.isActive && machine.state === 'idle' && !machine.currentAction) {
|
||||
if (machine && !machine.isActive && machine.state === "idle" && !machine.currentAction) {
|
||||
if (!monitoredHumansRef.current.has(human.modelUuid)) {
|
||||
addHumanToMonitor(human.modelUuid, () => {
|
||||
if (humanAsset?.animationState?.current === 'idle') {
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
addHumanToMonitor(
|
||||
human.modelUuid,
|
||||
() => {
|
||||
if (humanAsset?.animationState?.current === "idle") {
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
}
|
||||
}, action.actionUuid);
|
||||
},
|
||||
action.actionUuid
|
||||
);
|
||||
}
|
||||
monitoredHumansRef.current.add(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current === 'pickup' && humanAsset.animationState.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "pickup" && humanAsset.animationState.isCompleted) {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -439,14 +384,10 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (triggeredModel?.type === 'storageUnit') {
|
||||
} else if (triggeredModel?.type === "storageUnit") {
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, storageAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -459,49 +400,46 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (triggeredModel?.type === 'crane') {
|
||||
} else if (triggeredModel?.type === "crane") {
|
||||
const crane = getCraneById(triggeredModel.modelUuid);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || "");
|
||||
const currentCount = retrievalCountRef.current.get(actionUuid) ?? 0;
|
||||
|
||||
if (!crane) return;
|
||||
|
||||
const hasLock = cranePickupLockRef.current.get(crane.modelUuid) || false;
|
||||
|
||||
if (action && action.actionType === 'pickAndDrop' && !hasLock && !crane.isCarrying && !crane.isActive && crane.currentLoad < (action?.maxPickUpCount || 0)) {
|
||||
if (action && action.actionType === "pickAndDrop" && !hasLock && !crane.isCarrying && !crane.isActive && crane.currentLoad < (action?.maxPickUpCount || 0)) {
|
||||
const material = getLastMaterial(storageUnit.modelUuid);
|
||||
if (material) {
|
||||
if (action.triggers[0].triggeredAsset?.triggeredModel.modelUuid && action.triggers[0].triggeredAsset.triggeredAction?.actionUuid) {
|
||||
const human = getEventByModelUuid(selectedProduct.productUuid, action.triggers[0].triggeredAsset.triggeredModel.modelUuid);
|
||||
if (human && human.type === 'human') {
|
||||
if (human && human.type === "human") {
|
||||
if (!monitoredHumansRef.current.has(human.modelUuid)) {
|
||||
addHumanToMonitor(human.modelUuid, () => {
|
||||
addHumanToMonitor(
|
||||
human.modelUuid,
|
||||
() => {
|
||||
incrementCraneLoad(crane.modelUuid, 1);
|
||||
addCurrentActionToCrane(crane.modelUuid, action.actionUuid, material.materialType, material.materialId);
|
||||
addCurrentMaterialToCrane(crane.modelUuid, material.materialType, material.materialId);
|
||||
cranePickupLockRef.current.set(crane.modelUuid, true);
|
||||
monitoredHumansRef.current.delete(human.modelUuid);
|
||||
}, action.triggers[0].triggeredAsset.triggeredAction?.actionUuid)
|
||||
},
|
||||
action.triggers[0].triggeredAsset.triggeredAction?.actionUuid
|
||||
);
|
||||
}
|
||||
monitoredHumansRef.current.add(human.modelUuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (crane.isCarrying && crane.currentPhase === 'pickup-drop' && hasLock) {
|
||||
} else if (crane.isCarrying && crane.currentPhase === "pickup-drop" && hasLock) {
|
||||
cranePickupLockRef.current.set(crane.modelUuid, false);
|
||||
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const triggeredAction = getActionByUuid(
|
||||
selectedProduct.productUuid,
|
||||
action?.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid || ''
|
||||
);
|
||||
const triggeredAction = getActionByUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid || "");
|
||||
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
triggeredAction as StorageAction
|
||||
);
|
||||
const material = createNewMaterial(lastMaterial.materialId, lastMaterial.materialType, triggeredAction as StorageAction);
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
@@ -509,28 +447,27 @@ export function useRetrieveHandler() {
|
||||
}
|
||||
}
|
||||
} else if (!action) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid || "");
|
||||
if (action) {
|
||||
addCurrentActionToCrane(crane.modelUuid, action.actionUuid, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (hasChanges || completedActions.length > 0) {
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
completedActions.forEach(actionUuid => newRetrievals.delete(actionUuid));
|
||||
completedActions.forEach((actionUuid) => newRetrievals.delete(actionUuid));
|
||||
return newRetrievals;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const handleRetrieve = useCallback((action: StorageAction) => {
|
||||
if (!action || action.actionType !== 'retrieve') return;
|
||||
if (!action || action.actionType !== "retrieve") return;
|
||||
|
||||
setActiveRetrievals(prev => {
|
||||
setActiveRetrievals((prev) => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(action.actionUuid, {
|
||||
action,
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useStoreHandler() {
|
||||
const { materialStore, storageUnitStore, productStore } = useSceneContext();
|
||||
const { getMaterialById, removeMaterial, setEndTime } = materialStore();
|
||||
const { addCurrentMaterial, updateCurrentLoad } = storageUnitStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
|
||||
const storeLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleStore = useCallback((action: StorageAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'store' || !materialId) return;
|
||||
const handleStore = useCallback(
|
||||
(action: StorageAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "store" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -29,8 +27,9 @@ export function useStoreHandler() {
|
||||
updateCurrentLoad(modelUuid, 1);
|
||||
|
||||
storeLogStatus(material.materialName, `performed Store action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
},
|
||||
[getMaterialById]
|
||||
);
|
||||
|
||||
return {
|
||||
handleStore,
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { useCallback } from "react";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
|
||||
export function useTravelHandler() {
|
||||
const { materialStore, vehicleStore, productStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { getMaterialById } = materialStore();
|
||||
const { getModelUuidByActionUuid } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByActionUuid, selectedProduct } = productStore();
|
||||
const { incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
|
||||
|
||||
const travelLogStatus = (materialUuid: string, status: string) => {
|
||||
echo.info(`${materialUuid}, ${status}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTravel = useCallback((action: VehicleAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'travel' || !materialId) return;
|
||||
const handleTravel = useCallback(
|
||||
(action: VehicleAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== "travel" || !materialId) return;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
@@ -28,8 +26,9 @@ export function useTravelHandler() {
|
||||
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
|
||||
|
||||
travelLogStatus(material.materialName, `is triggering travel from ${modelUuid}`);
|
||||
|
||||
}, [addCurrentMaterial, getMaterialById, getModelUuidByActionUuid, incrementVehicleLoad, selectedProduct.productUuid]);
|
||||
},
|
||||
[addCurrentMaterial, getMaterialById, getModelUuidByActionUuid, incrementVehicleLoad, selectedProduct.productUuid]
|
||||
);
|
||||
|
||||
return {
|
||||
handleTravel,
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { CompareProduct, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
|
||||
import { usePlayButtonStore } from '../../../../store/ui/usePlayButtonStore';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useEffect } from "react";
|
||||
import { CompareProduct, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from "../../../../store/builder/store";
|
||||
import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
export default function ROIData() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { inputValues } = useInputValues();
|
||||
const { productionCapacityData } = useProductionCapacityData()
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { productionCapacityData } = useProductionCapacityData();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { setRoiSummaryData } = useROISummaryData();
|
||||
const { productStore } = useSceneContext();
|
||||
const { getProductById } = productStore();
|
||||
const { getProductById, selectedProduct } = productStore();
|
||||
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
|
||||
const { machineActiveTime } = useMachineUptime();
|
||||
const { machineIdleTime } = useMachineDowntime();
|
||||
const { throughputData } = useThroughPutData()
|
||||
const { throughputData } = useThroughPutData();
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) return;
|
||||
@@ -47,10 +44,7 @@ export default function ROIData() {
|
||||
const shiftsPerDay = parseFloat(inputValues["Shifts / day"]);
|
||||
const workingDaysPerYear = parseFloat(inputValues["Working days / year"]);
|
||||
|
||||
if (!isNaN(electricityCost) && !isNaN(fixedCost) && !isNaN(laborCost) && !isNaN(maintenanceCost) &&
|
||||
!isNaN(materialCost) && !isNaN(productionPeriod) && !isNaN(salvageValue) && !isNaN(sellingPrice) &&
|
||||
!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && productionCapacityData > 0) {
|
||||
|
||||
if (!isNaN(electricityCost) && !isNaN(fixedCost) && !isNaN(laborCost) && !isNaN(maintenanceCost) && !isNaN(materialCost) && !isNaN(productionPeriod) && !isNaN(salvageValue) && !isNaN(sellingPrice) && !isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && productionCapacityData > 0) {
|
||||
// const totalHoursPerYear = shiftLength * shiftsPerDay * workingDaysPerYear;
|
||||
// const annualProductionUnits = productionCapacityData * totalHoursPerYear;
|
||||
// const annualRevenue = annualProductionUnits * sellingPrice;
|
||||
@@ -120,20 +114,20 @@ export default function ROIData() {
|
||||
// setCompareProductsData([...prev, newData]);
|
||||
// }
|
||||
|
||||
const Annual_units = throughputData * workingDaysPerYear
|
||||
const Total_units = Annual_units * productionPeriod
|
||||
const Annual_units = throughputData * workingDaysPerYear;
|
||||
const Total_units = Annual_units * productionPeriod;
|
||||
|
||||
const Total_revenue = Total_units * sellingPrice
|
||||
const Total_variable_cost = Total_units * (materialCost + (laborCost))
|
||||
const Total_revenue = Total_units * sellingPrice;
|
||||
const Total_variable_cost = Total_units * (materialCost + laborCost);
|
||||
|
||||
const Total_fixed_cost = (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear * productionPeriod
|
||||
const Total_cost = Total_variable_cost + Total_fixed_cost
|
||||
const Total_fixed_cost = (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear * productionPeriod;
|
||||
const Total_cost = Total_variable_cost + Total_fixed_cost;
|
||||
|
||||
const Net_profit = Total_revenue - Total_cost + (salvageValue * workingDaysPerYear * productionPeriod)
|
||||
const Net_profit = Total_revenue - Total_cost + salvageValue * workingDaysPerYear * productionPeriod;
|
||||
|
||||
const ROI = (Net_profit / initialInvestment) * 100
|
||||
const ROI = (Net_profit / initialInvestment) * 100;
|
||||
|
||||
const Annual_net_profit = (Annual_units * (sellingPrice - materialCost - laborCost)) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + (salvageValue * workingDaysPerYear)
|
||||
const Annual_net_profit = Annual_units * (sellingPrice - materialCost - laborCost) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + salvageValue * workingDaysPerYear;
|
||||
const Payback_period_years = initialInvestment / Annual_net_profit;
|
||||
|
||||
setRoiSummaryData({
|
||||
@@ -143,15 +137,14 @@ export default function ROIData() {
|
||||
totalCost: Total_cost,
|
||||
revenueGenerated: Total_revenue,
|
||||
netProfit: Net_profit > 0 ? Net_profit : 0,
|
||||
netLoss: Net_profit < 0 ? -Net_profit : 0
|
||||
netLoss: Net_profit < 0 ? -Net_profit : 0,
|
||||
});
|
||||
|
||||
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
const prev = useCompareProductDataStore.getState().compareProductsData;
|
||||
const newData: CompareProduct = {
|
||||
productUuid: productData?.productUuid ?? '',
|
||||
productName: productData?.productName ?? '',
|
||||
productUuid: productData?.productUuid ?? "",
|
||||
productName: productData?.productName ?? "",
|
||||
simulationData: {
|
||||
// costPerUnit: costPerUnit,
|
||||
// workingDaysPerYear: workingDaysPerYear,
|
||||
@@ -168,12 +161,10 @@ export default function ROIData() {
|
||||
machineIdleTime: machineIdleTime,
|
||||
machineActiveTime: machineActiveTime,
|
||||
throughputData: throughputData,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const existingIndex = prev.findIndex((item: CompareProduct) =>
|
||||
item.productUuid === productData?.productUuid
|
||||
);
|
||||
const existingIndex = prev.findIndex((item: CompareProduct) => item.productUuid === productData?.productUuid);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
const updated = [...prev];
|
||||
@@ -183,12 +174,9 @@ export default function ROIData() {
|
||||
setCompareProductsData([...prev, newData]);
|
||||
}
|
||||
}
|
||||
|
||||
}, [inputValues, productionCapacityData, throughputData, isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, [compareProductsData])
|
||||
useEffect(() => {}, [compareProductsData]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { useEffect } from 'react';
|
||||
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
|
||||
import { useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
|
||||
import { usePlayButtonStore } from '../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { useEffect } from "react";
|
||||
import { determineExecutionMachineSequences } from "../../simulator/functions/determineExecutionMachineSequences";
|
||||
import { useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from "../../../../store/builder/store";
|
||||
import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
export default function ThroughPutData() {
|
||||
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { products, getProductById } = productStore();
|
||||
const { products, getProductById, selectedProduct } = productStore();
|
||||
const { armBots } = armBotStore();
|
||||
const { vehicles } = vehicleStore();
|
||||
const { machines } = machineStore();
|
||||
@@ -21,14 +18,14 @@ export default function ThroughPutData() {
|
||||
const { machineIdleTime, setMachineIdleTime } = useMachineDowntime();
|
||||
const { materialCycleTime, setMaterialCycleTime } = useMaterialCycle();
|
||||
const { setProcessBar } = useProcessBar();
|
||||
const { setThroughputData } = useThroughPutData()
|
||||
const { setThroughputData } = useThroughPutData();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { inputValues } = useInputValues();
|
||||
|
||||
// Setting machine count
|
||||
let totalItems = 0;
|
||||
let totalActiveTime = 0;
|
||||
let totalIdleTime = 0
|
||||
let totalIdleTime = 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
@@ -42,7 +39,7 @@ export default function ThroughPutData() {
|
||||
setProcessBar([]);
|
||||
setThroughputData(0);
|
||||
}
|
||||
}, [isPlaying])
|
||||
}, [isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
@@ -50,15 +47,16 @@ export default function ThroughPutData() {
|
||||
const fetchProductSequenceData = async () => {
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
if (productData) {
|
||||
const productSequenceData = await determineExecutionMachineSequences([productData])
|
||||
const productSequenceData = await determineExecutionMachineSequences([productData]);
|
||||
if (productSequenceData?.length > 0) {
|
||||
productSequenceData.forEach((sequence) => {
|
||||
sequence.forEach((item) => {
|
||||
if (item.type === "roboticArm") {
|
||||
armBots.filter(arm => arm.modelUuid === item.modelUuid)
|
||||
.forEach(arm => {
|
||||
armBots
|
||||
.filter((arm) => arm.modelUuid === item.modelUuid)
|
||||
.forEach((arm) => {
|
||||
if (arm.activeTime > 0) {
|
||||
process.push({ modelid: arm.modelUuid, modelName: arm.modelName, activeTime: arm?.activeTime })
|
||||
process.push({ modelid: arm.modelUuid, modelName: arm.modelName, activeTime: arm?.activeTime });
|
||||
totalActiveTime += arm.activeTime;
|
||||
}
|
||||
if (arm.idleTime > 0) {
|
||||
@@ -66,10 +64,11 @@ export default function ThroughPutData() {
|
||||
}
|
||||
});
|
||||
} else if (item.type === "vehicle") {
|
||||
vehicles.filter(vehicle => vehicle.modelUuid === item.modelUuid)
|
||||
.forEach(vehicle => {
|
||||
vehicles
|
||||
.filter((vehicle) => vehicle.modelUuid === item.modelUuid)
|
||||
.forEach((vehicle) => {
|
||||
if (vehicle.activeTime > 0) {
|
||||
process.push({ modelid: vehicle.modelUuid, modelName: vehicle.modelName, activeTime: vehicle?.activeTime })
|
||||
process.push({ modelid: vehicle.modelUuid, modelName: vehicle.modelName, activeTime: vehicle?.activeTime });
|
||||
|
||||
totalActiveTime += vehicle.activeTime;
|
||||
}
|
||||
@@ -78,10 +77,11 @@ export default function ThroughPutData() {
|
||||
}
|
||||
});
|
||||
} else if (item.type === "machine") {
|
||||
machines.filter(machine => machine.modelUuid === item.modelUuid)
|
||||
.forEach(machine => {
|
||||
machines
|
||||
.filter((machine) => machine.modelUuid === item.modelUuid)
|
||||
.forEach((machine) => {
|
||||
if (machine.activeTime > 0) {
|
||||
process.push({ modelid: machine.modelUuid, modelName: machine.modelName, activeTime: machine?.activeTime })
|
||||
process.push({ modelid: machine.modelUuid, modelName: machine.modelName, activeTime: machine?.activeTime });
|
||||
totalActiveTime += machine.activeTime;
|
||||
}
|
||||
if (machine.idleTime > 0) {
|
||||
@@ -89,15 +89,17 @@ export default function ThroughPutData() {
|
||||
}
|
||||
});
|
||||
} else if (item.type === "transfer") {
|
||||
conveyors.filter(conveyor => conveyor.modelUuid === item.modelUuid)
|
||||
.forEach(conveyor => {
|
||||
conveyors
|
||||
.filter((conveyor) => conveyor.modelUuid === item.modelUuid)
|
||||
.forEach((conveyor) => {
|
||||
if (conveyor.activeTime > 0) {
|
||||
// totalActiveTime += conveyor.activeTime;
|
||||
}
|
||||
});
|
||||
} else if (item.type === "storageUnit") {
|
||||
storageUnits.filter(storage => storage.modelUuid === item.modelUuid)
|
||||
.forEach(storage => {
|
||||
storageUnits
|
||||
.filter((storage) => storage.modelUuid === item.modelUuid)
|
||||
.forEach((storage) => {
|
||||
if (storage.activeTime > 0) {
|
||||
// totalActiveTime += storage.activeTime;
|
||||
}
|
||||
@@ -108,13 +110,12 @@ export default function ThroughPutData() {
|
||||
totalItems += sequence.length;
|
||||
});
|
||||
|
||||
|
||||
setMachineCount(totalItems);
|
||||
setMachineActiveTime(totalActiveTime);
|
||||
setMachineIdleTime(totalIdleTime);
|
||||
let arr = process.map((item: any) => ({
|
||||
name: item.modelName,
|
||||
completed: Math.round((item.activeTime / totalActiveTime) * 100)
|
||||
completed: Math.round((item.activeTime / totalActiveTime) * 100),
|
||||
}));
|
||||
setProcessBar(arr);
|
||||
}
|
||||
@@ -136,12 +137,12 @@ export default function ThroughPutData() {
|
||||
if (productData) {
|
||||
const productSequenceData = await determineExecutionMachineSequences([productData]);
|
||||
if (productSequenceData?.length > 0) {
|
||||
productSequenceData.forEach(sequence => {
|
||||
sequence.forEach(item => {
|
||||
productSequenceData.forEach((sequence) => {
|
||||
sequence.forEach((item) => {
|
||||
if (item.type === "roboticArm") {
|
||||
armBots
|
||||
.filter(arm => arm.modelUuid === item.modelUuid)
|
||||
.forEach(arm => {
|
||||
.filter((arm) => arm.modelUuid === item.modelUuid)
|
||||
.forEach((arm) => {
|
||||
if (arm.isActive) {
|
||||
anyArmActive = true;
|
||||
} else {
|
||||
@@ -151,8 +152,8 @@ export default function ThroughPutData() {
|
||||
}
|
||||
if (item.type === "vehicle") {
|
||||
vehicles
|
||||
.filter(vehicle => vehicle.modelUuid === item.modelUuid)
|
||||
.forEach(vehicle => {
|
||||
.filter((vehicle) => vehicle.modelUuid === item.modelUuid)
|
||||
.forEach((vehicle) => {
|
||||
if (vehicle.isActive) {
|
||||
anyVehicleActive = true;
|
||||
} else {
|
||||
@@ -162,8 +163,8 @@ export default function ThroughPutData() {
|
||||
}
|
||||
if (item.type === "machine") {
|
||||
machines
|
||||
.filter(machine => machine.modelUuid === item.modelUuid)
|
||||
.forEach(machine => {
|
||||
.filter((machine) => machine.modelUuid === item.modelUuid)
|
||||
.forEach((machine) => {
|
||||
if (machine.isActive) {
|
||||
anyMachineActive = true;
|
||||
} else {
|
||||
@@ -178,7 +179,6 @@ export default function ThroughPutData() {
|
||||
|
||||
const allInactive = !anyArmActive && !anyVehicleActive && !anyMachineActive;
|
||||
if (materialHistory.length > 0) {
|
||||
|
||||
let totalCycleTimeSum = 0;
|
||||
let cycleCount = 0;
|
||||
|
||||
@@ -207,7 +207,7 @@ export default function ThroughPutData() {
|
||||
return () => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
};
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid])
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid]);
|
||||
|
||||
useEffect(() => {
|
||||
const shiftLength = parseFloat(inputValues["Shift length"]);
|
||||
@@ -222,8 +222,5 @@ export default function ThroughPutData() {
|
||||
}
|
||||
}, [materialCycleTime, machineCount, isPlaying, inputValues]);
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
// import { findConveyorSubsequence } from '../../../simulator/functions/getConveyorSequencesInProduct';
|
||||
|
||||
function ConveyorInstance({ conveyor }: { readonly conveyor: ConveyorStatus }) {
|
||||
|
||||
const { materialStore, conveyorStore, productStore } = useSceneContext();
|
||||
const { getProductById } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getProductById, selectedProduct } = productStore();
|
||||
const { getMaterialsByCurrentModelUuid } = materialStore();
|
||||
const { setConveyorPaused } = conveyorStore();
|
||||
|
||||
@@ -19,8 +16,7 @@ function ConveyorInstance({ conveyor }: { readonly conveyor: ConveyorStatus }) {
|
||||
|
||||
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid);
|
||||
if (conveyorMaterials && conveyorMaterials.length > 0) {
|
||||
|
||||
const hasPausedMaterials = conveyorMaterials.some(material => material.isPaused);
|
||||
const hasPausedMaterials = conveyorMaterials.some((material) => material.isPaused);
|
||||
|
||||
if (hasPausedMaterials) {
|
||||
setConveyorPaused(conveyor.modelUuid, true);
|
||||
@@ -51,17 +47,13 @@ function ConveyorInstance({ conveyor }: { readonly conveyor: ConveyorStatus }) {
|
||||
// setConveyorPaused(event.modelUuid, hasPausedMaterials);
|
||||
// }
|
||||
// });
|
||||
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('conveyor: ', conveyor);
|
||||
}, [conveyor])
|
||||
}, [conveyor]);
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export default ConveyorInstance
|
||||
export default ConveyorInstance;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { useEffect } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
export function useCraneEventManager() {
|
||||
const { craneStore, productStore, assetStore, vehicleStore, armBotStore, machineStore, craneEventManagerRef } = useSceneContext();
|
||||
@@ -11,9 +10,7 @@ export function useCraneEventManager() {
|
||||
const { getVehicleById } = vehicleStore();
|
||||
const { getArmBotById } = armBotStore();
|
||||
const { getMachineById } = machineStore();
|
||||
const { getActionByUuid, getEventByModelUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, getEventByModelUuid, selectedProduct } = productStore();
|
||||
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -29,22 +26,22 @@ export function useCraneEventManager() {
|
||||
const crane = getCraneById(craneId);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, actionUuid) as CraneAction | undefined;
|
||||
|
||||
if (!crane || !action || action.actionType !== 'pickAndDrop' || !craneEventManagerRef.current) return;
|
||||
if (!crane || !action || action.actionType !== "pickAndDrop" || !craneEventManagerRef.current) return;
|
||||
|
||||
let state = craneEventManagerRef.current.craneStates.find(c => c.craneId === craneId);
|
||||
let state = craneEventManagerRef.current.craneStates.find((c) => c.craneId === craneId);
|
||||
if (!state) {
|
||||
state = {
|
||||
craneId,
|
||||
pendingActions: [],
|
||||
currentAction: null,
|
||||
isProcessing: false
|
||||
isProcessing: false,
|
||||
};
|
||||
craneEventManagerRef.current.craneStates.push(state);
|
||||
}
|
||||
|
||||
state.pendingActions.push({
|
||||
actionUuid,
|
||||
callback
|
||||
callback,
|
||||
});
|
||||
|
||||
if (!state.isProcessing) {
|
||||
@@ -75,19 +72,19 @@ export function useCraneEventManager() {
|
||||
const { craneId, currentAction } = craneState;
|
||||
const crane = getCraneById(craneId);
|
||||
const craneAsset = getAssetById(craneId);
|
||||
const currentCraneAction = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '') as CraneAction | undefined;
|
||||
const currentCraneAction = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || "") as CraneAction | undefined;
|
||||
|
||||
if (!crane || !craneAsset || !currentCraneAction) continue;
|
||||
if (crane.isActive || crane.state !== "idle") continue;
|
||||
|
||||
if (currentCraneAction.actionType === 'pickAndDrop' && crane.currentLoad < currentCraneAction.maxPickUpCount) {
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, currentCraneAction.triggers[0].triggeredAsset?.triggeredAction?.actionUuid || '');
|
||||
if (currentCraneAction.actionType === "pickAndDrop" && crane.currentLoad < currentCraneAction.maxPickUpCount) {
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, currentCraneAction.triggers[0].triggeredAsset?.triggeredAction?.actionUuid || "");
|
||||
if (humanAction) {
|
||||
const nextEvent = getEventByModelUuid(selectedProduct.productUuid, humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid || '')
|
||||
const nextEvent = getEventByModelUuid(selectedProduct.productUuid, humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid || "");
|
||||
if (nextEvent) {
|
||||
if (nextEvent.type === 'transfer') {
|
||||
if (nextEvent.type === "transfer") {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
@@ -97,12 +94,12 @@ export function useCraneEventManager() {
|
||||
setTimeout(() => {
|
||||
completeCurrentAction(craneState);
|
||||
}, 1000);
|
||||
} else if (nextEvent.type === 'vehicle') {
|
||||
} else if (nextEvent.type === "vehicle") {
|
||||
const vehicle = getVehicleById(nextEvent.modelUuid);
|
||||
|
||||
if (vehicle && !vehicle.isActive && vehicle.currentPhase === 'picking') {
|
||||
if (vehicle && !vehicle.isActive && vehicle.currentPhase === "picking") {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
@@ -113,12 +110,12 @@ export function useCraneEventManager() {
|
||||
completeCurrentAction(craneState);
|
||||
}, 1000);
|
||||
}
|
||||
} else if (nextEvent.type === 'roboticArm') {
|
||||
} else if (nextEvent.type === "roboticArm") {
|
||||
const armBot = getArmBotById(nextEvent.modelUuid);
|
||||
|
||||
if (armBot && !armBot.isActive) {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
@@ -129,12 +126,12 @@ export function useCraneEventManager() {
|
||||
completeCurrentAction(craneState);
|
||||
}, 1000);
|
||||
}
|
||||
} else if (nextEvent.type === 'machine') {
|
||||
} else if (nextEvent.type === "machine") {
|
||||
const machine = getMachineById(nextEvent.modelUuid);
|
||||
|
||||
if (machine && !machine.isActive) {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
@@ -147,7 +144,7 @@ export function useCraneEventManager() {
|
||||
}
|
||||
} else {
|
||||
if (currentAction.actionUuid !== crane.currentAction?.actionUuid) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
}
|
||||
|
||||
@@ -165,6 +162,6 @@ export function useCraneEventManager() {
|
||||
}, 0);
|
||||
|
||||
return {
|
||||
addCraneToMonitor
|
||||
addCraneToMonitor,
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
function PillarJibAnimator({
|
||||
crane,
|
||||
@@ -11,7 +10,7 @@ function PillarJibAnimator({
|
||||
setPoints,
|
||||
animationPhase,
|
||||
setAnimationPhase,
|
||||
onAnimationComplete
|
||||
onAnimationComplete,
|
||||
}: Readonly<{
|
||||
crane: CraneStatus;
|
||||
points: [THREE.Vector3, THREE.Vector3] | null;
|
||||
@@ -22,11 +21,9 @@ function PillarJibAnimator({
|
||||
}>) {
|
||||
const { scene } = useThree();
|
||||
const { assetStore, productStore, materialStore } = useSceneContext();
|
||||
const { getActionByUuid, getPointByUuid } = productStore();
|
||||
const { getActionByUuid, getPointByUuid, selectedProduct } = productStore();
|
||||
const { resetAsset } = assetStore();
|
||||
const { setIsVisible } = materialStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
@@ -37,45 +34,40 @@ function PillarJibAnimator({
|
||||
useEffect(() => {
|
||||
if (!isPlaying || isReset) {
|
||||
resetAsset(crane.modelUuid);
|
||||
setAnimationPhase('idle');
|
||||
setAnimationPhase("idle");
|
||||
setPoints(null);
|
||||
}
|
||||
}, [isPlaying, scene, crane.modelUuid, isReset]);
|
||||
|
||||
useEffect(() => {
|
||||
const model = scene.getObjectByProperty('uuid', crane.modelUuid);
|
||||
const model = scene.getObjectByProperty("uuid", crane.modelUuid);
|
||||
|
||||
if (!model) return;
|
||||
const hook = model.getObjectByName('hook');
|
||||
const hook = model.getObjectByName("hook");
|
||||
|
||||
if (!hook) return;
|
||||
const hookWorld = new THREE.Vector3();
|
||||
hook.getWorldPosition(hookWorld);
|
||||
|
||||
if (crane.currentPhase === 'init-pickup') {
|
||||
if (crane.currentPhase === "init-pickup") {
|
||||
if (crane.currentMaterials.length > 0) {
|
||||
const materials = scene.getObjectsByProperty('uuid', crane.currentMaterials[0].materialId);
|
||||
const materials = scene.getObjectsByProperty("uuid", crane.currentMaterials[0].materialId);
|
||||
const material = materials.find((material) => material.visible === true);
|
||||
if (material) {
|
||||
const materialWorld = new THREE.Vector3();
|
||||
material.getWorldPosition(materialWorld);
|
||||
setAnimationPhase('init-hook-adjust');
|
||||
setPoints(
|
||||
[
|
||||
new THREE.Vector3(hookWorld.x, hookWorld.y, hookWorld.z),
|
||||
new THREE.Vector3(materialWorld.x, materialWorld.y + 0.5, materialWorld.z)
|
||||
]
|
||||
);
|
||||
setAnimationPhase("init-hook-adjust");
|
||||
setPoints([new THREE.Vector3(hookWorld.x, hookWorld.y, hookWorld.z), new THREE.Vector3(materialWorld.x, materialWorld.y + 0.5, materialWorld.z)]);
|
||||
}
|
||||
}
|
||||
} else if (crane.currentPhase === 'pickup-drop') {
|
||||
} else if (crane.currentPhase === "pickup-drop") {
|
||||
if (crane.currentMaterials.length > 0) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '');
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, action?.triggers[0].triggeredAsset?.triggeredAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || "");
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, action?.triggers[0].triggeredAsset?.triggeredAction?.actionUuid || "");
|
||||
|
||||
if (humanAction) {
|
||||
const point = getPointByUuid(selectedProduct.productUuid, humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid || '', humanAction.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid || '');
|
||||
const eventModel = scene.getObjectByProperty('uuid', humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid);
|
||||
const point = getPointByUuid(selectedProduct.productUuid, humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid || "", humanAction.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid || "");
|
||||
const eventModel = scene.getObjectByProperty("uuid", humanAction.triggers[0].triggeredAsset?.triggeredModel?.modelUuid);
|
||||
if (point && eventModel) {
|
||||
const pointLocal = new THREE.Vector3(...point.position);
|
||||
const pointWorld = pointLocal.clone().applyMatrix4(eventModel.matrixWorld);
|
||||
@@ -85,21 +77,21 @@ function PillarJibAnimator({
|
||||
|
||||
setIsVisible(crane.currentMaterials[0].materialId, false);
|
||||
|
||||
setAnimationPhase('init-hook-adjust');
|
||||
setAnimationPhase("init-hook-adjust");
|
||||
setPoints([startPoint, endPoint]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [crane.currentPhase])
|
||||
}, [crane.currentPhase]);
|
||||
|
||||
useEffect(() => {
|
||||
const model = scene.getObjectByProperty('uuid', crane.modelUuid);
|
||||
const model = scene.getObjectByProperty("uuid", crane.modelUuid);
|
||||
if (!model?.userData.fieldData) return;
|
||||
|
||||
const base = model.getObjectByName('base');
|
||||
const trolley = model.getObjectByName('trolley');
|
||||
const hook = model.getObjectByName('hook');
|
||||
const base = model.getObjectByName("base");
|
||||
const trolley = model.getObjectByName("trolley");
|
||||
const hook = model.getObjectByName("hook");
|
||||
|
||||
if (!base || !trolley || !hook || !points) return;
|
||||
|
||||
@@ -119,10 +111,7 @@ function PillarJibAnimator({
|
||||
|
||||
const distFromBase = new THREE.Vector2(trolleyWorld.x - baseWorld.x, trolleyWorld.z - baseWorld.z).length();
|
||||
const innerRadius = Math.max(distFromBase + trolleyMinOffset, 0.05);
|
||||
const outerRadius = Math.max(
|
||||
new THREE.Vector2(trolleyWorld.x - baseWorld.x, trolleyWorld.z - baseWorld.z).length() + trolleyMaxOffset,
|
||||
innerRadius
|
||||
);
|
||||
const outerRadius = Math.max(new THREE.Vector2(trolleyWorld.x - baseWorld.x, trolleyWorld.z - baseWorld.z).length() + trolleyMaxOffset, innerRadius);
|
||||
|
||||
const yMin = hookWorld.y + hookMaxOffset;
|
||||
const yMax = hookWorld.y + hookMinOffset;
|
||||
@@ -158,14 +147,14 @@ function PillarJibAnimator({
|
||||
}, [crane.modelUuid, points]);
|
||||
|
||||
useFrame(() => {
|
||||
if (!isPlaying || isPaused || !points || !clampedPoints || animationPhase === 'idle') return;
|
||||
if (!isPlaying || isPaused || !points || !clampedPoints || animationPhase === "idle") return;
|
||||
|
||||
const model = scene.getObjectByProperty('uuid', crane.modelUuid);
|
||||
const model = scene.getObjectByProperty("uuid", crane.modelUuid);
|
||||
if (!model) return;
|
||||
|
||||
const base = model.getObjectByName('base');
|
||||
const trolley = model.getObjectByName('trolley');
|
||||
const hook = model.getObjectByName('hook');
|
||||
const base = model.getObjectByName("base");
|
||||
const trolley = model.getObjectByName("trolley");
|
||||
const hook = model.getObjectByName("hook");
|
||||
|
||||
if (!base || !trolley || !hook || !trolley.parent || !hook.parent) return;
|
||||
|
||||
@@ -182,7 +171,7 @@ function PillarJibAnimator({
|
||||
const threshold = Math.max(0.01, 0.05 / speed);
|
||||
|
||||
switch (animationPhase) {
|
||||
case 'init-hook-adjust': {
|
||||
case "init-hook-adjust": {
|
||||
const hookWorld = new THREE.Vector3();
|
||||
hook.getWorldPosition(hookWorld);
|
||||
|
||||
@@ -194,19 +183,19 @@ function PillarJibAnimator({
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[0].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('init-rotate-base');
|
||||
setAnimationPhase("init-rotate-base");
|
||||
} else {
|
||||
hook.position.y += step;
|
||||
}
|
||||
} else {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[0].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('init-rotate-base');
|
||||
setAnimationPhase("init-rotate-base");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'init-rotate-base': {
|
||||
case "init-rotate-base": {
|
||||
const baseWorld = new THREE.Vector3();
|
||||
base.getWorldPosition(baseWorld);
|
||||
|
||||
@@ -217,10 +206,7 @@ function PillarJibAnimator({
|
||||
const currentDir = new THREE.Vector2(baseForward.x, baseForward.z).normalize();
|
||||
|
||||
const targetWorld = clampedPoints[0];
|
||||
const targetDir = new THREE.Vector2(
|
||||
targetWorld.x - baseWorld.x,
|
||||
targetWorld.z - baseWorld.z
|
||||
).normalize();
|
||||
const targetDir = new THREE.Vector2(targetWorld.x - baseWorld.x, targetWorld.z - baseWorld.z).normalize();
|
||||
|
||||
const currentAngle = Math.atan2(currentDir.y, currentDir.x);
|
||||
const targetAngle = Math.atan2(targetDir.y, targetDir.x);
|
||||
@@ -233,18 +219,18 @@ function PillarJibAnimator({
|
||||
|
||||
if (Math.abs(step) > Math.abs(angleDiff)) {
|
||||
base.rotation.y += angleDiff;
|
||||
setAnimationPhase('init-move-trolley');
|
||||
setAnimationPhase("init-move-trolley");
|
||||
} else {
|
||||
base.rotation.y += step;
|
||||
}
|
||||
} else {
|
||||
base.rotation.y += angleDiff;
|
||||
setAnimationPhase('init-move-trolley');
|
||||
setAnimationPhase("init-move-trolley");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'init-move-trolley': {
|
||||
case "init-move-trolley": {
|
||||
const baseWorld = new THREE.Vector3();
|
||||
base.getWorldPosition(baseWorld);
|
||||
|
||||
@@ -257,18 +243,18 @@ function PillarJibAnimator({
|
||||
const step = Math.sign(diff) * trolleySpeed;
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
trolley.position.x = localTarget.x;
|
||||
setAnimationPhase('init-final-hook-adjust');
|
||||
setAnimationPhase("init-final-hook-adjust");
|
||||
} else {
|
||||
trolley.position.x += step;
|
||||
}
|
||||
} else {
|
||||
trolley.position.x = localTarget.x;
|
||||
setAnimationPhase('init-final-hook-adjust');
|
||||
setAnimationPhase("init-final-hook-adjust");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'init-final-hook-adjust': {
|
||||
case "init-final-hook-adjust": {
|
||||
const hookWorld = new THREE.Vector3();
|
||||
hook.getWorldPosition(hookWorld);
|
||||
|
||||
@@ -280,19 +266,19 @@ function PillarJibAnimator({
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[0].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('first-hook-adjust');
|
||||
setAnimationPhase("first-hook-adjust");
|
||||
} else {
|
||||
hook.position.y += step;
|
||||
}
|
||||
} else {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[0].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('first-hook-adjust');
|
||||
setAnimationPhase("first-hook-adjust");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'first-hook-adjust': {
|
||||
case "first-hook-adjust": {
|
||||
const hookWorld = new THREE.Vector3();
|
||||
hook.getWorldPosition(hookWorld);
|
||||
|
||||
@@ -305,19 +291,19 @@ function PillarJibAnimator({
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
const localTarget = hook.parent.worldToLocal(targetWorld.clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('first-rotate-base');
|
||||
setAnimationPhase("first-rotate-base");
|
||||
} else {
|
||||
hook.position.y += step;
|
||||
}
|
||||
} else {
|
||||
const localTarget = hook.parent.worldToLocal(targetWorld.clone());
|
||||
hook.position.y = localTarget.y;
|
||||
setAnimationPhase('first-rotate-base');
|
||||
setAnimationPhase("first-rotate-base");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'first-rotate-base': {
|
||||
case "first-rotate-base": {
|
||||
const baseWorld = new THREE.Vector3();
|
||||
base.getWorldPosition(baseWorld);
|
||||
|
||||
@@ -328,10 +314,7 @@ function PillarJibAnimator({
|
||||
const currentDir = new THREE.Vector2(baseForward.x, baseForward.z).normalize();
|
||||
|
||||
const targetWorld = clampedPoints[1];
|
||||
const targetDir = new THREE.Vector2(
|
||||
targetWorld.x - baseWorld.x,
|
||||
targetWorld.z - baseWorld.z
|
||||
).normalize();
|
||||
const targetDir = new THREE.Vector2(targetWorld.x - baseWorld.x, targetWorld.z - baseWorld.z).normalize();
|
||||
|
||||
const currentAngle = Math.atan2(currentDir.y, currentDir.x);
|
||||
const targetAngle = Math.atan2(targetDir.y, targetDir.x);
|
||||
@@ -344,18 +327,18 @@ function PillarJibAnimator({
|
||||
|
||||
if (Math.abs(step) > Math.abs(angleDiff)) {
|
||||
base.rotation.y += angleDiff;
|
||||
setAnimationPhase('first-move-trolley');
|
||||
setAnimationPhase("first-move-trolley");
|
||||
} else {
|
||||
base.rotation.y += step;
|
||||
}
|
||||
} else {
|
||||
base.rotation.y += angleDiff;
|
||||
setAnimationPhase('first-move-trolley');
|
||||
setAnimationPhase("first-move-trolley");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'first-move-trolley': {
|
||||
case "first-move-trolley": {
|
||||
const baseWorld = new THREE.Vector3();
|
||||
base.getWorldPosition(baseWorld);
|
||||
|
||||
@@ -368,18 +351,18 @@ function PillarJibAnimator({
|
||||
const step = Math.sign(diff) * trolleySpeed;
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
trolley.position.x = localTarget.x;
|
||||
setAnimationPhase('first-final-hook-adjust');
|
||||
setAnimationPhase("first-final-hook-adjust");
|
||||
} else {
|
||||
trolley.position.x += step;
|
||||
}
|
||||
} else {
|
||||
trolley.position.x = localTarget.x;
|
||||
setAnimationPhase('first-final-hook-adjust');
|
||||
setAnimationPhase("first-final-hook-adjust");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'first-final-hook-adjust': {
|
||||
case "first-final-hook-adjust": {
|
||||
const hookWorld = new THREE.Vector3();
|
||||
hook.getWorldPosition(hookWorld);
|
||||
|
||||
@@ -391,12 +374,12 @@ function PillarJibAnimator({
|
||||
if (Math.abs(step) > Math.abs(diff)) {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[1].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
if (crane.currentPhase === 'init-pickup') {
|
||||
setAnimationPhase('picking');
|
||||
onAnimationComplete('picking');
|
||||
} else if (crane.currentPhase === 'pickup-drop') {
|
||||
setAnimationPhase('dropping');
|
||||
onAnimationComplete('dropping');
|
||||
if (crane.currentPhase === "init-pickup") {
|
||||
setAnimationPhase("picking");
|
||||
onAnimationComplete("picking");
|
||||
} else if (crane.currentPhase === "pickup-drop") {
|
||||
setAnimationPhase("dropping");
|
||||
onAnimationComplete("dropping");
|
||||
}
|
||||
} else {
|
||||
hook.position.y += step;
|
||||
@@ -404,12 +387,12 @@ function PillarJibAnimator({
|
||||
} else {
|
||||
const localTarget = hook.parent.worldToLocal(clampedPoints[1].clone());
|
||||
hook.position.y = localTarget.y;
|
||||
if (crane.currentPhase === 'init-pickup') {
|
||||
setAnimationPhase('picking');
|
||||
onAnimationComplete('picking');
|
||||
} else if (crane.currentPhase === 'pickup-drop') {
|
||||
setAnimationPhase('dropping');
|
||||
onAnimationComplete('dropping');
|
||||
if (crane.currentPhase === "init-pickup") {
|
||||
setAnimationPhase("picking");
|
||||
onAnimationComplete("picking");
|
||||
} else if (crane.currentPhase === "pickup-drop") {
|
||||
setAnimationPhase("dropping");
|
||||
onAnimationComplete("dropping");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -417,10 +400,7 @@ function PillarJibAnimator({
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export default PillarJibAnimator;
|
||||
@@ -1,68 +1,65 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import * as THREE from 'three'
|
||||
import { usePlayButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useEffect, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useTriggerHandler } from "../../../triggers/triggerHandler/useTriggerHandler";
|
||||
|
||||
import PillarJibAnimator from '../animator/pillarJibAnimator'
|
||||
import PillarJibHelper from '../helper/pillarJibHelper'
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import PillarJibAnimator from "../animator/pillarJibAnimator";
|
||||
import PillarJibHelper from "../helper/pillarJibHelper";
|
||||
import MaterialAnimator from "../animator/materialAnimator";
|
||||
|
||||
function PillarJibInstance({ crane }: { readonly crane: CraneStatus }) {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { craneStore, productStore, humanStore, assetStore } = useSceneContext();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { setCurrentPhase, setCraneActive, setIsCaryying, removeCurrentAction, removeLastMaterial, decrementCraneLoad } = craneStore();
|
||||
const { setCurrentPhase: setCurrentPhaseHuman, setHumanActive, setHumanState, getHumanById } = humanStore();
|
||||
const { setCurrentAnimation, getAssetById } = assetStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const [animationPhase, setAnimationPhase] = useState<string>('idle');
|
||||
const [animationPhase, setAnimationPhase] = useState<string>("idle");
|
||||
const [points, setPoints] = useState<[THREE.Vector3, THREE.Vector3] | null>(null);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, crane?.currentAction?.actionUuid || "");
|
||||
const actionTriggers = action?.triggers || [];
|
||||
const humanId = actionTriggers?.[0]?.triggeredAsset?.triggeredModel?.modelUuid ?? null;
|
||||
const humanAsset = getAssetById(humanId || '');
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, actionTriggers?.[0]?.triggeredAsset?.triggeredAction?.actionUuid ?? '');
|
||||
const humanAsset = getAssetById(humanId || "");
|
||||
const humanAction = getActionByUuid(selectedProduct.productUuid, actionTriggers?.[0]?.triggeredAsset?.triggeredAction?.actionUuid ?? "");
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
const human = getHumanById(humanId || '');
|
||||
if (!human || !humanAsset || !humanId || !action || action.actionType !== 'pickAndDrop') return;
|
||||
const human = getHumanById(humanId || "");
|
||||
if (!human || !humanAsset || !humanId || !action || action.actionType !== "pickAndDrop") return;
|
||||
|
||||
if (!crane.isActive && crane.currentPhase === 'init' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length) {
|
||||
setCurrentPhase(crane.modelUuid, 'init-pickup');
|
||||
} else if (crane.currentPhase === 'picking' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && !crane.isCarrying) {
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === 'operator') {
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
if (!crane.isActive && crane.currentPhase === "init" && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length) {
|
||||
setCurrentPhase(crane.modelUuid, "init-pickup");
|
||||
} else if (crane.currentPhase === "picking" && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && !crane.isCarrying) {
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === "operator") {
|
||||
setCurrentAnimation(humanId, "idle", true, true, true);
|
||||
setIsCaryying(crane.modelUuid, true);
|
||||
setCurrentPhase(crane.modelUuid, 'pickup-drop');
|
||||
setCurrentPhase(crane.modelUuid, "pickup-drop");
|
||||
} else {
|
||||
setCurrentPhaseHuman(humanId, 'hooking');
|
||||
setCurrentPhaseHuman(humanId, "hooking");
|
||||
setHumanActive(humanId, true);
|
||||
setHumanState(humanId, 'running');
|
||||
setCurrentAnimation(humanId, 'working_standing', true, false, false);
|
||||
setHumanState(humanId, "running");
|
||||
setCurrentAnimation(humanId, "working_standing", true, false, false);
|
||||
}
|
||||
} else if (crane.currentPhase === 'dropping' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && crane.isCarrying && human.currentPhase === 'hooking') {
|
||||
setCurrentPhaseHuman(humanId, 'loadPoint-unloadPoint');
|
||||
} else if (human.state === 'running' && human.currentPhase === 'unhooking') {
|
||||
} else if (crane.currentPhase === "dropping" && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && crane.isCarrying && human.currentPhase === "hooking") {
|
||||
setCurrentPhaseHuman(humanId, "loadPoint-unloadPoint");
|
||||
} else if (human.state === "running" && human.currentPhase === "unhooking") {
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted) {
|
||||
setCurrentPhase(crane.modelUuid, 'init');
|
||||
setCurrentPhase(crane.modelUuid, "init");
|
||||
setCraneActive(crane.modelUuid, false);
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
setCurrentPhaseHuman(humanId, 'init');
|
||||
setCurrentAnimation(humanId, "idle", true, true, true);
|
||||
setCurrentPhaseHuman(humanId, "init");
|
||||
setHumanActive(humanId, false);
|
||||
setHumanState(humanId, 'idle');
|
||||
setHumanState(humanId, "idle");
|
||||
handleMaterialDrop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [crane, humanAsset?.animationState?.isCompleted])
|
||||
}, [crane, humanAsset?.animationState?.isCompleted]);
|
||||
|
||||
const handleMaterialDrop = () => {
|
||||
if (humanAction && humanAction.actionType === 'operator') {
|
||||
if (humanAction && humanAction.actionType === "operator") {
|
||||
setIsCaryying(crane.modelUuid, false);
|
||||
removeCurrentAction(crane.modelUuid);
|
||||
const removedMaterial = removeLastMaterial(crane.modelUuid);
|
||||
@@ -72,41 +69,27 @@ function PillarJibInstance({ crane }: { readonly crane: CraneStatus }) {
|
||||
triggerPointActions(humanAction, removedMaterial.materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleAnimationComplete = (action: string) => {
|
||||
if (action === 'starting') {
|
||||
setAnimationPhase('first-hook-adjust');
|
||||
} else if (action === 'picking') {
|
||||
setCurrentPhase(crane.modelUuid, 'picking');
|
||||
} else if (action === 'dropping') {
|
||||
setCurrentPhase(crane.modelUuid, 'dropping');
|
||||
}
|
||||
if (action === "starting") {
|
||||
setAnimationPhase("first-hook-adjust");
|
||||
} else if (action === "picking") {
|
||||
setCurrentPhase(crane.modelUuid, "picking");
|
||||
} else if (action === "dropping") {
|
||||
setCurrentPhase(crane.modelUuid, "dropping");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<PillarJibAnimator
|
||||
key={crane.modelUuid}
|
||||
crane={crane}
|
||||
points={points}
|
||||
setPoints={setPoints}
|
||||
animationPhase={animationPhase}
|
||||
setAnimationPhase={setAnimationPhase}
|
||||
onAnimationComplete={handleAnimationComplete}
|
||||
/>
|
||||
<PillarJibAnimator key={crane.modelUuid} crane={crane} points={points} setPoints={setPoints} animationPhase={animationPhase} setAnimationPhase={setAnimationPhase} onAnimationComplete={handleAnimationComplete} />
|
||||
|
||||
<MaterialAnimator crane={crane} />
|
||||
|
||||
<PillarJibHelper
|
||||
crane={crane}
|
||||
points={points}
|
||||
isHelperNeeded={false}
|
||||
/>
|
||||
|
||||
<PillarJibHelper crane={crane} points={points} isHelperNeeded={false} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default PillarJibInstance;
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import * as THREE from "three";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { useToolMode } from "../../../../store/builder/store";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
|
||||
interface ConnectionLine {
|
||||
@@ -20,10 +19,8 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
const { scene } = useThree();
|
||||
const { toolMode } = useToolMode();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { removeTrigger } = productStore();
|
||||
const { removeTrigger, selectedProduct } = productStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const updateBackend = (productName: string, productUuid: string, projectId: string, eventData: EventsSchema) => {
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useSelectedEventSphere, useSelectedEventData, useDeletableEventSphere }
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
@@ -19,11 +18,9 @@ function PointsCreator() {
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { toolMode } = useToolMode();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { eventStore, productStore, versionStore } = useSceneContext();
|
||||
const { getEventByModelUuid } = eventStore();
|
||||
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getPointByUuid: getPointByUuidFromProduct, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getPointByUuid: getPointByUuidFromProduct, getTriggersByTriggeredPointUuid, removeTrigger, removePoint, selectedProduct } = productStore();
|
||||
const transformRef = useRef<any>(null);
|
||||
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||
const { selectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import * as THREE from "three";
|
||||
import { MeshProps } from "@react-three/fiber";
|
||||
import { useRef } from "react";
|
||||
import { useToolMode } from "../../../../../../store/builder/store";
|
||||
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
|
||||
interface PointInstanceProps extends Omit<MeshProps, "ref"> {
|
||||
@@ -23,9 +22,7 @@ export default function PointInstance({ point, modelUuid, color, ...meshProps }:
|
||||
const { deletableEventSphere, setDeletableEventSphere, clearDeletableEventSphere } = useDeletableEventSphere();
|
||||
const { toolMode } = useToolMode();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { getEventByModelUuid, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getEventByModelUuid, getTriggersByTriggeredPointUuid, removeTrigger, removePoint, selectedProduct } = productStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
import PointInstance from "./instance/pointInstance";
|
||||
|
||||
function PointInstances() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
const { eventStore, productStore } = useSceneContext();
|
||||
const { events } = eventStore();
|
||||
const { getEventByModelUuid } = productStore();
|
||||
const { getEventByModelUuid, selectedProduct } = productStore();
|
||||
|
||||
const colorByType: Record<string, string> = {
|
||||
transfer: "orange",
|
||||
@@ -24,7 +20,7 @@ function PointInstances() {
|
||||
return (
|
||||
<>
|
||||
{events.map((event, index) => {
|
||||
const updatedEvent = selectedProduct.productUuid !== '' ? getEventByModelUuid(selectedProduct.productUuid, event.modelUuid) : null;
|
||||
const updatedEvent = selectedProduct.productUuid !== "" ? getEventByModelUuid(selectedProduct.productUuid, event.modelUuid) : null;
|
||||
|
||||
const usedEvent = updatedEvent || event;
|
||||
const color = colorByType[usedEvent.type];
|
||||
@@ -34,18 +30,9 @@ function PointInstances() {
|
||||
const points = usedEvent.type === "transfer" ? usedEvent.points : [usedEvent.point];
|
||||
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<group key={`${index}-${usedEvent.modelUuid}`} position={usedEvent.position} rotation={usedEvent.rotation}>
|
||||
{points.map((point) => (
|
||||
<PointInstance
|
||||
key={point.uuid}
|
||||
point={point}
|
||||
modelUuid={usedEvent.modelUuid}
|
||||
color={color}
|
||||
/>
|
||||
<PointInstance key={point.uuid} point={point} modelUuid={usedEvent.modelUuid} color={color} />
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import * as THREE from "three";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { useSubModuleStore } from "../../../../store/ui/useModuleStore";
|
||||
import { useSelectedAction, useSelectedAsset, useSelectedEventData } from "../../../../store/simulation/useSimulationStore";
|
||||
import { handleAddEventToProduct } from "../points/functions/handleAddEventToProduct";
|
||||
@@ -8,8 +9,6 @@ import { QuadraticBezierLine } from "@react-three/drei";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore";
|
||||
import { ArrowOnQuadraticBezier, Arrows } from "../arrows/arrows";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useToolMode } from "../../../../store/builder/store";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
@@ -23,11 +22,9 @@ interface ConnectionLine {
|
||||
function TriggerConnector() {
|
||||
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { eventStore, productStore, versionStore } = useSceneContext();
|
||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getPointUuidByActionUuid, getProductById } = productStore();
|
||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getPointUuidByActionUuid, getProductById, selectedProduct } = productStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
||||
const groupRefs = useRef<Record<string, any>>({});
|
||||
const [helperLineColor, setHelperLineColor] = useState<string>("red");
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { useEffect } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
export function useHumanEventManager() {
|
||||
const { humanStore, productStore, assetStore, humanEventManagerRef } = useSceneContext();
|
||||
const { getHumanById, setCurrentPhase, removeCurrentAction } = humanStore();
|
||||
const { getAssetById } = assetStore();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -25,24 +22,24 @@ export function useHumanEventManager() {
|
||||
const addHumanToMonitor = (humanId: string, callback: () => void, actionUuid: string) => {
|
||||
const human = getHumanById(humanId);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, actionUuid);
|
||||
if (!human || !action || (action.actionType !== 'manufacturer' && action.actionType !== 'worker' && action.actionType !== 'operator') || !humanEventManagerRef.current) return;
|
||||
if (!human || !action || (action.actionType !== "manufacturer" && action.actionType !== "worker" && action.actionType !== "operator") || !humanEventManagerRef.current) return;
|
||||
|
||||
let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId);
|
||||
let state = humanEventManagerRef.current.humanStates.find((h) => h.humanId === humanId);
|
||||
if (!state) {
|
||||
state = { humanId, actionQueue: [], isCooldown: false };
|
||||
humanEventManagerRef.current.humanStates.push(state);
|
||||
}
|
||||
|
||||
const existingAction = state.actionQueue.find(a => a.actionUuid === actionUuid);
|
||||
const existingAction = state.actionQueue.find((a) => a.actionUuid === actionUuid);
|
||||
if (existingAction) {
|
||||
const currentCount = existingAction.count ?? 0;
|
||||
if (existingAction.actionType === 'worker' || existingAction.actionType === 'operator') {
|
||||
if (existingAction.actionType === "worker" || existingAction.actionType === "operator") {
|
||||
if (currentCount < existingAction.maxLoadCount) {
|
||||
existingAction.callback = callback;
|
||||
existingAction.isMonitored = true;
|
||||
existingAction.isCompleted = false;
|
||||
}
|
||||
} else if (existingAction.actionType === 'manufacturer') {
|
||||
} else if (existingAction.actionType === "manufacturer") {
|
||||
if (currentCount < existingAction.maxManufactureCount) {
|
||||
existingAction.callback = callback;
|
||||
existingAction.isMonitored = true;
|
||||
@@ -61,16 +58,16 @@ export function useHumanEventManager() {
|
||||
count: 0,
|
||||
isMonitored: true,
|
||||
isCompleted: false,
|
||||
callback
|
||||
callback,
|
||||
});
|
||||
};
|
||||
|
||||
const removeHumanFromMonitor = (humanId: string, actionUuid: string) => {
|
||||
if (!humanEventManagerRef.current) return;
|
||||
const state = humanEventManagerRef.current.humanStates.find(h => h.humanId === humanId);
|
||||
const state = humanEventManagerRef.current.humanStates.find((h) => h.humanId === humanId);
|
||||
if (!state) return;
|
||||
|
||||
const action = state.actionQueue.find(a => a.actionUuid === actionUuid);
|
||||
const action = state.actionQueue.find((a) => a.actionUuid === actionUuid);
|
||||
if (action) {
|
||||
action.callback = undefined;
|
||||
action.isMonitored = false;
|
||||
@@ -86,43 +83,42 @@ export function useHumanEventManager() {
|
||||
const { humanId, actionQueue } = humanState;
|
||||
if (!actionQueue || actionQueue.length === 0) continue;
|
||||
|
||||
const action = actionQueue.find(a => !a.isCompleted);
|
||||
const action = actionQueue.find((a) => !a.isCompleted);
|
||||
if (!action || !action.isMonitored || !action.callback) continue;
|
||||
|
||||
const human = getHumanById(humanId);
|
||||
const humanAsset = getAssetById(humanId);
|
||||
const currentAction = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '') as HumanAction | undefined;
|
||||
const currentAction = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "") as HumanAction | undefined;
|
||||
|
||||
if (!human || !humanAsset || !currentAction) continue;
|
||||
if (human.isActive || human.state !== "idle" || humanAsset.animationState?.current !== 'idle') continue;
|
||||
if (human.isActive || human.state !== "idle" || humanAsset.animationState?.current !== "idle") continue;
|
||||
|
||||
let conditionMet = false;
|
||||
|
||||
if (currentAction.actionType === 'worker' || currentAction.actionType === 'operator') {
|
||||
if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
|
||||
if (currentAction.actionType === "worker" || currentAction.actionType === "operator") {
|
||||
if ((action.actionType === "worker" || action.actionType === "operator") && human.currentLoad < currentAction.loadCapacity) {
|
||||
conditionMet = true;
|
||||
} else if (action.actionType === 'manufacturer') {
|
||||
} else if (action.actionType === "manufacturer") {
|
||||
conditionMet = true;
|
||||
}
|
||||
} else if (currentAction.actionType === 'manufacturer') {
|
||||
if (action.actionType === 'manufacturer') {
|
||||
} else if (currentAction.actionType === "manufacturer") {
|
||||
if (action.actionType === "manufacturer") {
|
||||
conditionMet = true;
|
||||
} else if ((action.actionType === 'worker' || action.actionType === 'operator') && human.currentLoad < currentAction.loadCapacity) {
|
||||
} else if ((action.actionType === "worker" || action.actionType === "operator") && human.currentLoad < currentAction.loadCapacity) {
|
||||
conditionMet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionMet) {
|
||||
if (action.actionUuid !== human.currentAction?.actionUuid) {
|
||||
setCurrentPhase(human.modelUuid, 'init');
|
||||
setCurrentPhase(human.modelUuid, "init");
|
||||
removeCurrentAction(human.modelUuid);
|
||||
}
|
||||
|
||||
action.callback();
|
||||
action.count = (action.count ?? 0) + 1;
|
||||
action.isMonitored = false;
|
||||
if (((action.actionType === 'worker' || action.actionType === 'operator') && action.count >= action.maxLoadCount) ||
|
||||
(action.actionType === 'manufacturer' && action.count >= action.maxManufactureCount)) {
|
||||
if (((action.actionType === "worker" || action.actionType === "operator") && action.count >= action.maxLoadCount) || (action.actionType === "manufacturer" && action.count >= action.maxManufactureCount)) {
|
||||
action.isCompleted = true;
|
||||
}
|
||||
humanState.isCooldown = true;
|
||||
@@ -137,6 +133,6 @@ export function useHumanEventManager() {
|
||||
|
||||
return {
|
||||
addHumanToMonitor,
|
||||
removeHumanFromMonitor
|
||||
removeHumanFromMonitor,
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
interface ManufacturerAnimatorProps {
|
||||
path: [number, number, number][];
|
||||
@@ -15,9 +14,7 @@ interface ManufacturerAnimatorProps {
|
||||
|
||||
function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<ManufacturerAnimatorProps>) {
|
||||
const { humanStore, assetStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { getHumanById } = humanStore();
|
||||
const { setCurrentAnimation } = assetStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -26,7 +23,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
const { isReset, setReset } = useResetButtonStore();
|
||||
const progressRef = useRef<number>(0);
|
||||
const completedRef = useRef<boolean>(false);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.manufacturePoint?.rotation || [0, 0, 0]);
|
||||
const [restingRotation, setRestingRotation] = useState<boolean>(true);
|
||||
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||
@@ -34,7 +31,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
|
||||
useEffect(() => {
|
||||
if (!human.currentAction?.actionUuid) return;
|
||||
if (human.currentPhase === 'init-manufacture' && path.length > 0) {
|
||||
if (human.currentPhase === "init-manufacture" && path.length > 0) {
|
||||
setCurrentPath(path);
|
||||
setObjectRotation((action as HumanAction)?.manufacturePoint?.rotation ?? null);
|
||||
}
|
||||
@@ -52,7 +49,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
progressRef.current = 0;
|
||||
setReset(false);
|
||||
setRestingRotation(true);
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
const humanData = getHumanById(human.modelUuid);
|
||||
if (object && humanData) {
|
||||
object.position.set(humanData.position[0], humanData.position[1], humanData.position[2]);
|
||||
@@ -68,7 +65,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
const delta = (now - lastTimeRef.current) / 1000;
|
||||
lastTimeRef.current = now;
|
||||
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!object || currentPath.length < 2) return;
|
||||
if (isPaused || !isPlaying) return;
|
||||
|
||||
@@ -96,9 +93,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
const end = new THREE.Vector3(...currentPath[index + 1]);
|
||||
const segmentDistance = distances[index];
|
||||
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(
|
||||
new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0))
|
||||
);
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0)));
|
||||
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
|
||||
targetQuaternion.multiply(y180);
|
||||
|
||||
@@ -117,9 +112,9 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||
const position = start.clone().lerp(end, t);
|
||||
object.position.copy(position);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +134,7 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly<M
|
||||
object.quaternion.rotateTowards(targetQuaternion, step);
|
||||
}
|
||||
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { MaterialModel } from '../../../materials/instances/material/materialModel';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { MaterialModel } from "../../../materials/instances/material/materialModel";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
const MaterialAnimator = ({ human }: { human: HumanStatus; }) => {
|
||||
const MaterialAnimator = ({ human }: { human: HumanStatus }) => {
|
||||
const { productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const meshRef = useRef<any>(null!);
|
||||
const [hasLoad, setHasLoad] = useState(false);
|
||||
const [isAttached, setIsAttached] = useState(false);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const { scene } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -31,7 +28,7 @@ const MaterialAnimator = ({ human }: { human: HumanStatus; }) => {
|
||||
|
||||
meshRef.current.visible = false;
|
||||
|
||||
const bone = humanModel.getObjectByName('PlaceObjectRefBone') as THREE.Bone;
|
||||
const bone = humanModel.getObjectByName("PlaceObjectRefBone") as THREE.Bone;
|
||||
if (bone) {
|
||||
if (meshRef.current.parent) {
|
||||
meshRef.current.parent.remove(meshRef.current);
|
||||
@@ -48,18 +45,7 @@ const MaterialAnimator = ({ human }: { human: HumanStatus; }) => {
|
||||
}
|
||||
}, [hasLoad, human.modelUuid, scene, human.currentPhase]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{hasLoad && action && (action as HumanAction).actionType === 'worker' && human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup') && (
|
||||
<MaterialModel
|
||||
matRef={meshRef}
|
||||
materialId={`human-${human.currentMaterials[0].materialId}` || ''}
|
||||
materialType={human.currentMaterials[0].materialType || 'Default material'}
|
||||
visible={isAttached}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return <>{hasLoad && action && (action as HumanAction).actionType === "worker" && human.currentMaterials.length > 0 && human.currentPhase !== "init-pickup" && human.currentPhase !== "init-manufacture" && human.currentPhase !== "drop-pickup" && <MaterialModel matRef={meshRef} materialId={`human-${human.currentMaterials[0].materialId}` || ""} materialType={human.currentMaterials[0].materialType || "Default material"} visible={isAttached} />}</>;
|
||||
};
|
||||
|
||||
export default MaterialAnimator;
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
interface WorkerAnimatorProps {
|
||||
path: [number, number, number][];
|
||||
@@ -15,9 +14,7 @@ interface WorkerAnimatorProps {
|
||||
|
||||
function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<WorkerAnimatorProps>) {
|
||||
const { humanStore, assetStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { getHumanById } = humanStore();
|
||||
const { setCurrentAnimation } = assetStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -27,7 +24,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
const progressRef = useRef<number>(0);
|
||||
const movingForward = useRef<boolean>(true);
|
||||
const completedRef = useRef<boolean>(false);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]);
|
||||
const [restingRotation, setRestingRotation] = useState<boolean>(true);
|
||||
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||
@@ -35,14 +32,14 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
|
||||
useEffect(() => {
|
||||
if (!human.currentAction?.actionUuid) return;
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
if (human.currentPhase === 'init-loadPoint' && path.length > 0) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
if (human.currentPhase === "init-loadPoint" && path.length > 0) {
|
||||
setCurrentPath(path);
|
||||
setObjectRotation((action as HumanAction).pickUpPoint?.rotation ?? null);
|
||||
} else if (human.currentPhase === 'loadPoint-unloadPoint' && path.length > 0) {
|
||||
} else if (human.currentPhase === "loadPoint-unloadPoint" && path.length > 0) {
|
||||
setObjectRotation((action as HumanAction)?.dropPoint?.rotation ?? null);
|
||||
setCurrentPath(path);
|
||||
} else if (human.currentPhase === 'unloadPoint-loadPoint' && path.length > 0) {
|
||||
} else if (human.currentPhase === "unloadPoint-loadPoint" && path.length > 0) {
|
||||
setObjectRotation((action as HumanAction)?.pickUpPoint?.rotation ?? null);
|
||||
setCurrentPath(path);
|
||||
}
|
||||
@@ -61,7 +58,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
progressRef.current = 0;
|
||||
setReset(false);
|
||||
setRestingRotation(true);
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
const humanData = getHumanById(human.modelUuid);
|
||||
if (object && humanData) {
|
||||
object.position.set(humanData.position[0], humanData.position[1], humanData.position[2]);
|
||||
@@ -77,7 +74,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
const delta = (now - lastTimeRef.current) / 1000;
|
||||
lastTimeRef.current = now;
|
||||
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!object || currentPath.length < 2) return;
|
||||
if (isPaused || !isPlaying) return;
|
||||
|
||||
@@ -105,9 +102,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
const end = new THREE.Vector3(...currentPath[index + 1]);
|
||||
const segmentDistance = distances[index];
|
||||
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(
|
||||
new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0))
|
||||
);
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0)));
|
||||
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
|
||||
targetQuaternion.multiply(y180);
|
||||
|
||||
@@ -126,9 +121,9 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||
const position = start.clone().lerp(end, t);
|
||||
object.position.copy(position);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +143,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly<Worke
|
||||
object.quaternion.rotateTowards(targetQuaternion, step);
|
||||
}
|
||||
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { Line } from "@react-three/drei";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
interface WorkerAnimatorProps {
|
||||
path: [number, number, number][];
|
||||
@@ -16,9 +15,7 @@ interface WorkerAnimatorProps {
|
||||
|
||||
function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProcess }: Readonly<WorkerAnimatorProps>) {
|
||||
const { humanStore, assetStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { getHumanById } = humanStore();
|
||||
const { setCurrentAnimation } = assetStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -28,7 +25,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
const progressRef = useRef<number>(0);
|
||||
const movingForward = useRef<boolean>(true);
|
||||
const completedRef = useRef<boolean>(false);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]);
|
||||
const [restingRotation, setRestingRotation] = useState<boolean>(true);
|
||||
const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]);
|
||||
@@ -36,14 +33,14 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
|
||||
useEffect(() => {
|
||||
if (!human.currentAction?.actionUuid) return;
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
if (human.currentPhase === 'init-pickup' && path.length > 0) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
if (human.currentPhase === "init-pickup" && path.length > 0) {
|
||||
setCurrentPath(path);
|
||||
setObjectRotation((action as HumanAction).pickUpPoint?.rotation ?? null);
|
||||
} else if (human.currentPhase === 'pickup-drop' && path.length > 0) {
|
||||
} else if (human.currentPhase === "pickup-drop" && path.length > 0) {
|
||||
setObjectRotation((action as HumanAction)?.dropPoint?.rotation ?? null);
|
||||
setCurrentPath(path);
|
||||
} else if (human.currentPhase === 'drop-pickup' && path.length > 0) {
|
||||
} else if (human.currentPhase === "drop-pickup" && path.length > 0) {
|
||||
setObjectRotation((action as HumanAction)?.pickUpPoint?.rotation ?? null);
|
||||
setCurrentPath(path);
|
||||
}
|
||||
@@ -62,7 +59,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
progressRef.current = 0;
|
||||
setReset(false);
|
||||
setRestingRotation(true);
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
const humanData = getHumanById(human.modelUuid);
|
||||
if (object && humanData) {
|
||||
object.position.set(humanData.position[0], humanData.position[1], humanData.position[2]);
|
||||
@@ -78,7 +75,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
const delta = (now - lastTimeRef.current) / 1000;
|
||||
lastTimeRef.current = now;
|
||||
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!object || currentPath.length < 2) return;
|
||||
if (isPaused || !isPlaying) return;
|
||||
|
||||
@@ -106,9 +103,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
const end = new THREE.Vector3(...currentPath[index + 1]);
|
||||
const segmentDistance = distances[index];
|
||||
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(
|
||||
new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0))
|
||||
);
|
||||
const targetQuaternion = new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().lookAt(start, end, new THREE.Vector3(0, 1, 0)));
|
||||
const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
|
||||
targetQuaternion.multiply(y180);
|
||||
|
||||
@@ -127,16 +122,16 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
const t = (progressRef.current - accumulatedDistance) / segmentDistance;
|
||||
const position = start.clone().lerp(end, t);
|
||||
object.position.copy(position);
|
||||
if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup')) {
|
||||
setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true);
|
||||
if (human.currentMaterials.length > 0 && human.currentPhase !== "init-pickup" && human.currentPhase !== "init-manufacture" && human.currentPhase !== "drop-pickup") {
|
||||
setCurrentAnimation(human.modelUuid, "walk_with_box", true, true, true);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
}
|
||||
} else if (!isAligned) {
|
||||
if (human.currentMaterials.length > 0 && (human.currentPhase !== 'init-pickup' && human.currentPhase !== 'init-manufacture' && human.currentPhase !== 'drop-pickup')) {
|
||||
setCurrentAnimation(human.modelUuid, 'idle_with_box', true, true, true);
|
||||
if (human.currentMaterials.length > 0 && human.currentPhase !== "init-pickup" && human.currentPhase !== "init-manufacture" && human.currentPhase !== "drop-pickup") {
|
||||
setCurrentAnimation(human.modelUuid, "idle_with_box", true, true, true);
|
||||
} else {
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,11 +152,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
object.quaternion.rotateTowards(targetQuaternion, step);
|
||||
}
|
||||
|
||||
setCurrentAnimation(
|
||||
human.modelUuid,
|
||||
human.currentMaterials.length > 0 ? 'idle_with_box' : 'idle',
|
||||
true, true, true
|
||||
);
|
||||
setCurrentAnimation(human.modelUuid, human.currentMaterials.length > 0 ? "idle_with_box" : "idle", true, true, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -172,7 +163,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc
|
||||
movingForward.current = !movingForward.current;
|
||||
setCurrentPath([]);
|
||||
handleCallBack();
|
||||
if (human.currentPhase === 'pickup-drop') {
|
||||
if (human.currentPhase === "pickup-drop") {
|
||||
requestAnimationFrame(startUnloadingProcess);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
import { NavMeshQuery } from '@recast-navigation/core';
|
||||
import { useNavMesh } from '../../../../../../store/builder/store';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../../store/ui/usePlayButtonStore';
|
||||
import { useTriggerHandler } from '../../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../../products/productContext';
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { useNavMesh } from "../../../../../../store/builder/store";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../../store/ui/usePlayButtonStore";
|
||||
import { useTriggerHandler } from "../../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
|
||||
import ManufacturerAnimator from '../../animator/manufacturerAnimator';
|
||||
import ManufacturerAnimator from "../../animator/manufacturerAnimator";
|
||||
|
||||
function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { navMesh } = useNavMesh();
|
||||
@@ -18,9 +17,7 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { setMaterial } = materialStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { setCurrentAnimation, resetAnimation, getAssetById } = assetStore();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { setHumanActive, setHumanState, decrementHumanLoad, removeLastMaterial, setCurrentPhase } = humanStore();
|
||||
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
@@ -45,20 +42,17 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
isSpeedRef.current = speed;
|
||||
}, [speed]);
|
||||
|
||||
const computePath = useCallback((start: [number, number, number], end: [number, number, number]) => {
|
||||
const computePath = useCallback(
|
||||
(start: [number, number, number], end: [number, number, number]) => {
|
||||
try {
|
||||
const navMeshQuery = new NavMeshQuery(navMesh);
|
||||
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
|
||||
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
|
||||
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
|
||||
if (
|
||||
segmentPath.length > 0 &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
|
||||
) {
|
||||
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
|
||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
} else {
|
||||
console.log("There is no path here...Choose valid path")
|
||||
console.log("There is no path here...Choose valid path");
|
||||
const { path: segmentPaths } = navMeshQuery.computePath(startPoint, startPoint);
|
||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
}
|
||||
@@ -66,16 +60,18 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
console.error("Failed to compute path");
|
||||
return [];
|
||||
}
|
||||
}, [navMesh]);
|
||||
},
|
||||
[navMesh]
|
||||
);
|
||||
|
||||
function humanStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setCurrentPhase(human.modelUuid, 'init');
|
||||
setCurrentPhase(human.modelUuid, "init");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
resetAnimation(human.modelUuid);
|
||||
setPath([]);
|
||||
if (processAnimationIdRef.current) {
|
||||
@@ -88,7 +84,7 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
lastPauseTimeRef.current = null;
|
||||
hasLoggedHalfway.current = false;
|
||||
hasLoggedCompleted.current = false;
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (object && human) {
|
||||
object.position.set(human.position[0], human.position[1], human.position[2]);
|
||||
object.rotation.set(human.rotation[0], human.rotation[1], human.rotation[2]);
|
||||
@@ -97,26 +93,26 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
|
||||
if (!action || !(action as HumanAction).manufacturePoint || (action as HumanAction).actionType === 'worker') return;
|
||||
if (!action || !(action as HumanAction).manufacturePoint || (action as HumanAction).actionType === "worker") return;
|
||||
|
||||
if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') {
|
||||
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
if (!human.isActive && human.state === "idle" && human.currentPhase === "init") {
|
||||
const humanMesh = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!humanMesh) return;
|
||||
|
||||
const toPickupPath = computePath(humanMesh.position.toArray(), (action as HumanAction)?.manufacturePoint?.position || [0, 0, 0]);
|
||||
setPath(toPickupPath);
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setCurrentPhase(human.modelUuid, 'init-manufacture');
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setCurrentPhase(human.modelUuid, "init-manufacture");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Human is waiting for material in manufacture');
|
||||
} else if (!human.isActive && human.state === 'idle' && human.currentPhase === 'waiting') {
|
||||
if (human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current !== 'working_standing') {
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false);
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentPhase(human.modelUuid, 'manufacturing');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Human is waiting for material in manufacture");
|
||||
} else if (!human.isActive && human.state === "idle" && human.currentPhase === "waiting") {
|
||||
if (human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current !== "working_standing") {
|
||||
setCurrentAnimation(human.modelUuid, "working_standing", true, true, false);
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setCurrentPhase(human.modelUuid, "manufacturing");
|
||||
setHumanActive(human.modelUuid, true);
|
||||
|
||||
processStartTimeRef.current = performance.now();
|
||||
@@ -130,28 +126,28 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess);
|
||||
}
|
||||
}
|
||||
} else if (human.isActive && human.state === 'running' && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === 'working_standing' && humanAsset.animationState?.isCompleted) {
|
||||
if ((action as HumanAction).manufacturePoint && human.currentPhase === 'manufacturing') {
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setCurrentPhase(human.modelUuid, 'waiting');
|
||||
} else if (human.isActive && human.state === "running" && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === "working_standing" && humanAsset.animationState?.isCompleted) {
|
||||
if ((action as HumanAction).manufacturePoint && human.currentPhase === "manufacturing") {
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setCurrentPhase(human.modelUuid, "waiting");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Human is waiting for material in manufacture');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Human is waiting for material in manufacture");
|
||||
|
||||
decrementHumanLoad(human.modelUuid, 1);
|
||||
const material = removeLastMaterial(human.modelUuid);
|
||||
if (material) {
|
||||
triggerPointActions((action as HumanAction), material.materialId);
|
||||
triggerPointActions(action as HumanAction, material.materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reset()
|
||||
reset();
|
||||
}
|
||||
}, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);
|
||||
|
||||
const trackManufactureProcess = useCallback(() => {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
|
||||
const now = performance.now();
|
||||
|
||||
@@ -176,14 +172,14 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
if (elapsed >= totalProcessTimeMs / 2 && !hasLoggedHalfway.current) {
|
||||
hasLoggedHalfway.current = true;
|
||||
if (human.currentMaterials.length > 0) {
|
||||
setMaterial(human.currentMaterials[0].materialId, (action as HumanAction).swapMaterial || 'Default Material');
|
||||
setMaterial(human.currentMaterials[0].materialId, (action as HumanAction).swapMaterial || "Default Material");
|
||||
}
|
||||
humanStatus(human.modelUuid, `🟡 Human ${human.modelUuid} reached halfway in manufacture.`);
|
||||
}
|
||||
|
||||
if (elapsed >= totalProcessTimeMs && !hasLoggedCompleted.current) {
|
||||
hasLoggedCompleted.current = true;
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "working_standing", true, true, true);
|
||||
if (processAnimationIdRef.current) {
|
||||
cancelAnimationFrame(processAnimationIdRef.current);
|
||||
processAnimationIdRef.current = null;
|
||||
@@ -196,24 +192,17 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}, [human.modelUuid, human.currentMaterials]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (human.currentPhase === 'init-manufacture') {
|
||||
setCurrentPhase(human.modelUuid, 'waiting');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
if (human.currentPhase === "init-manufacture") {
|
||||
setCurrentPhase(human.modelUuid, "waiting");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Reached manufacture point, waiting for material');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Reached manufacture point, waiting for material");
|
||||
setPath([]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ManufacturerAnimator
|
||||
path={path}
|
||||
handleCallBack={handleCallBack}
|
||||
human={human}
|
||||
reset={reset}
|
||||
/>
|
||||
)
|
||||
return <ManufacturerAnimator path={path} handleCallBack={handleCallBack} human={human} reset={reset} />;
|
||||
}
|
||||
|
||||
export default ManufacturerInstance;
|
||||
@@ -1,13 +1,12 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
import { NavMeshQuery } from '@recast-navigation/core';
|
||||
import { useNavMesh } from '../../../../../../store/builder/store';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../../products/productContext';
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { useNavMesh } from "../../../../../../store/builder/store";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
|
||||
import OperatorAnimator from '../../animator/operatorAnimator';
|
||||
import OperatorAnimator from "../../animator/operatorAnimator";
|
||||
|
||||
function OperatorInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { navMesh } = useNavMesh();
|
||||
@@ -15,9 +14,7 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { scene } = useThree();
|
||||
const { assetStore, humanStore, productStore } = useSceneContext();
|
||||
const { setCurrentAnimation, resetAnimation, getAssetById } = assetStore();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { setHumanActive, setHumanState, setHumanLoad, setHumanScheduled, resetTime, setCurrentPhase } = humanStore();
|
||||
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
@@ -40,20 +37,17 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
|
||||
isSpeedRef.current = speed;
|
||||
}, [speed]);
|
||||
|
||||
const computePath = useCallback((start: [number, number, number], end: [number, number, number]) => {
|
||||
const computePath = useCallback(
|
||||
(start: [number, number, number], end: [number, number, number]) => {
|
||||
try {
|
||||
const navMeshQuery = new NavMeshQuery(navMesh);
|
||||
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
|
||||
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
|
||||
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
|
||||
if (
|
||||
segmentPath.length > 0 &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
|
||||
) {
|
||||
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
|
||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
} else {
|
||||
console.log("There is no path here...Choose valid path")
|
||||
console.log("There is no path here...Choose valid path");
|
||||
const { path: segmentPaths } = navMeshQuery.computePath(startPoint, startPoint);
|
||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
}
|
||||
@@ -61,31 +55,33 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
|
||||
console.error("Failed to compute path");
|
||||
return [];
|
||||
}
|
||||
}, [navMesh]);
|
||||
},
|
||||
[navMesh]
|
||||
);
|
||||
|
||||
function humanStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setCurrentPhase(human.modelUuid, 'init');
|
||||
setCurrentPhase(human.modelUuid, "init");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanScheduled(human.modelUuid, false);
|
||||
setHumanLoad(human.modelUuid, 0);
|
||||
resetAnimation(human.modelUuid);
|
||||
setPath([]);
|
||||
isPausedRef.current = false;
|
||||
pauseTimeRef.current = 0;
|
||||
resetTime(human.modelUuid)
|
||||
activeTimeRef.current = 0
|
||||
idleTimeRef.current = 0
|
||||
previousTimeRef.current = null
|
||||
resetTime(human.modelUuid);
|
||||
activeTimeRef.current = 0;
|
||||
idleTimeRef.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
if (animationFrameIdRef.current !== null) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current)
|
||||
animationFrameIdRef.current = null
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (object && human) {
|
||||
object.position.set(human.position[0], human.position[1], human.position[2]);
|
||||
object.rotation.set(human.rotation[0], human.rotation[1], human.rotation[2]);
|
||||
@@ -94,66 +90,59 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
if (!action || action.actionType !== 'operator' || !action.pickUpPoint || !action.dropPoint) return;
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
if (!action || action.actionType !== "operator" || !action.pickUpPoint || !action.dropPoint) return;
|
||||
|
||||
if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') {
|
||||
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
if (!human.isActive && human.state === "idle" && human.currentPhase === "init") {
|
||||
const humanMesh = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!humanMesh) return;
|
||||
|
||||
const toPickupPath = computePath(humanMesh.position.toArray(), action?.pickUpPoint?.position || [0, 0, 0]);
|
||||
|
||||
setPath(toPickupPath);
|
||||
setCurrentPhase(human.modelUuid, 'init-loadPoint');
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentPhase(human.modelUuid, "init-loadPoint");
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Started from init, heading to loadPoint');
|
||||
} else if (human.isActive && human.currentPhase === 'loadPoint-unloadPoint') {
|
||||
if (action.pickUpPoint && action.dropPoint && humanAsset?.animationState?.current === 'idle') {
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
humanStatus(human.modelUuid, "Started from init, heading to loadPoint");
|
||||
} else if (human.isActive && human.currentPhase === "loadPoint-unloadPoint") {
|
||||
if (action.pickUpPoint && action.dropPoint && humanAsset?.animationState?.current === "idle") {
|
||||
const toDrop = computePath(action.pickUpPoint.position || [0, 0, 0], action.dropPoint.position || [0, 0, 0]);
|
||||
setPath(toDrop);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Started from loadPoint, heading to unloadPoint');
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
humanStatus(human.modelUuid, "Started from loadPoint, heading to unloadPoint");
|
||||
}
|
||||
} else if (human.state === 'idle' && human.currentPhase === 'unhooking') {
|
||||
} else if (human.state === "idle" && human.currentPhase === "unhooking") {
|
||||
setTimeout(() => {
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, false, false);
|
||||
}, 1)
|
||||
setCurrentAnimation(human.modelUuid, "working_standing", true, false, false);
|
||||
}, 1);
|
||||
}
|
||||
} else {
|
||||
reset()
|
||||
reset();
|
||||
}
|
||||
}, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (human.currentPhase === 'init-loadPoint') {
|
||||
setCurrentPhase(human.modelUuid, 'waiting');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
if (human.currentPhase === "init-loadPoint") {
|
||||
setCurrentPhase(human.modelUuid, "waiting");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Reached loadPoint point, waiting for material');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Reached loadPoint point, waiting for material");
|
||||
setPath([]);
|
||||
} else if (human.currentPhase === 'loadPoint-unloadPoint') {
|
||||
setCurrentPhase(human.modelUuid, 'unhooking');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
} else if (human.currentPhase === "loadPoint-unloadPoint") {
|
||||
setCurrentPhase(human.modelUuid, "unhooking");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Reached loadPoint point, waiting for material');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Reached loadPoint point, waiting for material");
|
||||
setPath([]);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<OperatorAnimator
|
||||
path={path}
|
||||
handleCallBack={handleCallBack}
|
||||
human={human}
|
||||
reset={reset}
|
||||
/>
|
||||
)
|
||||
return <OperatorAnimator path={path} handleCallBack={handleCallBack} human={human} reset={reset} />;
|
||||
}
|
||||
|
||||
export default OperatorInstance;
|
||||
@@ -1,14 +1,13 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
import { NavMeshQuery } from '@recast-navigation/core';
|
||||
import { useNavMesh } from '../../../../../../store/builder/store';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../../store/ui/usePlayButtonStore';
|
||||
import { useTriggerHandler } from '../../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../../products/productContext';
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { useNavMesh } from "../../../../../../store/builder/store";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../../store/ui/usePlayButtonStore";
|
||||
import { useTriggerHandler } from "../../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
|
||||
import WorkerAnimator from '../../animator/workerAnimator';
|
||||
import WorkerAnimator from "../../animator/workerAnimator";
|
||||
|
||||
function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { navMesh } = useNavMesh();
|
||||
@@ -23,9 +22,7 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { getMachineById } = machineStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { setCurrentAnimation, resetAnimation, getAssetById } = assetStore();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid, selectedProduct } = productStore();
|
||||
const { setHumanActive, setHumanState, clearCurrentMaterials, setHumanLoad, setHumanScheduled, decrementHumanLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime, setCurrentPhase } = humanStore();
|
||||
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
@@ -48,20 +45,17 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
isSpeedRef.current = speed;
|
||||
}, [speed]);
|
||||
|
||||
const computePath = useCallback((start: [number, number, number], end: [number, number, number]) => {
|
||||
const computePath = useCallback(
|
||||
(start: [number, number, number], end: [number, number, number]) => {
|
||||
try {
|
||||
const navMeshQuery = new NavMeshQuery(navMesh);
|
||||
let startPoint = new THREE.Vector3(start[0], start[1], start[2]);
|
||||
let endPoint = new THREE.Vector3(end[0], end[1], end[2]);
|
||||
const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint);
|
||||
if (
|
||||
segmentPath.length > 0 &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)
|
||||
) {
|
||||
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) {
|
||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
} else {
|
||||
console.log("There is no path here...Choose valid path")
|
||||
console.log("There is no path here...Choose valid path");
|
||||
const { path: segmentPaths } = navMeshQuery.computePath(startPoint, startPoint);
|
||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
}
|
||||
@@ -69,31 +63,33 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
console.error("Failed to compute path");
|
||||
return [];
|
||||
}
|
||||
}, [navMesh]);
|
||||
},
|
||||
[navMesh]
|
||||
);
|
||||
|
||||
function humanStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setCurrentPhase(human.modelUuid, 'init');
|
||||
setCurrentPhase(human.modelUuid, "init");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanScheduled(human.modelUuid, false);
|
||||
setHumanLoad(human.modelUuid, 0);
|
||||
resetAnimation(human.modelUuid);
|
||||
setPath([]);
|
||||
isPausedRef.current = false;
|
||||
pauseTimeRef.current = 0;
|
||||
resetTime(human.modelUuid)
|
||||
activeTimeRef.current = 0
|
||||
idleTimeRef.current = 0
|
||||
previousTimeRef.current = null
|
||||
resetTime(human.modelUuid);
|
||||
activeTimeRef.current = 0;
|
||||
idleTimeRef.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
if (animationFrameIdRef.current !== null) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current)
|
||||
animationFrameIdRef.current = null
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
const object = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
const object = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (object && human) {
|
||||
object.position.set(human.position[0], human.position[1], human.position[2]);
|
||||
object.rotation.set(human.rotation[0], human.rotation[1], human.rotation[2]);
|
||||
@@ -102,42 +98,42 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
if (!action || action.actionType !== 'worker' || !action.pickUpPoint || !action.dropPoint) return;
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
if (!action || action.actionType !== "worker" || !action.pickUpPoint || !action.dropPoint) return;
|
||||
|
||||
if (!human.isActive && human.state === 'idle' && human.currentPhase === 'init') {
|
||||
const humanMesh = scene.getObjectByProperty('uuid', human.modelUuid);
|
||||
if (!human.isActive && human.state === "idle" && human.currentPhase === "init") {
|
||||
const humanMesh = scene.getObjectByProperty("uuid", human.modelUuid);
|
||||
if (!humanMesh) return;
|
||||
|
||||
const toPickupPath = computePath(humanMesh.position.toArray(), action?.pickUpPoint?.position || [0, 0, 0]);
|
||||
|
||||
setPath(toPickupPath);
|
||||
setCurrentPhase(human.modelUuid, 'init-pickup');
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentPhase(human.modelUuid, "init-pickup");
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Started from init, heading to pickup');
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
humanStatus(human.modelUuid, "Started from init, heading to pickup");
|
||||
return;
|
||||
} else if (!human.isActive && human.state === 'idle' && human.currentPhase === 'picking') {
|
||||
if (humanAsset && human.currentLoad === action.loadCapacity && human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset.animationState?.current === 'pickup' && humanAsset.animationState?.isCompleted) {
|
||||
} else if (!human.isActive && human.state === "idle" && human.currentPhase === "picking") {
|
||||
if (humanAsset && human.currentLoad === action.loadCapacity && human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset.animationState?.current === "pickup" && humanAsset.animationState?.isCompleted) {
|
||||
if (action.pickUpPoint && action.dropPoint) {
|
||||
const toDrop = computePath(action.pickUpPoint.position || [0, 0, 0], action.dropPoint.position || [0, 0, 0]);
|
||||
setPath(toDrop);
|
||||
setCurrentPhase(human.modelUuid, 'pickup-drop');
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Started from pickup point, heading to drop point');
|
||||
setCurrentPhase(human.modelUuid, "pickup-drop");
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setCurrentAnimation(human.modelUuid, "walk_with_box", true, true, true);
|
||||
humanStatus(human.modelUuid, "Started from pickup point, heading to drop point");
|
||||
}
|
||||
} else if (human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset?.animationState?.current !== 'pickup') {
|
||||
} else if (human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset?.animationState?.current !== "pickup") {
|
||||
setTimeout(() => {
|
||||
if (human.currentMaterials[0]?.materialId) {
|
||||
setIsVisible(human.currentMaterials[0]?.materialId, false);
|
||||
}
|
||||
humanStatus(human.modelUuid, 'Started to pickup in pickup point');
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
}, 1)
|
||||
humanStatus(human.modelUuid, "Started to pickup in pickup point");
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
}, 1);
|
||||
}
|
||||
} else if (!human.isActive && human.state === 'idle' && human.currentPhase === 'dropping' && human.currentLoad === 0) {
|
||||
} else if (!human.isActive && human.state === "idle" && human.currentPhase === "dropping" && human.currentLoad === 0) {
|
||||
if (action.pickUpPoint && action.dropPoint) {
|
||||
// const dropToPickup = computePath(action.dropPoint.position || [0, 0, 0], action.pickUpPoint.position || [0, 0, 0]);
|
||||
// setPath(dropToPickup);
|
||||
@@ -146,25 +142,25 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
// setHumanActive(human.modelUuid, true);
|
||||
// setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
if (humanEventManagerRef.current) {
|
||||
let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === human.modelUuid);
|
||||
let state = humanEventManagerRef.current.humanStates.find((h) => h.humanId === human.modelUuid);
|
||||
if (state) {
|
||||
const existingAction = state.actionQueue.find(a => a.actionUuid === action.actionUuid);
|
||||
const existingAction = state.actionQueue.find((a) => a.actionUuid === action.actionUuid);
|
||||
if (existingAction) {
|
||||
const currentCount = existingAction.count ?? 0;
|
||||
if (existingAction.actionType === 'worker') {
|
||||
if (existingAction.actionType === "worker") {
|
||||
if (currentCount < existingAction.maxLoadCount) {
|
||||
const dropToPickup = computePath(action.dropPoint.position || [0, 0, 0], action.pickUpPoint.position || [0, 0, 0]);
|
||||
setPath(dropToPickup);
|
||||
setCurrentPhase(human.modelUuid, 'drop-pickup');
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setCurrentPhase(human.modelUuid, "drop-pickup");
|
||||
setHumanState(human.modelUuid, "running");
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||
setCurrentAnimation(human.modelUuid, "walking", true, true, true);
|
||||
} else {
|
||||
setCurrentPhase(human.modelUuid, 'picking');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
setCurrentPhase(human.modelUuid, "picking");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Started from dropping point, heading to pickup point');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Started from dropping point, heading to pickup point");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,67 +169,67 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reset()
|
||||
reset();
|
||||
}
|
||||
}, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (human.currentPhase === 'init-pickup') {
|
||||
setCurrentPhase(human.modelUuid, 'picking');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
if (human.currentPhase === "init-pickup") {
|
||||
setCurrentPhase(human.modelUuid, "picking");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Reached pickup point, waiting for material');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Reached pickup point, waiting for material");
|
||||
setPath([]);
|
||||
} else if (human.currentPhase === 'pickup-drop') {
|
||||
setCurrentPhase(human.modelUuid, 'dropping');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
} else if (human.currentPhase === "pickup-drop") {
|
||||
setCurrentPhase(human.modelUuid, "dropping");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
humanStatus(human.modelUuid, 'Reached drop point');
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
humanStatus(human.modelUuid, "Reached drop point");
|
||||
setPath([]);
|
||||
} else if (human.currentPhase === 'drop-pickup') {
|
||||
setCurrentPhase(human.modelUuid, 'picking');
|
||||
setHumanState(human.modelUuid, 'idle');
|
||||
} else if (human.currentPhase === "drop-pickup") {
|
||||
setCurrentPhase(human.modelUuid, "picking");
|
||||
setHumanState(human.modelUuid, "idle");
|
||||
setHumanActive(human.modelUuid, false);
|
||||
setHumanScheduled(human.modelUuid, false);
|
||||
setPath([]);
|
||||
clearCurrentMaterials(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||
humanStatus(human.modelUuid, 'Reached pickup point again, cycle complete');
|
||||
setCurrentAnimation(human.modelUuid, "idle", true, true, true);
|
||||
humanStatus(human.modelUuid, "Reached pickup point again, cycle complete");
|
||||
}
|
||||
}
|
||||
|
||||
function startUnloadingProcess() {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "drop" && humanAsset?.animationState?.isCompleted) {
|
||||
if ((action as HumanAction).triggers.length > 0) {
|
||||
const trigger = getTriggerByUuid(selectedProduct.productUuid, (action as HumanAction).triggers[0]?.triggerUuid);
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredModel?.modelUuid || '');
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredModel?.modelUuid || "");
|
||||
|
||||
if (trigger && model) {
|
||||
if (model.type === 'transfer') {
|
||||
if (model.type === "transfer") {
|
||||
if (action) {
|
||||
handleMaterialDropToConveyor(model);
|
||||
}
|
||||
} else if (model.type === 'machine') {
|
||||
} else if (model.type === "machine") {
|
||||
if (action) {
|
||||
handleMaterialDropToMachine(model);
|
||||
}
|
||||
} else if (model.type === 'roboticArm') {
|
||||
} else if (model.type === "roboticArm") {
|
||||
if (action) {
|
||||
handleMaterialDropToArmBot(model);
|
||||
}
|
||||
} else if (model.type === 'storageUnit') {
|
||||
} else if (model.type === "storageUnit") {
|
||||
if (action) {
|
||||
handleMaterialDropToStorageUnit(model);
|
||||
}
|
||||
} else if (model.type === 'vehicle') {
|
||||
} else if (model.type === "vehicle") {
|
||||
if (action) {
|
||||
handleMaterialDropToVehicle(model);
|
||||
}
|
||||
@@ -252,21 +248,15 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
function handleMaterialDropToStorageUnit(model: StorageEventSchema) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (model && humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (model && humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToStorage(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
model.storageCapacity,
|
||||
(action as HumanAction)
|
||||
);
|
||||
loopMaterialDropToStorage(human.modelUuid, human.currentLoad, model.modelUuid, model.storageCapacity, action as HumanAction);
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
}
|
||||
@@ -274,13 +264,7 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
checkAnimation();
|
||||
}
|
||||
|
||||
function loopMaterialDropToStorage(
|
||||
humanId: string,
|
||||
humanCurrentLoad: number,
|
||||
storageUnitId: string,
|
||||
storageMaxCapacity: number,
|
||||
action: HumanAction
|
||||
) {
|
||||
function loopMaterialDropToStorage(humanId: string, humanCurrentLoad: number, storageUnitId: string, storageMaxCapacity: number, action: HumanAction) {
|
||||
const storageUnit = getStorageUnitById(storageUnitId);
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
|
||||
@@ -298,17 +282,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (humanCurrentLoad > 0 && storageUnit.currentLoad < storageMaxCapacity) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
const waitForNextDrop = () => {
|
||||
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToStorage(
|
||||
humanId,
|
||||
humanCurrentLoad,
|
||||
storageUnitId,
|
||||
storageMaxCapacity,
|
||||
action
|
||||
);
|
||||
if (humanAsset?.animationState?.current === "drop" && humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToStorage(humanId, humanCurrentLoad, storageUnitId, storageMaxCapacity, action);
|
||||
} else {
|
||||
requestAnimationFrame(waitForNextDrop);
|
||||
}
|
||||
@@ -318,22 +296,17 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
function handleMaterialDropToConveyor(model: ConveyorEventSchema) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
const conveyor = getConveyorById(model.modelUuid);
|
||||
if (conveyor) {
|
||||
loopMaterialDropToConveyor(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
conveyor.modelUuid,
|
||||
(action as HumanAction)
|
||||
);
|
||||
loopMaterialDropToConveyor(human.modelUuid, human.currentLoad, conveyor.modelUuid, action as HumanAction);
|
||||
}
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
@@ -342,12 +315,7 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
checkAnimation();
|
||||
}
|
||||
|
||||
function loopMaterialDropToConveyor(
|
||||
humanId: string,
|
||||
humanCurrentLoad: number,
|
||||
conveyorId: string,
|
||||
action: HumanAction
|
||||
) {
|
||||
function loopMaterialDropToConveyor(humanId: string, humanCurrentLoad: number, conveyorId: string, action: HumanAction) {
|
||||
const conveyor = getConveyorById(conveyorId);
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
|
||||
@@ -365,16 +333,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (humanCurrentLoad > 0) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
const waitForNextDrop = () => {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToConveyor(
|
||||
humanId,
|
||||
humanCurrentLoad,
|
||||
conveyorId,
|
||||
action
|
||||
);
|
||||
loopMaterialDropToConveyor(humanId, humanCurrentLoad, conveyorId, action);
|
||||
} else {
|
||||
requestAnimationFrame(waitForNextDrop);
|
||||
}
|
||||
@@ -384,22 +347,17 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
function handleMaterialDropToArmBot(model: RoboticArmEventSchema) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "drop" && humanAsset?.animationState?.isCompleted) {
|
||||
const armBot = getArmBotById(model.modelUuid);
|
||||
if (armBot && armBot.state === 'idle' && !armBot.isActive) {
|
||||
loopMaterialDropToArmBot(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
(action as HumanAction)
|
||||
);
|
||||
if (armBot && armBot.state === "idle" && !armBot.isActive) {
|
||||
loopMaterialDropToArmBot(human.modelUuid, human.currentLoad, model.modelUuid, action as HumanAction);
|
||||
}
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
@@ -408,16 +366,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
checkAnimation();
|
||||
}
|
||||
|
||||
function loopMaterialDropToArmBot(
|
||||
humanId: string,
|
||||
humanCurrentLoad: number,
|
||||
armBotId: string,
|
||||
action: HumanAction
|
||||
) {
|
||||
function loopMaterialDropToArmBot(humanId: string, humanCurrentLoad: number, armBotId: string, action: HumanAction) {
|
||||
const armBot = getArmBotById(armBotId);
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
|
||||
if (!armBot || armBot.state !== 'idle' || armBot.isActive || humanCurrentLoad <= 0) {
|
||||
if (!armBot || armBot.state !== "idle" || armBot.isActive || humanCurrentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -431,18 +384,13 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (humanCurrentLoad > 0) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
const waitForNextTransfer = () => {
|
||||
const currentArmBot = getArmBotById(armBotId);
|
||||
if (currentArmBot && currentArmBot.state === 'idle' && !currentArmBot.isActive) {
|
||||
if (currentArmBot && currentArmBot.state === "idle" && !currentArmBot.isActive) {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToArmBot(
|
||||
humanId,
|
||||
humanCurrentLoad,
|
||||
armBotId,
|
||||
action
|
||||
);
|
||||
loopMaterialDropToArmBot(humanId, humanCurrentLoad, armBotId, action);
|
||||
} else {
|
||||
requestAnimationFrame(waitForNextTransfer);
|
||||
}
|
||||
@@ -455,22 +403,17 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
function handleMaterialDropToVehicle(model: VehicleEventSchema) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "drop" && humanAsset?.animationState?.isCompleted) {
|
||||
const vehicle = getVehicleById(model.modelUuid);
|
||||
if (vehicle && vehicle.state === 'idle' && !vehicle.isActive) {
|
||||
loopMaterialDropToVehicle(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
(action as HumanAction)
|
||||
);
|
||||
if (vehicle && vehicle.state === "idle" && !vehicle.isActive) {
|
||||
loopMaterialDropToVehicle(human.modelUuid, human.currentLoad, model.modelUuid, action as HumanAction);
|
||||
}
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
@@ -479,16 +422,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
checkAnimation();
|
||||
}
|
||||
|
||||
function loopMaterialDropToVehicle(
|
||||
humanId: string,
|
||||
humanCurrentLoad: number,
|
||||
vehicleId: string,
|
||||
action: HumanAction
|
||||
) {
|
||||
function loopMaterialDropToVehicle(humanId: string, humanCurrentLoad: number, vehicleId: string, action: HumanAction) {
|
||||
const vehicle = getVehicleById(vehicleId);
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
|
||||
if (!vehicle || vehicle.state !== 'idle' || vehicle.isActive || humanCurrentLoad <= 0) {
|
||||
if (!vehicle || vehicle.state !== "idle" || vehicle.isActive || humanCurrentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -502,18 +440,13 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (humanCurrentLoad > 0) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
const waitForNextTransfer = () => {
|
||||
const currentVehicle = getVehicleById(vehicleId);
|
||||
if (currentVehicle && currentVehicle.state === 'idle' && !currentVehicle.isActive) {
|
||||
if (currentVehicle && currentVehicle.state === "idle" && !currentVehicle.isActive) {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToVehicle(
|
||||
humanId,
|
||||
humanCurrentLoad,
|
||||
vehicleId,
|
||||
action
|
||||
);
|
||||
loopMaterialDropToVehicle(humanId, humanCurrentLoad, vehicleId, action);
|
||||
} else {
|
||||
requestAnimationFrame(waitForNextTransfer);
|
||||
}
|
||||
@@ -526,22 +459,17 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
function handleMaterialDropToMachine(model: MachineEventSchema) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
const checkAnimation = () => {
|
||||
if (humanAsset?.animationState?.current === 'drop' && humanAsset?.animationState?.isCompleted) {
|
||||
if (humanAsset?.animationState?.current === "drop" && humanAsset?.animationState?.isCompleted) {
|
||||
const machine = getMachineById(model.modelUuid);
|
||||
if (machine && machine.state === 'idle' && !machine.isActive) {
|
||||
loopMaterialDropToMachine(
|
||||
human.modelUuid,
|
||||
human.currentLoad,
|
||||
model.modelUuid,
|
||||
(action as HumanAction)
|
||||
);
|
||||
if (machine && machine.state === "idle" && !machine.isActive) {
|
||||
loopMaterialDropToMachine(human.modelUuid, human.currentLoad, model.modelUuid, action as HumanAction);
|
||||
}
|
||||
} else {
|
||||
requestAnimationFrame(checkAnimation);
|
||||
@@ -550,16 +478,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
checkAnimation();
|
||||
}
|
||||
|
||||
function loopMaterialDropToMachine(
|
||||
humanId: string,
|
||||
humanCurrentLoad: number,
|
||||
machineId: string,
|
||||
action: HumanAction
|
||||
) {
|
||||
function loopMaterialDropToMachine(humanId: string, humanCurrentLoad: number, machineId: string, action: HumanAction) {
|
||||
const machine = getMachineById(machineId);
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
|
||||
if (!machine || machine.state !== 'idle' || machine.isActive || humanCurrentLoad <= 0) {
|
||||
if (!machine || machine.state !== "idle" || machine.isActive || humanCurrentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -573,18 +496,13 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (humanCurrentLoad > 0) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
const waitForNextTransfer = () => {
|
||||
const currentMachine = getMachineById(machineId);
|
||||
if (currentMachine && currentMachine.state === 'idle' && !currentMachine.isActive) {
|
||||
if (currentMachine && currentMachine.state === "idle" && !currentMachine.isActive) {
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
loopMaterialDropToMachine(
|
||||
humanId,
|
||||
humanCurrentLoad,
|
||||
machineId,
|
||||
action
|
||||
);
|
||||
loopMaterialDropToMachine(humanId, humanCurrentLoad, machineId, action);
|
||||
} else {
|
||||
requestAnimationFrame(waitForNextTransfer);
|
||||
}
|
||||
@@ -598,8 +516,8 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
function handleMaterialDropByDefault(droppedMaterial: number) {
|
||||
const humanAsset = getAssetById(human.modelUuid);
|
||||
if (humanAsset?.animationState?.current !== 'drop') {
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
if (humanAsset?.animationState?.current !== "drop") {
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
}
|
||||
|
||||
if (humanAsset?.animationState?.isCompleted) {
|
||||
@@ -614,7 +532,7 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
|
||||
if (remainingMaterials > 0) {
|
||||
resetAnimation(human.modelUuid);
|
||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||
setCurrentAnimation(human.modelUuid, "drop", true, false, false);
|
||||
|
||||
requestAnimationFrame(() => handleMaterialDropByDefault(remainingMaterials));
|
||||
}
|
||||
@@ -624,15 +542,7 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) {
|
||||
requestAnimationFrame(() => handleMaterialDropByDefault(droppedMaterial));
|
||||
}
|
||||
|
||||
return (
|
||||
<WorkerAnimator
|
||||
path={path}
|
||||
handleCallBack={handleCallBack}
|
||||
human={human}
|
||||
reset={reset}
|
||||
startUnloadingProcess={startUnloadingProcess}
|
||||
/>
|
||||
)
|
||||
return <WorkerAnimator path={path} handleCallBack={handleCallBack} human={human} reset={reset} startUnloadingProcess={startUnloadingProcess} />;
|
||||
}
|
||||
|
||||
export default WorkerInstance;
|
||||
@@ -1,19 +1,16 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import ManufacturerInstance from './actions/manufacturerInstance';
|
||||
import WorkerInstance from './actions/workerInstance';
|
||||
import OperatorInstance from './actions/operatorInstance';
|
||||
import MaterialAnimator from "../animator/materialAnimator";
|
||||
import ManufacturerInstance from "./actions/manufacturerInstance";
|
||||
import WorkerInstance from "./actions/workerInstance";
|
||||
import OperatorInstance from "./actions/operatorInstance";
|
||||
|
||||
function HumanInstance({ human }: {readonly human: HumanStatus }) {
|
||||
function HumanInstance({ human }: { readonly human: HumanStatus }) {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { humanStore, productStore } = useSceneContext();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { incrementIdleTime, incrementActiveTime } = humanStore();
|
||||
|
||||
const idleTimeRef = useRef<number>(0);
|
||||
@@ -24,7 +21,7 @@ function HumanInstance({ human }: {readonly human: HumanStatus }) {
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const previousTimeRef = useRef<number | null>(null);
|
||||
const animationFrameIdRef = useRef<number | null>(null);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
||||
|
||||
useEffect(() => {
|
||||
isPausedRef.current = isPaused;
|
||||
@@ -55,7 +52,7 @@ function HumanInstance({ human }: {readonly human: HumanStatus }) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return
|
||||
if (!isPlaying) return;
|
||||
if (!human.isActive) {
|
||||
const roundedActiveTime = Math.round(activeTimeRef.current);
|
||||
incrementActiveTime(human.modelUuid, roundedActiveTime);
|
||||
@@ -80,20 +77,13 @@ function HumanInstance({ human }: {readonly human: HumanStatus }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{action && action.actionType === 'worker' &&
|
||||
<WorkerInstance human={human} />
|
||||
}
|
||||
{action && action.actionType === 'manufacturer' &&
|
||||
<ManufacturerInstance human={human} />
|
||||
}
|
||||
{action && action.actionType === 'operator' &&
|
||||
<OperatorInstance human={human} />
|
||||
}
|
||||
{action && action.actionType === "worker" && <WorkerInstance human={human} />}
|
||||
{action && action.actionType === "manufacturer" && <ManufacturerInstance human={human} />}
|
||||
{action && action.actionType === "operator" && <OperatorInstance human={human} />}
|
||||
|
||||
<MaterialAnimator human={human} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default HumanInstance
|
||||
export default HumanInstance;
|
||||
|
||||
@@ -3,7 +3,6 @@ import * as THREE from "three";
|
||||
import { Tube, useGLTF } from "@react-three/drei";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useIsDragging, useIsRotating, useSelectedAction, useSelectedEventSphere } from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { Group, Plane, Vector2, Vector3 } from "three";
|
||||
import { useParams } from "react-router-dom";
|
||||
@@ -23,11 +22,9 @@ function HumanUi() {
|
||||
const prevMousePos = useRef({ x: 0, y: 0 });
|
||||
const { controls, raycaster, camera } = useThree();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { humanStore, productStore, versionStore } = useSceneContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { humans, getHumanById } = humanStore();
|
||||
const { updateEvent, getActionByUuid } = productStore();
|
||||
const { updateEvent, getActionByUuid, selectedProduct } = productStore();
|
||||
const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 1, 0]);
|
||||
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 1, 0]);
|
||||
const [manufacturePosition, setManufacturePosition] = useState<[number, number, number]>([0, 1, 0]);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import MachineAnimator from '../animator/machineAnimator';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import MachineAnimator from "../animator/machineAnimator";
|
||||
import { useTriggerHandler } from "../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
function MachineInstance({ machineDetail }: { readonly machineDetail: MachineStatus }) {
|
||||
const [currentPhase, setCurrentPhase] = useState<string>('idle');
|
||||
const [currentPhase, setCurrentPhase] = useState<string>("idle");
|
||||
let isIncrememtable = useRef<boolean>(true);
|
||||
const idleTimeRef = useRef<number>(0);
|
||||
const activeTimeRef = useRef<number>(0);
|
||||
@@ -16,10 +15,8 @@ function MachineInstance({ machineDetail }: { readonly machineDetail: MachineSta
|
||||
const isPausedRef = useRef<boolean>(false);
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { machineStore, productStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { machines, setMachineState, setMachineActive, incrementIdleTime, incrementActiveTime, resetTime } = machineStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid } = productStore();
|
||||
const { getActionByUuid, selectedProduct } = productStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
@@ -34,19 +31,19 @@ function MachineInstance({ machineDetail }: { readonly machineDetail: MachineSta
|
||||
|
||||
const reset = () => {
|
||||
setCurrentPhase("idle");
|
||||
setMachineState(machineDetail.modelUuid, 'idle');
|
||||
setMachineState(machineDetail.modelUuid, "idle");
|
||||
setMachineActive(machineDetail.modelUuid, false);
|
||||
isIncrememtable.current = true;
|
||||
isPausedRef.current = false;
|
||||
resetTime(machineDetail.modelUuid)
|
||||
activeTimeRef.current = 0
|
||||
idleTimeRef.current = 0
|
||||
previousTimeRef.current = null
|
||||
resetTime(machineDetail.modelUuid);
|
||||
activeTimeRef.current = 0;
|
||||
idleTimeRef.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
if (animationFrameIdRef.current !== null) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current)
|
||||
animationFrameIdRef.current = null
|
||||
}
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
function machineStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
@@ -75,7 +72,7 @@ function MachineInstance({ machineDetail }: { readonly machineDetail: MachineSta
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return
|
||||
if (!isPlaying) return;
|
||||
if (!machineDetail.isActive) {
|
||||
const roundedActiveTime = Math.round(activeTimeRef.current);
|
||||
// console.log('Final Active Time:', roundedActiveTime, 'seconds');
|
||||
@@ -103,38 +100,34 @@ function MachineInstance({ machineDetail }: { readonly machineDetail: MachineSta
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && !machineDetail.currentAction) {
|
||||
machineStatus(machineDetail.modelUuid, 'Machine is idle and waiting for next instruction.')
|
||||
machineStatus(machineDetail.modelUuid, "Machine is idle and waiting for next instruction.");
|
||||
} else if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && machineDetail.currentAction) {
|
||||
setCurrentPhase("processing");
|
||||
setMachineState(machineDetail.modelUuid, 'running');
|
||||
setMachineState(machineDetail.modelUuid, "running");
|
||||
setMachineActive(machineDetail.modelUuid, true);
|
||||
machineStatus(machineDetail.modelUuid, "Machine started processing")
|
||||
machineStatus(machineDetail.modelUuid, "Machine started processing");
|
||||
}
|
||||
}
|
||||
}, [currentPhase, isPlaying, machines])
|
||||
}, [currentPhase, isPlaying, machines]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (currentPhase == "processing") {
|
||||
setMachineState(machineDetail.modelUuid, 'idle');
|
||||
setMachineState(machineDetail.modelUuid, "idle");
|
||||
setMachineActive(machineDetail.modelUuid, false);
|
||||
setCurrentPhase("idle")
|
||||
setCurrentPhase("idle");
|
||||
isIncrememtable.current = true;
|
||||
machineStatus(machineDetail.modelUuid, "Machine has completed the processing")
|
||||
machineStatus(machineDetail.modelUuid, "Machine has completed the processing");
|
||||
|
||||
if (machineDetail.currentAction) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, machineDetail.currentAction.actionUuid);
|
||||
if (action && machineDetail.currentAction.materialId) {
|
||||
triggerPointActions(action, machineDetail.currentAction.materialId)
|
||||
triggerPointActions(action, machineDetail.currentAction.materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<MachineAnimator processingTime={machineDetail.point.action.processTime} handleCallBack={handleCallBack} currentPhase={currentPhase} machineUuid={machineDetail.modelUuid} machineStatus={machineStatus} reset={reset} />
|
||||
|
||||
)
|
||||
return <MachineAnimator processingTime={machineDetail.point.action.processTime} handleCallBack={handleCallBack} currentPhase={currentPhase} machineUuid={machineDetail.modelUuid} machineStatus={machineStatus} reset={reset} />;
|
||||
}
|
||||
|
||||
export default MachineInstance
|
||||
export default MachineInstance;
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import { useMemo, useRef } from 'react'
|
||||
import * as THREE from 'three';
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import { MaterialModel } from '../material/materialModel';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
import { useAnimationPlaySpeed } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useMemo, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import MaterialAnimator from "../animator/materialAnimator";
|
||||
import { MaterialModel } from "../material/materialModel";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { useAnimationPlaySpeed } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useTriggerHandler } from "../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
function MaterialInstance({ material }: { readonly material: MaterialSchema }) {
|
||||
const matRef: any = useRef();
|
||||
const { scene } = useThree();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { productStore, materialStore } = useSceneContext();
|
||||
const { setIsPaused } = materialStore();
|
||||
const { getModelUuidByPointUuid, getPointByUuid, getEventByModelUuid, getActionByPointUuid } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getModelUuidByPointUuid, getPointByUuid, getEventByModelUuid, getActionByPointUuid, selectedProduct } = productStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
|
||||
@@ -53,18 +50,17 @@ function MaterialInstance({ material }: { readonly material: MaterialSchema }) {
|
||||
return {
|
||||
position: new THREE.Vector3(...point.position),
|
||||
rotation: new THREE.Vector3(...point.rotation),
|
||||
currentSpeed: currentSpeed || 1
|
||||
currentSpeed: currentSpeed || 1,
|
||||
};
|
||||
}, [material, getPointByUuid]);
|
||||
|
||||
|
||||
function getCurrentSpeed(productUuid: string, modelUuid: string) {
|
||||
const event = getEventByModelUuid(productUuid, modelUuid)
|
||||
const event = getEventByModelUuid(productUuid, modelUuid);
|
||||
if (event) {
|
||||
if (event.type === 'transfer' || event.type === 'machine' || event.type === 'storageUnit') {
|
||||
if (event.type === "transfer" || event.type === "machine" || event.type === "storageUnit") {
|
||||
return 1;
|
||||
}
|
||||
if (event.type === 'vehicle' || event.type === 'roboticArm' || event.type === 'human') {
|
||||
if (event.type === "vehicle" || event.type === "roboticArm" || event.type === "human") {
|
||||
return event.speed;
|
||||
}
|
||||
} else {
|
||||
@@ -81,23 +77,22 @@ function MaterialInstance({ material }: { readonly material: MaterialSchema }) {
|
||||
} else {
|
||||
setIsPaused(material.materialId, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{material.isRendered &&
|
||||
<MaterialModel materialId={material.materialId} matRef={matRef} materialType={material.materialType} visible={material.isVisible} position={position} rotation={[rotation.x, rotation.y, rotation.z]} />
|
||||
}
|
||||
{material.isRendered && <MaterialModel materialId={material.materialId} matRef={matRef} materialType={material.materialType} visible={material.isVisible} position={position} rotation={[rotation.x, rotation.y, rotation.z]} />}
|
||||
|
||||
<MaterialAnimator
|
||||
matRef={matRef}
|
||||
material={material}
|
||||
currentSpeed={currentSpeed * speed}
|
||||
onAnimationComplete={() => { callTrigger() }}
|
||||
onAnimationComplete={() => {
|
||||
callTrigger();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default MaterialInstance
|
||||
export default MaterialInstance;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import { createContext, useContext, useMemo } from 'react';
|
||||
import { createSelectedProductStore, SelectedProductType } from '../../../store/simulation/useSimulationStore';
|
||||
|
||||
type ProductContextValue = {
|
||||
selectedProductStore: SelectedProductType,
|
||||
};
|
||||
|
||||
const ProductContext = createContext<ProductContextValue | null>(null);
|
||||
|
||||
export function ProductProvider({
|
||||
children,
|
||||
}: {
|
||||
readonly children: React.ReactNode;
|
||||
}) {
|
||||
const selectedProductStore = useMemo(() => createSelectedProductStore(), []);
|
||||
|
||||
const contextValue = useMemo(() => (
|
||||
{
|
||||
selectedProductStore
|
||||
}
|
||||
), [selectedProductStore]);
|
||||
|
||||
return (
|
||||
<ProductContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</ProductContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// Base hook to get the context
|
||||
export function useProductContext() {
|
||||
const context = useContext(ProductContext);
|
||||
if (!context) {
|
||||
throw new Error('useProductContext must be used within a ProductProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
import * as THREE from 'three';
|
||||
import { useEffect } from 'react';
|
||||
import { upsertProductOrEventApi } from '../../../services/simulation/products/UpsertProductOrEventApi';
|
||||
import { getAllProductsApi } from '../../../services/simulation/products/getallProductsApi';
|
||||
import { usePlayButtonStore, useResetButtonStore } from '../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../scene/sceneContext';
|
||||
import { useProductContext } from './productContext';
|
||||
import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import * as THREE from "three";
|
||||
import { useEffect } from "react";
|
||||
import { upsertProductOrEventApi } from "../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
|
||||
import { usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../scene/sceneContext";
|
||||
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
function Products() {
|
||||
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, craneStore, layout, productStore, versionStore } = useSceneContext();
|
||||
const { products, getProductById, addProduct, setProducts } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { products, getProductById, addProduct, setProducts, selectedProduct, setSelectedProduct } = productStore();
|
||||
const { setMainProduct } = useMainProduct();
|
||||
const { selectedProduct, setSelectedProduct } = selectedProductStore();
|
||||
const { addVehicle, clearVehicles } = vehicleStore();
|
||||
const { addArmBot, clearArmBots } = armBotStore();
|
||||
const { addMachine, clearMachines } = machineStore();
|
||||
@@ -29,53 +26,55 @@ function Products() {
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (layout === 'Main Layout' && mainProduct) {
|
||||
if (layout === "Main Layout" && mainProduct) {
|
||||
setSelectedProduct(mainProduct.productUuid, mainProduct.productName);
|
||||
}
|
||||
}, [mainProduct])
|
||||
}, [mainProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
if (layout === 'Comparison Layout' && comparisonProduct) {
|
||||
if (layout === "Comparison Layout" && comparisonProduct) {
|
||||
setSelectedProduct(comparisonProduct.productUuid, comparisonProduct.productName);
|
||||
}
|
||||
}, [comparisonProduct])
|
||||
}, [comparisonProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedVersion) return;
|
||||
getAllProductsApi(projectId || '', selectedVersion?.versionId || '').then((data) => {
|
||||
getAllProductsApi(projectId || "", selectedVersion?.versionId || "")
|
||||
.then((data) => {
|
||||
if (data && data.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
const name = "Product 1";
|
||||
addProduct(name, id);
|
||||
upsertProductOrEventApi({
|
||||
productName: name,
|
||||
productUuid: id,
|
||||
projectId: projectId || '',
|
||||
versionId: selectedVersion?.versionId || ''
|
||||
})
|
||||
if (layout === 'Main Layout') {
|
||||
projectId: projectId || "",
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
if (layout === "Main Layout") {
|
||||
setSelectedProduct(id, name);
|
||||
setMainProduct(id, name);
|
||||
}
|
||||
} else {
|
||||
setProducts(data);
|
||||
if (layout === 'Main Layout') {
|
||||
if (layout === "Main Layout") {
|
||||
setSelectedProduct(data[0].productUuid, data[0].productName);
|
||||
setMainProduct(data[0].productUuid, data[0].productName);
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
})
|
||||
}, [selectedVersion?.versionId])
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}, [selectedVersion?.versionId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedProduct.productUuid) {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearVehicles();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'vehicle') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "vehicle") {
|
||||
addVehicle(selectedProduct.productUuid, events);
|
||||
}
|
||||
});
|
||||
@@ -88,8 +87,8 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearArmBots();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'roboticArm') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "roboticArm") {
|
||||
addArmBot(selectedProduct.productUuid, events);
|
||||
}
|
||||
});
|
||||
@@ -102,8 +101,8 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearConveyors();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'transfer') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "transfer") {
|
||||
addConveyor(selectedProduct.productUuid, events);
|
||||
}
|
||||
});
|
||||
@@ -116,8 +115,8 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearMachines();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'machine') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "machine") {
|
||||
addMachine(selectedProduct.productUuid, events);
|
||||
}
|
||||
});
|
||||
@@ -130,14 +129,14 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearStorageUnits();
|
||||
product.eventDatas.forEach(event => {
|
||||
if (event.type === 'storageUnit') {
|
||||
product.eventDatas.forEach((event) => {
|
||||
if (event.type === "storageUnit") {
|
||||
addStorageUnit(selectedProduct.productUuid, event);
|
||||
|
||||
if (event.storageCount > 0) {
|
||||
const materials = Array.from({ length: event.storageCount }, () => ({
|
||||
materialType: event.materialType || 'Default material',
|
||||
materialId: THREE.MathUtils.generateUUID()
|
||||
materialType: event.materialType || "Default material",
|
||||
materialId: THREE.MathUtils.generateUUID(),
|
||||
}));
|
||||
|
||||
setCurrentMaterials(event.modelUuid, materials);
|
||||
@@ -157,8 +156,8 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearHumans();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'human') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "human") {
|
||||
addHuman(selectedProduct.productUuid, events);
|
||||
|
||||
if (events.point.actions.length > 0) {
|
||||
@@ -175,8 +174,8 @@ function Products() {
|
||||
const product = getProductById(selectedProduct.productUuid);
|
||||
if (product) {
|
||||
clearCranes();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'crane') {
|
||||
product.eventDatas.forEach((events) => {
|
||||
if (events.type === "crane") {
|
||||
addCrane(selectedProduct.productUuid, events);
|
||||
|
||||
if (events.point.actions.length > 0) {
|
||||
@@ -188,11 +187,7 @@ function Products() {
|
||||
}
|
||||
}, [selectedProduct, products, isReset, isPlaying]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
</>
|
||||
)
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export default Products
|
||||
export default Products;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
import { Line, Text } from '@react-three/drei';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { Line, Text } from "@react-three/drei";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
type PointWithDegree = {
|
||||
position: [number, number, number];
|
||||
@@ -34,13 +33,11 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
const { armBotStore, productStore, materialStore } = useSceneContext();
|
||||
const { getArmBotById } = armBotStore();
|
||||
const { getMaterialById, getMaterialPosition } = materialStore();
|
||||
const { getEventByModelUuid, getActionByUuid, getPointByUuid, getTriggeringModels } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getEventByModelUuid, getActionByUuid, getPointByUuid, getTriggeringModels, selectedProduct } = productStore();
|
||||
const { scene } = useThree();
|
||||
|
||||
let curveHeight = 1.75
|
||||
const CIRCLE_RADIUS = 1.6
|
||||
let curveHeight = 1.75;
|
||||
const CIRCLE_RADIUS = 1.6;
|
||||
|
||||
// Zustand stores
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
@@ -55,7 +52,7 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
|
||||
// Handle circle points based on armBot position
|
||||
useEffect(() => {
|
||||
const points = generateRingPoints(CIRCLE_RADIUS, 64)
|
||||
const points = generateRingPoints(CIRCLE_RADIUS, 64);
|
||||
setCirclePoints(points);
|
||||
}, [armBot.position]);
|
||||
|
||||
@@ -69,13 +66,13 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
totalDistanceRef.current = 0;
|
||||
startTimeRef.current = null;
|
||||
segmentDistancesRef.current = [];
|
||||
if (!ikSolver) return
|
||||
if (!ikSolver) return;
|
||||
const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBone);
|
||||
if (!bone) return;
|
||||
bone.position.copy(restPosition)
|
||||
bone.position.copy(restPosition);
|
||||
ikSolver.update();
|
||||
}
|
||||
}, [isReset, isPlaying])
|
||||
}, [isReset, isPlaying]);
|
||||
|
||||
//Generate Circle Points
|
||||
function generateRingPoints(radius: any, segments: any) {
|
||||
@@ -110,18 +107,14 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
// Handle circle points based on armBot position
|
||||
useEffect(() => {
|
||||
const points = generateRingPointsWithDegrees(CIRCLE_RADIUS, 64, armBot.rotation);
|
||||
setCirclePointsWithDegrees(points)
|
||||
setCirclePointsWithDegrees(points);
|
||||
}, [armBot.rotation]);
|
||||
|
||||
// Function for find nearest Circlepoints Index
|
||||
const findNearestIndex = (nearestPoint: [number, number, number], points: [number, number, number][], epsilon = 1e-6) => {
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const [x, y, z] = points[i];
|
||||
if (
|
||||
Math.abs(x - nearestPoint[0]) < epsilon &&
|
||||
Math.abs(y - nearestPoint[1]) < epsilon &&
|
||||
Math.abs(z - nearestPoint[2]) < epsilon
|
||||
) {
|
||||
if (Math.abs(x - nearestPoint[0]) < epsilon && Math.abs(y - nearestPoint[1]) < epsilon && Math.abs(z - nearestPoint[2]) < epsilon) {
|
||||
return i; // Found the matching index
|
||||
}
|
||||
}
|
||||
@@ -154,7 +147,7 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
|
||||
//Range to restrict angle
|
||||
const hasForbiddenDegrees = (arc: [number, number, number][]) => {
|
||||
return arc.some(p => {
|
||||
return arc.some((p) => {
|
||||
const idx = findNearestIndex(p, circlePoints);
|
||||
const degree = circlePointsWithDegrees[idx]?.degree || 0;
|
||||
return degree >= 271 && degree <= 300; // Forbidden range: 271° to 300°
|
||||
@@ -164,24 +157,23 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
// Handle nearest points and final path (including arc points)
|
||||
useEffect(() => {
|
||||
if (circlePoints.length > 0 && currentPath.length > 0 && ikSolver.mesh) {
|
||||
|
||||
let start = currentPath[0];
|
||||
let end = currentPath[currentPath.length - 1];
|
||||
const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBone);
|
||||
|
||||
const armbotStatus = getArmBotById(armBot.modelUuid);
|
||||
const currentMaterial = armbotStatus?.currentAction?.materialId;
|
||||
const currentAction = getActionByUuid(selectedProduct.productUuid, armbotStatus?.currentAction?.actionUuid || '');
|
||||
const currentAction = getActionByUuid(selectedProduct.productUuid, armbotStatus?.currentAction?.actionUuid || "");
|
||||
|
||||
if (armbotStatus && currentMaterial && currentAction && (currentPhase === 'rest-to-start' || currentPhase === 'start-to-end' || currentPhase === 'end-to-rest')) {
|
||||
if (armbotStatus && currentMaterial && currentAction && (currentPhase === "rest-to-start" || currentPhase === "start-to-end" || currentPhase === "end-to-rest")) {
|
||||
const materialData = getMaterialById(currentMaterial);
|
||||
if (materialData) {
|
||||
const triggeringModel = getTriggeringModels(selectedProduct.productUuid, currentAction.actionUuid);
|
||||
const prevModel = triggeringModel[0] || null;
|
||||
const nextModel = getEventByModelUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || '');
|
||||
const nextPoint = getPointByUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || '', currentAction?.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid || '');
|
||||
const nextModel = getEventByModelUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || "");
|
||||
const nextPoint = getPointByUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || "", currentAction?.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid || "");
|
||||
|
||||
if (prevModel && prevModel.type === 'transfer') {
|
||||
if (prevModel && prevModel.type === "transfer") {
|
||||
const material = scene.getObjectByProperty("uuid", currentMaterial);
|
||||
const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid);
|
||||
if (material && armbotModel) {
|
||||
@@ -194,13 +186,13 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
const materialLocalPos = materialWorldPos.clone();
|
||||
armbotModel.worldToLocal(materialLocalPos);
|
||||
|
||||
if (currentPhase === 'rest-to-start') {
|
||||
if (currentPhase === "rest-to-start") {
|
||||
end = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
} else if (currentPhase === 'start-to-end') {
|
||||
} else if (currentPhase === "start-to-end") {
|
||||
start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
}
|
||||
}
|
||||
} else if (prevModel && prevModel.type === 'storageUnit') {
|
||||
} else if (prevModel && prevModel.type === "storageUnit") {
|
||||
const position = getMaterialPosition(prevModel.modelUuid, currentMaterial);
|
||||
const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid);
|
||||
|
||||
@@ -218,40 +210,35 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
const materialLocalPos = materialWorldPos.clone();
|
||||
armbotModel.worldToLocal(materialLocalPos);
|
||||
|
||||
if (currentPhase === 'rest-to-start') {
|
||||
if (currentPhase === "rest-to-start") {
|
||||
end = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
} else if (currentPhase === 'start-to-end') {
|
||||
} else if (currentPhase === "start-to-end") {
|
||||
start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
} else if (currentPhase === 'end-to-rest') {
|
||||
} else if (currentPhase === "end-to-rest") {
|
||||
start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nextModel && nextPoint && nextModel.type === 'transfer') {
|
||||
if (nextModel && nextPoint && nextModel.type === "transfer") {
|
||||
const conveyorModel = scene.getObjectByProperty("uuid", nextModel.modelUuid);
|
||||
const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid);
|
||||
if (conveyorModel && armbotModel) {
|
||||
const localPoint = new THREE.Vector3(
|
||||
nextPoint.position[0],
|
||||
nextPoint.position[1],
|
||||
nextPoint.position[2]
|
||||
);
|
||||
const localPoint = new THREE.Vector3(nextPoint.position[0], nextPoint.position[1], nextPoint.position[2]);
|
||||
|
||||
const worldPoint = conveyorModel.localToWorld(localPoint);
|
||||
|
||||
armbotModel.worldToLocal(worldPoint);
|
||||
|
||||
if (currentPhase === 'start-to-end') {
|
||||
if (currentPhase === "start-to-end") {
|
||||
end = [worldPoint.x, worldPoint.y + 0.35, worldPoint.z];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (currentPhase === 'end-to-rest') {
|
||||
if (currentPhase === "end-to-rest") {
|
||||
const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid);
|
||||
const armbotWorldPos = new THREE.Vector3();
|
||||
|
||||
@@ -293,15 +280,7 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
arcPoints = arcCounterClockwise;
|
||||
}
|
||||
|
||||
const pathVectors = [
|
||||
new THREE.Vector3(start[0], start[1], start[2]),
|
||||
new THREE.Vector3(start[0], curveHeight, start[2]),
|
||||
new THREE.Vector3(nearestToStart[0], curveHeight, nearestToStart[2]),
|
||||
...arcPoints.map(point => new THREE.Vector3(point[0], curveHeight, point[2])),
|
||||
new THREE.Vector3(nearestToEnd[0], curveHeight, nearestToEnd[2]),
|
||||
new THREE.Vector3(end[0], curveHeight, end[2]),
|
||||
new THREE.Vector3(end[0], end[1], end[2])
|
||||
];
|
||||
const pathVectors = [new THREE.Vector3(start[0], start[1], start[2]), new THREE.Vector3(start[0], curveHeight, start[2]), new THREE.Vector3(nearestToStart[0], curveHeight, nearestToStart[2]), ...arcPoints.map((point) => new THREE.Vector3(point[0], curveHeight, point[2])), new THREE.Vector3(nearestToEnd[0], curveHeight, nearestToEnd[2]), new THREE.Vector3(end[0], curveHeight, end[2]), new THREE.Vector3(end[0], end[1], end[2])];
|
||||
|
||||
const pathSegments: [THREE.Vector3, THREE.Vector3][] = [];
|
||||
for (let i = 0; i < pathVectors.length - 1; i++) {
|
||||
@@ -426,7 +405,6 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
);
|
||||
})}
|
||||
</group> */}
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import IKInstance from '../ikInstance/ikInstance';
|
||||
import RoboticArmAnimator from '../animator/roboticArmAnimator';
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import IKInstance from "../ikInstance/ikInstance";
|
||||
import RoboticArmAnimator from "../animator/roboticArmAnimator";
|
||||
import MaterialAnimator from "../animator/materialAnimator";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useTriggerHandler } from "../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
const [currentPhase, setCurrentPhase] = useState<(string)>("init");
|
||||
const [currentPhase, setCurrentPhase] = useState<string>("init");
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
const [ikSolver, setIkSolver] = useState<any>(null);
|
||||
const restPosition = new THREE.Vector3(0, 1.75, -1.6);
|
||||
@@ -18,15 +17,13 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
const isPausedRef = useRef<boolean>(false);
|
||||
const isSpeedRef = useRef<any>(null);
|
||||
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore, assetStore } = useSceneContext();
|
||||
const { resetAsset } = assetStore();
|
||||
const { setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = armBotStore();
|
||||
const { decrementVehicleLoad, removeLastMaterial } = vehicleStore();
|
||||
const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = storageUnitStore();
|
||||
const { getMaterialById, setIsVisible } = materialStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid } = productStore();
|
||||
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid, selectedProduct } = productStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
@@ -39,9 +36,9 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
const animationFrameIdRef = useRef<number | null>(null);
|
||||
const previousTimeRef = useRef<number | null>(null);
|
||||
|
||||
const lastRemoved = useRef<{ type: string, materialId: string, modelId: string } | null>(null);
|
||||
const lastRemoved = useRef<{ type: string; materialId: string; modelId: string } | null>(null);
|
||||
|
||||
const action = getActionByUuid(selectedProduct.productUuid, armBot.currentAction?.actionUuid || '');
|
||||
const action = getActionByUuid(selectedProduct.productUuid, armBot.currentAction?.actionUuid || "");
|
||||
|
||||
const handlePickUpTrigger = () => {
|
||||
if (armBot?.currentAction?.materialId) {
|
||||
@@ -49,17 +46,17 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
if (material?.previous?.modelUuid) {
|
||||
const previousModel = getEventByActionUuid(selectedProduct.productUuid, material.previous.actionUuid);
|
||||
if (previousModel) {
|
||||
if (previousModel.type === 'transfer') {
|
||||
if (previousModel.type === "transfer") {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
} else if (previousModel.type === 'machine') {
|
||||
} else if (previousModel.type === "machine") {
|
||||
// machine specific logic
|
||||
} else if (previousModel.type === 'vehicle') {
|
||||
} else if (previousModel.type === "vehicle") {
|
||||
decrementVehicleLoad(previousModel.modelUuid, 1);
|
||||
removeLastMaterial(previousModel.modelUuid);
|
||||
} else if (previousModel.type === 'storageUnit') {
|
||||
} else if (previousModel.type === "storageUnit") {
|
||||
// storage unit logic
|
||||
removeLastStorageMaterial(previousModel.modelUuid);
|
||||
updateCurrentLoad(previousModel.modelUuid, -1)
|
||||
updateCurrentLoad(previousModel.modelUuid, -1);
|
||||
}
|
||||
lastRemoved.current = { type: previousModel.type, materialId: armBot.currentAction.materialId, modelId: previousModel.modelUuid };
|
||||
} else {
|
||||
@@ -69,28 +66,27 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDropTrigger = () => {
|
||||
|
||||
if (armBot.currentAction) {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, armBot.currentAction.actionUuid);
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || "");
|
||||
if (action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
|
||||
if (!model) return;
|
||||
if (model.type === 'transfer') {
|
||||
setIsVisible(armBot.currentAction.materialId || '', true);
|
||||
} else if (model.type === 'machine') {
|
||||
if (model.type === "transfer") {
|
||||
setIsVisible(armBot.currentAction.materialId || "", true);
|
||||
} else if (model.type === "machine") {
|
||||
//
|
||||
} else if (model.type === 'vehicle') {
|
||||
} else if (model.type === "vehicle") {
|
||||
//
|
||||
} else if (model.type === 'storageUnit') {
|
||||
} else if (model.type === "storageUnit") {
|
||||
//
|
||||
}
|
||||
}
|
||||
if (action && armBot.currentAction.materialId) {
|
||||
triggerPointActions(action, armBot.currentAction.materialId)
|
||||
removeCurrentAction(armBot.modelUuid)
|
||||
triggerPointActions(action, armBot.currentAction.materialId);
|
||||
removeCurrentAction(armBot.modelUuid);
|
||||
}
|
||||
|
||||
// if (lastRemoved.current) {
|
||||
@@ -101,7 +97,7 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
isPausedRef.current = isPaused;
|
||||
@@ -113,16 +109,16 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (isReset || !isPlaying) {
|
||||
logStatus(armBot.modelUuid, "Simulation Play Reset Successfully")
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "idle")
|
||||
logStatus(armBot.modelUuid, "Simulation Play Reset Successfully");
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "idle");
|
||||
setCurrentPhase("init");
|
||||
setPath([])
|
||||
setPath([]);
|
||||
setIkSolver(null);
|
||||
removeCurrentAction(armBot.modelUuid);
|
||||
resetAsset(armBot.modelUuid);
|
||||
isPausedRef.current = false
|
||||
pauseTimeRef.current = null
|
||||
isPausedRef.current = false;
|
||||
pauseTimeRef.current = null;
|
||||
activeSecondsElapsed.current = 0;
|
||||
idleSecondsElapsed.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
@@ -131,17 +127,16 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
const targetBones = ikSolver?.mesh.skeleton.bones.find((b: any) => b.name === targetBone
|
||||
);
|
||||
const targetBones = ikSolver?.mesh.skeleton.bones.find((b: any) => b.name === targetBone);
|
||||
if (targetBones && isPlaying) {
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition)
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition);
|
||||
if (curve) {
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]));
|
||||
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.")
|
||||
setPath(curve.points.map((point) => [point.x, point.y, point.z]));
|
||||
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [isReset, isPlaying])
|
||||
}, [isReset, isPlaying]);
|
||||
|
||||
function animate(currentTime: number) {
|
||||
if (previousTimeRef.current === null) {
|
||||
@@ -164,7 +159,7 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return
|
||||
if (!isPlaying) return;
|
||||
|
||||
if (!armBot.isActive && armBot.state === "idle" && (currentPhase === "rest" || currentPhase === "init")) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current!);
|
||||
@@ -173,7 +168,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
// console.log('🚨Final Active Time:',armBot.modelUuid, roundedActiveTime, 'seconds');
|
||||
incrementActiveTime(armBot.modelUuid, roundedActiveTime);
|
||||
activeSecondsElapsed.current = 0;
|
||||
|
||||
} else if (armBot.isActive && armBot.state !== "idle" && currentPhase !== "rest" && armBot.currentAction) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current!);
|
||||
animationFrameIdRef.current = null;
|
||||
@@ -181,7 +175,6 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
// console.log('🕒 Final Idle Time:', armBot.modelUuid,roundedIdleTime, 'seconds');
|
||||
incrementIdleTime(armBot.modelUuid, roundedIdleTime);
|
||||
idleSecondsElapsed.current = 0;
|
||||
|
||||
}
|
||||
if (animationFrameIdRef.current === null) {
|
||||
animationFrameIdRef.current = requestAnimationFrame(animate);
|
||||
@@ -193,28 +186,26 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
animationFrameIdRef.current = null; // Reset the animation frame ID
|
||||
}
|
||||
};
|
||||
|
||||
}, [armBot, currentPhase, isPlaying])
|
||||
}, [armBot, currentPhase, isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
const targetBones = ikSolver?.mesh.skeleton.bones.find((b: any) => b.name === targetBone);
|
||||
if (!isReset && isPlaying) {
|
||||
if (!armBot?.isActive && armBot?.state == "idle" && currentPhase == "init") {
|
||||
if (targetBones) {
|
||||
setArmBotActive(armBot.modelUuid, true)
|
||||
setArmBotState(armBot.modelUuid, "running")
|
||||
setArmBotActive(armBot.modelUuid, true);
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("init-to-rest");
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition)
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, restPosition);
|
||||
if (curve) {
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]));
|
||||
setPath(curve.points.map((point) => [point.x, point.y, point.z]));
|
||||
}
|
||||
}
|
||||
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.")
|
||||
logStatus(armBot.modelUuid, "Moving armBot from initial point to rest position.");
|
||||
} else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && !armBot.currentAction) {
|
||||
logStatus(armBot.modelUuid, "Waiting to trigger CurrentAction")
|
||||
logStatus(armBot.modelUuid, "Waiting to trigger CurrentAction");
|
||||
} else if (armBot && !armBot.isActive && armBot.state === "idle" && currentPhase === "rest" && armBot.currentAction) {
|
||||
if (armBot.currentAction) {
|
||||
|
||||
setArmBotActive(armBot.modelUuid, true);
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("rest-to-start");
|
||||
@@ -223,11 +214,11 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
if (startPoint) {
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]));
|
||||
if (curve) {
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]));
|
||||
setPath(curve.points.map((point) => [point.x, point.y, point.z]));
|
||||
}
|
||||
}
|
||||
}
|
||||
logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.")
|
||||
logStatus(armBot.modelUuid, "Moving armBot from rest point to start position.");
|
||||
} else if (armBot && !armBot.isActive && armBot.state === "running" && currentPhase === "picking" && armBot.currentAction) {
|
||||
setTimeout(() => {
|
||||
setArmBotActive(armBot.modelUuid, true);
|
||||
@@ -240,12 +231,12 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
let curve = createCurveBetweenTwoPoints(new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]), new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]));
|
||||
if (curve) {
|
||||
logStatus(armBot.modelUuid, "picking the object");
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]))
|
||||
setPath(curve.points.map((point) => [point.x, point.y, point.z]));
|
||||
handlePickUpTrigger();
|
||||
}
|
||||
}
|
||||
logStatus(armBot.modelUuid, "Moving armBot from start point to end position.")
|
||||
}, 100)
|
||||
logStatus(armBot.modelUuid, "Moving armBot from start point to end position.");
|
||||
}, 100);
|
||||
} else if (armBot && !armBot.isActive && armBot.state === "running" && currentPhase === "dropping" && armBot.currentAction) {
|
||||
setTimeout(() => {
|
||||
setArmBotActive(armBot.modelUuid, true);
|
||||
@@ -257,25 +248,24 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
let curve = createCurveBetweenTwoPoints(new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]), restPosition);
|
||||
if (curve) {
|
||||
logStatus(armBot.modelUuid, "dropping the object");
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]));
|
||||
setPath(curve.points.map((point) => [point.x, point.y, point.z]));
|
||||
|
||||
handleDropTrigger();
|
||||
|
||||
}
|
||||
}
|
||||
logStatus(armBot.modelUuid, "Moving armBot from end point to rest position.")
|
||||
}, 100)
|
||||
logStatus(armBot.modelUuid, "Moving armBot from end point to rest position.");
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
logStatus(armBot.modelUuid, "Simulation Play Exited")
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "idle")
|
||||
logStatus(armBot.modelUuid, "Simulation Play Exited");
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "idle");
|
||||
setCurrentPhase("init");
|
||||
setIkSolver(null);
|
||||
setPath([])
|
||||
isPausedRef.current = false
|
||||
pauseTimeRef.current = null
|
||||
isPausedRef.current = false
|
||||
setPath([]);
|
||||
isPausedRef.current = false;
|
||||
pauseTimeRef.current = null;
|
||||
isPausedRef.current = false;
|
||||
activeSecondsElapsed.current = 0;
|
||||
idleSecondsElapsed.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
@@ -283,10 +273,9 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
removeCurrentAction(armBot.modelUuid)
|
||||
removeCurrentAction(armBot.modelUuid);
|
||||
}
|
||||
|
||||
}, [currentPhase, armBot, isPlaying, isReset, ikSolver])
|
||||
}, [currentPhase, armBot, isPlaying, isReset, ikSolver]);
|
||||
|
||||
function createCurveBetweenTwoPoints(p1: any, p2: any) {
|
||||
const mid = new THREE.Vector3().addVectors(p1, p2).multiplyScalar(0.5);
|
||||
@@ -297,57 +286,46 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
|
||||
const HandleCallback = () => {
|
||||
if (armBot.isActive && armBot.state == "running" && currentPhase == "init-to-rest") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: rest");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "idle")
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "idle");
|
||||
setCurrentPhase("rest");
|
||||
setPath([])
|
||||
}
|
||||
else if (armBot.state == "running" && currentPhase == "rest-to-start") {
|
||||
setPath([]);
|
||||
} else if (armBot.state == "running" && currentPhase == "rest-to-start") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: pick.");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "running")
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("picking");
|
||||
setPath([])
|
||||
}
|
||||
else if (armBot.isActive && armBot.state == "running" && currentPhase == "start-to-end") {
|
||||
setPath([]);
|
||||
} else if (armBot.isActive && armBot.state == "running" && currentPhase == "start-to-end") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: drop.");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "running")
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("dropping");
|
||||
setPath([])
|
||||
}
|
||||
else if (armBot.isActive && armBot.state == "running" && currentPhase == "end-to-rest") {
|
||||
setPath([]);
|
||||
} else if (armBot.isActive && armBot.state == "running" && currentPhase == "end-to-rest") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: rest, cycle completed.");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
setArmBotState(armBot.modelUuid, "idle")
|
||||
setArmBotActive(armBot.modelUuid, false);
|
||||
setArmBotState(armBot.modelUuid, "idle");
|
||||
setCurrentPhase("rest");
|
||||
setPath([])
|
||||
}
|
||||
setPath([]);
|
||||
}
|
||||
};
|
||||
|
||||
const logStatus = (id: string, status: string) => {
|
||||
// console.log('status: ', status);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isReset && isPlaying && (
|
||||
<>
|
||||
<IKInstance setIkSolver={setIkSolver} armBot={armBot} />
|
||||
<RoboticArmAnimator
|
||||
HandleCallback={HandleCallback}
|
||||
restPosition={restPosition}
|
||||
ikSolver={ikSolver}
|
||||
targetBone={targetBone}
|
||||
armBot={armBot}
|
||||
path={path}
|
||||
currentPhase={currentPhase}
|
||||
/>
|
||||
<RoboticArmAnimator HandleCallback={HandleCallback} restPosition={restPosition} ikSolver={ikSolver} targetBone={targetBone} armBot={armBot} path={path} currentPhase={currentPhase} />
|
||||
</>
|
||||
)}
|
||||
<MaterialAnimator ikSolver={ikSolver} armBot={armBot} currentPhase={currentPhase} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default RoboticArmInstance;
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useActionHandler } from '../actions/useActionHandler';
|
||||
import { usePlayButtonStore, useResetButtonStore } from '../../../store/ui/usePlayButtonStore';
|
||||
import { determineExecutionOrder } from './functions/determineExecutionOrder';
|
||||
import { useProductContext } from '../products/productContext';
|
||||
import { useSceneContext } from '../../scene/sceneContext';
|
||||
import { useEffect } from "react";
|
||||
import { useActionHandler } from "../actions/useActionHandler";
|
||||
import { usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { determineExecutionOrder } from "./functions/determineExecutionOrder";
|
||||
import { useSceneContext } from "../../scene/sceneContext";
|
||||
|
||||
function Simulator() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { productStore } = useSceneContext();
|
||||
const { products, getProductById } = productStore();
|
||||
const { products, getProductById, selectedProduct } = productStore();
|
||||
const { handleAction } = useActionHandler();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
@@ -22,19 +19,12 @@ function Simulator() {
|
||||
|
||||
const executionOrder = determineExecutionOrder([product]);
|
||||
|
||||
executionOrder.forEach(action => {
|
||||
executionOrder.forEach((action) => {
|
||||
handleAction(action);
|
||||
});
|
||||
}, [products, isPlaying, isReset, selectedProduct]);
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<>
|
||||
|
||||
</>
|
||||
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export default Simulator;
|
||||
@@ -10,7 +10,6 @@ import armPick from "../../../../assets/gltf-glb/ui/arm_ui_pick.glb";
|
||||
import armDrop from "../../../../assets/gltf-glb/ui/arm_ui_drop.glb";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
type Positions = {
|
||||
@@ -24,10 +23,8 @@ const ArmBotUI = () => {
|
||||
const { armBotStore, productStore, versionStore } = useSceneContext();
|
||||
const { armBots } = armBotStore();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { getEventByModelUuid, updateAction, getActionByUuid } = productStore();
|
||||
const { getEventByModelUuid, updateAction, getActionByUuid, selectedProduct } = productStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { selectedAction } = useSelectedAction();
|
||||
const { projectId } = useParams();
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { ThreeEvent, useThree } from "@react-three/fiber";
|
||||
import { useSelectedEventData } from "../../../../store/simulation/useSimulationStore";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
|
||||
type OnUpdateCallback = (object: THREE.Object3D) => void;
|
||||
@@ -18,14 +17,12 @@ export default function useDraggableGLTF(
|
||||
minDistance: 1.2,
|
||||
maxDistance: 2,
|
||||
minheight: 0.6,
|
||||
maxheight: 1.9
|
||||
maxheight: 1.9,
|
||||
}
|
||||
) {
|
||||
const { productStore } = useSceneContext();
|
||||
const { getEventByModelUuid } = productStore();
|
||||
const { getEventByModelUuid, selectedProduct } = productStore();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { camera, gl, controls } = useThree();
|
||||
const activeObjRef = useRef<THREE.Object3D | null>(null);
|
||||
const planeRef = useRef<THREE.Plane>(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0));
|
||||
@@ -81,10 +78,7 @@ export default function useDraggableGLTF(
|
||||
const handlePointerMove = (e: PointerEvent) => {
|
||||
if (!activeObjRef.current) return;
|
||||
if (selectedEventData?.data.type === "roboticArm") {
|
||||
const selectedArmBot = getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid
|
||||
);
|
||||
const selectedArmBot = getEventByModelUuid(selectedProduct.productUuid, selectedEventData.data.modelUuid);
|
||||
if (!selectedArmBot) return;
|
||||
// Check if Shift key is pressed
|
||||
const isShiftKeyPressed = e.shiftKey;
|
||||
@@ -99,10 +93,7 @@ export default function useDraggableGLTF(
|
||||
|
||||
// Create a vector to store intersection point
|
||||
const intersection = new THREE.Vector3();
|
||||
const intersects = raycaster.ray.intersectPlane(
|
||||
planeRef.current,
|
||||
intersection
|
||||
);
|
||||
const intersects = raycaster.ray.intersectPlane(planeRef.current, intersection);
|
||||
if (!intersects) return;
|
||||
|
||||
// Add offset for dragging
|
||||
@@ -170,11 +161,7 @@ export default function useDraggableGLTF(
|
||||
const clampedDistance = Math.min(Math.max(distance, minDistance), maxDistance);
|
||||
|
||||
// Calculate local target
|
||||
const finalLocal = new THREE.Vector3(
|
||||
Math.cos(relativeAngle) * clampedDistance,
|
||||
0,
|
||||
Math.sin(relativeAngle) * clampedDistance
|
||||
);
|
||||
const finalLocal = new THREE.Vector3(Math.cos(relativeAngle) * clampedDistance, 0, Math.sin(relativeAngle) * clampedDistance);
|
||||
|
||||
// Rotate back to world space
|
||||
finalLocal.applyQuaternion(robotQuaternion);
|
||||
@@ -184,10 +171,7 @@ export default function useDraggableGLTF(
|
||||
|
||||
// Clamp Y axis using variables
|
||||
|
||||
targetPosition.y = Math.min(
|
||||
Math.max(targetPosition.y, Math.min(minHeight, maxHeight)),
|
||||
Math.max(minHeight, maxHeight)
|
||||
);
|
||||
targetPosition.y = Math.min(Math.max(targetPosition.y, Math.min(minHeight, maxHeight)), Math.max(minHeight, maxHeight));
|
||||
|
||||
// Convert to local if parent exists
|
||||
if (parent) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import { DoubleSide, Group, Plane, Vector3 } from "three";
|
||||
import startPoint from "../../../../assets/gltf-glb/ui/arrow_green.glb";
|
||||
import startEnd from "../../../../assets/gltf-glb/ui/arrow_red.glb";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
const VehicleUI = () => {
|
||||
@@ -18,11 +17,9 @@ const VehicleUI = () => {
|
||||
const { scene: endScene } = useGLTF(startEnd) as any;
|
||||
const prevMousePos = useRef({ x: 0, y: 0 });
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { vehicleStore, productStore, versionStore } = useSceneContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { vehicles, getVehicleById } = vehicleStore();
|
||||
const { updateEvent } = productStore();
|
||||
const { updateEvent, selectedProduct } = productStore();
|
||||
const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 1, 0]);
|
||||
|
||||
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 1, 0]);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,17 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { NavMeshQuery } from '@recast-navigation/core';
|
||||
import { useNavMesh, useSelectedPath } from '../../../../../store/builder/store';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/ui/usePlayButtonStore';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../../products/productContext';
|
||||
import InteractivePoints from '../animator/interactivePoint';
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { NavMeshQuery } from "@recast-navigation/core";
|
||||
import { useNavMesh, useSelectedPath } from "../../../../../store/builder/store";
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
||||
import { useTriggerHandler } from "../../../triggers/triggerHandler/useTriggerHandler";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import InteractivePoints from "../animator/interactivePoint";
|
||||
|
||||
import MaterialAnimator from '../animator/materialAnimator';
|
||||
import VehicleAnimator from '../animator/vehicleAnimator';
|
||||
import MaterialAnimator from "../animator/materialAnimator";
|
||||
import VehicleAnimator from "../animator/vehicleAnimator";
|
||||
|
||||
import { useHumanEventManager } from '../../../human/eventManager/useHumanEventManager';
|
||||
import { useCraneEventManager } from '../../../crane/eventManager/useCraneEventManager';
|
||||
import { useHumanEventManager } from "../../../human/eventManager/useHumanEventManager";
|
||||
import { useCraneEventManager } from "../../../crane/eventManager/useCraneEventManager";
|
||||
|
||||
function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) {
|
||||
const { navMesh } = useNavMesh();
|
||||
@@ -28,9 +27,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
const { setCurrentAnimation, getAssetById } = assetStore();
|
||||
const { addHumanToMonitor } = useHumanEventManager();
|
||||
const { addCraneToMonitor } = useCraneEventManager();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid, selectedProduct } = productStore();
|
||||
const { vehicles, setCurrentPhase, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = vehicleStore();
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
const pauseTimeRef = useRef<number | null>(null);
|
||||
@@ -59,22 +56,19 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
try {
|
||||
const navMeshQuery = new NavMeshQuery(navMesh);
|
||||
const { path: segmentPath } = navMeshQuery.computePath(start, end);
|
||||
if (
|
||||
segmentPath.length > 0 &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
||||
) {
|
||||
if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)) {
|
||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
} else {
|
||||
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
}
|
||||
|
||||
} catch {
|
||||
console.error("Failed to compute path");
|
||||
return [];
|
||||
}
|
||||
}, [navMesh]);
|
||||
},
|
||||
[navMesh]
|
||||
);
|
||||
|
||||
function vehicleStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
@@ -82,22 +76,22 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
// Function to reset everything
|
||||
function reset() {
|
||||
setCurrentPhase(agvDetail.modelUuid, 'stationed');
|
||||
setCurrentPhase(agvDetail.modelUuid, "stationed");
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
setVehicleState(agvDetail.modelUuid, "idle");
|
||||
setVehicleLoad(agvDetail.modelUuid, 0);
|
||||
setPath([]);
|
||||
startTime = 0;
|
||||
isPausedRef.current = false;
|
||||
pauseTimeRef.current = 0;
|
||||
resetTime(agvDetail.modelUuid)
|
||||
activeTimeRef.current = 0
|
||||
idleTimeRef.current = 0
|
||||
previousTimeRef.current = null
|
||||
resetTime(agvDetail.modelUuid);
|
||||
activeTimeRef.current = 0;
|
||||
idleTimeRef.current = 0;
|
||||
previousTimeRef.current = null;
|
||||
if (animationFrameIdRef.current !== null) {
|
||||
cancelAnimationFrame(animationFrameIdRef.current)
|
||||
animationFrameIdRef.current = null
|
||||
cancelAnimationFrame(animationFrameIdRef.current);
|
||||
animationFrameIdRef.current = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,51 +99,41 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
if (isPlaying && selectedPath === "auto") {
|
||||
if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return;
|
||||
|
||||
if (!agvDetail.isActive && agvDetail.state === 'idle' && agvDetail.currentPhase === 'stationed') {
|
||||
const toPickupPath = computePath(
|
||||
new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]),
|
||||
agvDetail?.point?.action?.pickUpPoint?.position
|
||||
);
|
||||
if (!agvDetail.isActive && agvDetail.state === "idle" && agvDetail.currentPhase === "stationed") {
|
||||
const toPickupPath = computePath(new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]), agvDetail?.point?.action?.pickUpPoint?.position);
|
||||
|
||||
setPath(toPickupPath);
|
||||
setCurrentPhase(agvDetail.modelUuid, 'stationed-pickup');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setCurrentPhase(agvDetail.modelUuid, "stationed-pickup");
|
||||
setVehicleState(agvDetail.modelUuid, "running");
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup');
|
||||
vehicleStatus(agvDetail.modelUuid, "Started from station, heading to pickup");
|
||||
return;
|
||||
} else if (!agvDetail.isActive && agvDetail.state === 'idle' && agvDetail.currentPhase === 'picking') {
|
||||
} else if (!agvDetail.isActive && agvDetail.state === "idle" && agvDetail.currentPhase === "picking") {
|
||||
if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.currentMaterials.length > 0) {
|
||||
if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) {
|
||||
const toDrop = computePath(
|
||||
agvDetail.point.action.pickUpPoint.position,
|
||||
agvDetail.point.action.unLoadPoint.position
|
||||
);
|
||||
const toDrop = computePath(agvDetail.point.action.pickUpPoint.position, agvDetail.point.action.unLoadPoint.position);
|
||||
setPath(toDrop);
|
||||
setCurrentPhase(agvDetail.modelUuid, 'pickup-drop');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setCurrentPhase(agvDetail.modelUuid, "pickup-drop");
|
||||
setVehicleState(agvDetail.modelUuid, "running");
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from pickup point, heading to drop point');
|
||||
vehicleStatus(agvDetail.modelUuid, "Started from pickup point, heading to drop point");
|
||||
}
|
||||
}
|
||||
} else if (!agvDetail.isActive && agvDetail.state === 'idle' && agvDetail.currentPhase === 'dropping' && agvDetail.currentLoad === 0) {
|
||||
} else if (!agvDetail.isActive && agvDetail.state === "idle" && agvDetail.currentPhase === "dropping" && agvDetail.currentLoad === 0) {
|
||||
if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) {
|
||||
const dropToPickup = computePath(
|
||||
agvDetail.point.action.unLoadPoint.position,
|
||||
agvDetail.point.action.pickUpPoint.position
|
||||
);
|
||||
const dropToPickup = computePath(agvDetail.point.action.unLoadPoint.position, agvDetail.point.action.pickUpPoint.position);
|
||||
setPath(dropToPickup);
|
||||
setCurrentPhase(agvDetail.modelUuid, 'drop-pickup');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setCurrentPhase(agvDetail.modelUuid, "drop-pickup");
|
||||
setVehicleState(agvDetail.modelUuid, "running");
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point');
|
||||
vehicleStatus(agvDetail.modelUuid, "Started from dropping point, heading to pickup point");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
reset()
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}, [vehicles, agvDetail.currentPhase, path, isPlaying, selectedPath]);
|
||||
|
||||
@@ -174,7 +158,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return
|
||||
if (!isPlaying) return;
|
||||
if (!agvDetail.isActive) {
|
||||
const roundedActiveTime = Math.round(activeTimeRef.current);
|
||||
// console.log('Final Active Time:', roundedActiveTime, 'seconds');
|
||||
@@ -200,63 +184,63 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}, [agvDetail, isPlaying]);
|
||||
|
||||
function handleCallBack() {
|
||||
if (agvDetail.currentPhase === 'stationed-pickup') {
|
||||
setCurrentPhase(agvDetail.modelUuid, 'picking');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
if (agvDetail.currentPhase === "stationed-pickup") {
|
||||
setCurrentPhase(agvDetail.modelUuid, "picking");
|
||||
setVehicleState(agvDetail.modelUuid, "idle");
|
||||
setVehiclePicking(agvDetail.modelUuid, true);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Reached pickup point, waiting for material');
|
||||
vehicleStatus(agvDetail.modelUuid, "Reached pickup point, waiting for material");
|
||||
setPath([]);
|
||||
} else if (agvDetail.currentPhase === 'pickup-drop') {
|
||||
setCurrentPhase(agvDetail.modelUuid, 'dropping');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
} else if (agvDetail.currentPhase === "pickup-drop") {
|
||||
setCurrentPhase(agvDetail.modelUuid, "dropping");
|
||||
setVehicleState(agvDetail.modelUuid, "idle");
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Reached drop point');
|
||||
vehicleStatus(agvDetail.modelUuid, "Reached drop point");
|
||||
setPath([]);
|
||||
} else if (agvDetail.currentPhase === 'drop-pickup') {
|
||||
setCurrentPhase(agvDetail.modelUuid, 'picking');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
} else if (agvDetail.currentPhase === "drop-pickup") {
|
||||
setCurrentPhase(agvDetail.modelUuid, "picking");
|
||||
setVehicleState(agvDetail.modelUuid, "idle");
|
||||
setVehiclePicking(agvDetail.modelUuid, true);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
setPath([]);
|
||||
clearCurrentMaterials(agvDetail.modelUuid)
|
||||
vehicleStatus(agvDetail.modelUuid, 'Reached pickup point again, cycle complete');
|
||||
clearCurrentMaterials(agvDetail.modelUuid);
|
||||
vehicleStatus(agvDetail.modelUuid, "Reached pickup point again, cycle complete");
|
||||
}
|
||||
}
|
||||
|
||||
function startUnloadingProcess() {
|
||||
if (agvDetail.point.action.triggers.length > 0) {
|
||||
const trigger = getTriggerByUuid(selectedProduct.productUuid, agvDetail.point.action.triggers[0]?.triggerUuid);
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredModel?.modelUuid || '');
|
||||
const triggeredAction = getActionByUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredAction?.actionUuid || '');
|
||||
const model = getEventByModelUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredModel?.modelUuid || "");
|
||||
const triggeredAction = getActionByUuid(selectedProduct.productUuid, trigger?.triggeredAsset?.triggeredAction?.actionUuid || "");
|
||||
|
||||
if (trigger && model) {
|
||||
if (model.type === 'transfer') {
|
||||
if (model.type === "transfer") {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
|
||||
if (action) {
|
||||
handleMaterialDropToConveyor(model);
|
||||
}
|
||||
} else if (model.type === 'machine') {
|
||||
} else if (model.type === "machine") {
|
||||
//
|
||||
} else if (model.type === 'roboticArm') {
|
||||
} else if (model.type === "roboticArm") {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
|
||||
if (action) {
|
||||
handleMaterialDropToArmBot(model);
|
||||
}
|
||||
} else if (model.type === 'storageUnit') {
|
||||
} else if (model.type === "storageUnit") {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
|
||||
if (action) {
|
||||
handleMaterialDropToStorageUnit(model);
|
||||
}
|
||||
} else if (model.type === 'human') {
|
||||
} else if (model.type === "human") {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
|
||||
if (action && (triggeredAction?.actionType === 'manufacturer' || triggeredAction?.actionType === 'worker')) {
|
||||
if (action && (triggeredAction?.actionType === "manufacturer" || triggeredAction?.actionType === "worker")) {
|
||||
handleMaterialDropToHuman(model, triggeredAction);
|
||||
}
|
||||
} else if (model.type === 'crane') {
|
||||
} else if (model.type === "crane") {
|
||||
const action = getActionByUuid(selectedProduct.productUuid, agvDetail.point.action.actionUuid);
|
||||
if (action && (triggeredAction?.actionType === 'pickAndDrop')) {
|
||||
if (action && triggeredAction?.actionType === "pickAndDrop") {
|
||||
handleMaterialDropToCrane(model, triggeredAction);
|
||||
addCraneAction(model.modelUuid, triggeredAction.actionUuid, null, null);
|
||||
}
|
||||
@@ -274,25 +258,20 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
|
||||
function handleMaterialDropToCrane(model: CraneEventSchema, action: CraneAction) {
|
||||
|
||||
if (model) {
|
||||
if (action.actionType === 'pickAndDrop') {
|
||||
addCraneToMonitor(model.modelUuid, () => {
|
||||
loopMaterialDropToCrane(
|
||||
agvDetail,
|
||||
if (action.actionType === "pickAndDrop") {
|
||||
addCraneToMonitor(
|
||||
model.modelUuid,
|
||||
action.actionUuid
|
||||
() => {
|
||||
loopMaterialDropToCrane(agvDetail, model.modelUuid, action.actionUuid);
|
||||
},
|
||||
action.actionUuid || ""
|
||||
);
|
||||
}, action.actionUuid || '')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loopMaterialDropToCrane(
|
||||
vehicle: VehicleStatus,
|
||||
craneId: string,
|
||||
craneActionId: string
|
||||
) {
|
||||
function loopMaterialDropToCrane(vehicle: VehicleStatus, craneId: string, craneActionId: string) {
|
||||
let currentVehicleLoad = vehicle.currentLoad;
|
||||
|
||||
const unloadLoop = () => {
|
||||
@@ -308,7 +287,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
setIsVisible(material.materialId, false);
|
||||
}
|
||||
return;
|
||||
} else if (!crane.isCarrying && !crane.isActive && crane.currentLoad < (craneaction?.maxPickUpCount || 0) && craneaction?.actionType === 'pickAndDrop') {
|
||||
} else if (!crane.isCarrying && !crane.isActive && crane.currentLoad < (craneaction?.maxPickUpCount || 0) && craneaction?.actionType === "pickAndDrop") {
|
||||
const material = getLastMaterial(vehicle.modelUuid);
|
||||
if (material) {
|
||||
incrementCraneLoad(craneId, 1);
|
||||
@@ -318,7 +297,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(unloadLoop);
|
||||
}, 500)
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const crane = getCraneById(craneId);
|
||||
@@ -326,31 +305,25 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
if (crane && crane.currentLoad < (craneaction?.maxPickUpCount || 0)) {
|
||||
setTimeout(() => {
|
||||
unloadLoop();
|
||||
}, 500)
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleMaterialDropToHuman(model: HumanEventSchema, action: HumanAction) {
|
||||
|
||||
if (model) {
|
||||
if (action.actionType === 'worker') {
|
||||
addHumanToMonitor(model.modelUuid, () => {
|
||||
loopMaterialDropToHuman(
|
||||
agvDetail,
|
||||
if (action.actionType === "worker") {
|
||||
addHumanToMonitor(
|
||||
model.modelUuid,
|
||||
action.actionUuid
|
||||
() => {
|
||||
loopMaterialDropToHuman(agvDetail, model.modelUuid, action.actionUuid);
|
||||
},
|
||||
action.actionUuid || ""
|
||||
);
|
||||
}, action.actionUuid || '')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loopMaterialDropToHuman(
|
||||
vehicle: VehicleStatus,
|
||||
humanId: string,
|
||||
humanActionId: string
|
||||
) {
|
||||
function loopMaterialDropToHuman(vehicle: VehicleStatus, humanId: string, humanActionId: string) {
|
||||
let currentVehicleLoad = vehicle.currentLoad;
|
||||
|
||||
const unloadLoop = () => {
|
||||
@@ -359,8 +332,8 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
const humanAction = human?.point.actions.find((action) => action.actionUuid === humanActionId);
|
||||
|
||||
if (!human || human.currentAction?.actionUuid !== humanAction?.actionUuid) return;
|
||||
if (!human.isActive && human.currentLoad < (humanAction?.loadCapacity || 0) && humanAsset?.animationState?.current === 'idle' && humanAction?.actionType === 'worker') {
|
||||
setCurrentAnimation(human.modelUuid, 'pickup', true, false, false);
|
||||
if (!human.isActive && human.currentLoad < (humanAction?.loadCapacity || 0) && humanAsset?.animationState?.current === "idle" && humanAction?.actionType === "worker") {
|
||||
setCurrentAnimation(human.modelUuid, "pickup", true, false, false);
|
||||
decrementVehicleLoad(vehicle.modelUuid, 1);
|
||||
currentVehicleLoad -= 1;
|
||||
const material = removeLastMaterial(vehicle.modelUuid);
|
||||
@@ -373,7 +346,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(unloadLoop);
|
||||
}, 500)
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const human = getHumanById(humanId);
|
||||
@@ -384,33 +357,19 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
setTimeout(() => {
|
||||
unloadLoop();
|
||||
}, 500)
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMaterialDropToStorageUnit(model: StorageEventSchema) {
|
||||
if (model) {
|
||||
loopMaterialDropToStorage(
|
||||
agvDetail.modelUuid,
|
||||
agvDetail.currentLoad,
|
||||
agvDetail.point.action.unLoadDuration,
|
||||
model.modelUuid,
|
||||
model.storageCapacity,
|
||||
agvDetail.point.action
|
||||
);
|
||||
loopMaterialDropToStorage(agvDetail.modelUuid, agvDetail.currentLoad, agvDetail.point.action.unLoadDuration, model.modelUuid, model.storageCapacity, agvDetail.point.action);
|
||||
}
|
||||
}
|
||||
|
||||
function loopMaterialDropToStorage(
|
||||
vehicleId: string,
|
||||
vehicleCurrentLoad: number,
|
||||
unLoadDuration: number,
|
||||
storageUnitId: string,
|
||||
storageMaxCapacity: number,
|
||||
action: VehicleAction
|
||||
) {
|
||||
function loopMaterialDropToStorage(vehicleId: string, vehicleCurrentLoad: number, unLoadDuration: number, storageUnitId: string, storageMaxCapacity: number, action: VehicleAction) {
|
||||
startTime = performance.now();
|
||||
const fixedInterval = ((unLoadDuration / vehicleCurrentLoad) * (1000 / isSpeedRef.current));
|
||||
const fixedInterval = (unLoadDuration / vehicleCurrentLoad) * (1000 / isSpeedRef.current);
|
||||
|
||||
const unloadLoop = () => {
|
||||
if (isPausedRef.current) {
|
||||
@@ -429,18 +388,13 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
const storageUnit = getStorageUnitById(storageUnitId);
|
||||
|
||||
if (elapsedTime >= fixedInterval) {
|
||||
if (storageUnit && agvDetail &&
|
||||
storageUnit.currentLoad < storageMaxCapacity &&
|
||||
vehicleCurrentLoad > 0) {
|
||||
|
||||
if (storageUnit && agvDetail && storageUnit.currentLoad < storageMaxCapacity && vehicleCurrentLoad > 0) {
|
||||
decrementVehicleLoad(vehicleId, 1);
|
||||
vehicleCurrentLoad -= 1;
|
||||
|
||||
const material = removeLastMaterial(vehicleId);
|
||||
if (material) {
|
||||
|
||||
triggerPointActions(action, material.materialId);
|
||||
|
||||
}
|
||||
|
||||
if (vehicleCurrentLoad > 0 && storageUnit.currentLoad < storageMaxCapacity) {
|
||||
@@ -462,23 +416,11 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
function handleMaterialDropToConveyor(model: ConveyorEventSchema) {
|
||||
const conveyor = getConveyorById(model.modelUuid);
|
||||
if (conveyor) {
|
||||
loopMaterialDropToConveyor(
|
||||
agvDetail.modelUuid,
|
||||
agvDetail.currentLoad,
|
||||
conveyor.modelUuid,
|
||||
agvDetail.point.action.unLoadDuration,
|
||||
agvDetail.point.action
|
||||
);
|
||||
loopMaterialDropToConveyor(agvDetail.modelUuid, agvDetail.currentLoad, conveyor.modelUuid, agvDetail.point.action.unLoadDuration, agvDetail.point.action);
|
||||
}
|
||||
}
|
||||
|
||||
function loopMaterialDropToConveyor(
|
||||
vehicleId: string,
|
||||
vehicleCurrentLoad: number,
|
||||
conveyorId: string,
|
||||
unLoadDuration: number,
|
||||
action: VehicleAction
|
||||
) {
|
||||
function loopMaterialDropToConveyor(vehicleId: string, vehicleCurrentLoad: number, conveyorId: string, unLoadDuration: number, action: VehicleAction) {
|
||||
let lastIncrementTime = performance.now();
|
||||
let pauseStartTime: number | null = null;
|
||||
let totalPausedDuration = 0;
|
||||
@@ -487,7 +429,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
const dropLoop = (currentTime: number) => {
|
||||
const conveyor = getConveyorById(conveyorId);
|
||||
|
||||
if (isPausedRef.current || (conveyor?.isPaused)) {
|
||||
if (isPausedRef.current || conveyor?.isPaused) {
|
||||
if (pauseStartTime === null) {
|
||||
pauseStartTime = currentTime;
|
||||
}
|
||||
@@ -531,28 +473,16 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
function handleMaterialDropToArmBot(model: RoboticArmEventSchema) {
|
||||
const armBot = getArmBotById(model.modelUuid);
|
||||
if (armBot && armBot.state === 'idle' && !armBot.isActive) {
|
||||
loopMaterialDropToArmBot(
|
||||
agvDetail.modelUuid,
|
||||
agvDetail.currentLoad,
|
||||
agvDetail.point.action.unLoadDuration,
|
||||
model.modelUuid,
|
||||
agvDetail.point.action
|
||||
);
|
||||
if (armBot && armBot.state === "idle" && !armBot.isActive) {
|
||||
loopMaterialDropToArmBot(agvDetail.modelUuid, agvDetail.currentLoad, agvDetail.point.action.unLoadDuration, model.modelUuid, agvDetail.point.action);
|
||||
}
|
||||
}
|
||||
|
||||
function loopMaterialDropToArmBot(
|
||||
vehicleId: string,
|
||||
vehicleCurrentLoad: number,
|
||||
unLoadDuration: number,
|
||||
armBotId: string,
|
||||
action: VehicleAction
|
||||
) {
|
||||
function loopMaterialDropToArmBot(vehicleId: string, vehicleCurrentLoad: number, unLoadDuration: number, armBotId: string, action: VehicleAction) {
|
||||
startTime = performance.now();
|
||||
const armBot = getArmBotById(armBotId);
|
||||
|
||||
if (!armBot || armBot.state !== 'idle' || armBot.isActive || vehicleCurrentLoad <= 0) {
|
||||
if (!armBot || armBot.state !== "idle" || armBot.isActive || vehicleCurrentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -582,7 +512,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
setTimeout(() => {
|
||||
const waitForNextTransfer = () => {
|
||||
const currentArmBot = getArmBotById(armBotId);
|
||||
if (currentArmBot && currentArmBot.state === 'idle' && !currentArmBot.isActive) {
|
||||
if (currentArmBot && currentArmBot.state === "idle" && !currentArmBot.isActive) {
|
||||
startTime = performance.now();
|
||||
loopMaterialDropToArmBot(vehicleId, vehicleCurrentLoad, unLoadDuration, armBotId, action);
|
||||
} else {
|
||||
@@ -590,7 +520,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
}
|
||||
};
|
||||
waitForNextTransfer();
|
||||
}, 0)
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -616,7 +546,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
const elapsedTime = performance.now() - startTime;
|
||||
const unLoadDuration = agvDetail.point.action.unLoadDuration;
|
||||
fixedInterval = ((unLoadDuration / agvDetail.currentLoad) * (1000 / isSpeedRef.current));
|
||||
fixedInterval = (unLoadDuration / agvDetail.currentLoad) * (1000 / isSpeedRef.current);
|
||||
|
||||
if (elapsedTime >= fixedInterval) {
|
||||
let droppedMat = droppedMaterial - 1;
|
||||
@@ -639,16 +569,8 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
return (
|
||||
<>
|
||||
<VehicleAnimator
|
||||
path={path}
|
||||
handleCallBack={handleCallBack}
|
||||
currentPhase={agvDetail.currentPhase}
|
||||
agvUuid={agvDetail?.modelUuid}
|
||||
agvDetail={agvDetail}
|
||||
reset={reset}
|
||||
startUnloadingProcess={startUnloadingProcess}
|
||||
/>
|
||||
{selectedPath === "manual" && (<InteractivePoints agvUuid={agvDetail?.modelUuid} />)}
|
||||
<VehicleAnimator path={path} handleCallBack={handleCallBack} currentPhase={agvDetail.currentPhase} agvUuid={agvDetail?.modelUuid} agvDetail={agvDetail} reset={reset} startUnloadingProcess={startUnloadingProcess} />
|
||||
{selectedPath === "manual" && <InteractivePoints agvUuid={agvDetail?.modelUuid} />}
|
||||
<MaterialAnimator agvDetail={agvDetail} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -13,7 +13,6 @@ import { getUserData } from "../functions/getUserData";
|
||||
import { SceneProvider } from "../modules/scene/sceneContext";
|
||||
import { sharedWithMeProjects } from "../services/dashboard/sharedWithMeProject";
|
||||
import { handleCanvasCursors } from "../utils/mouseUtils/handleCanvasCursors";
|
||||
import { ProductProvider } from "../modules/simulation/products/productContext";
|
||||
import MainScene from "../components/layout/scenes/MainScene";
|
||||
import ComparisonScene from "../components/layout/scenes/ComparisonScene";
|
||||
|
||||
@@ -84,14 +83,10 @@ const Project: React.FC = () => {
|
||||
return (
|
||||
<div className="project-main">
|
||||
<SceneProvider layout="Main Layout">
|
||||
<ProductProvider>
|
||||
<MainScene />
|
||||
</ProductProvider>
|
||||
</SceneProvider>
|
||||
<SceneProvider layout="Comparison Layout">
|
||||
<ProductProvider>
|
||||
<ComparisonScene />
|
||||
</ProductProvider>
|
||||
</SceneProvider>
|
||||
{selectedUser && <FollowPerson />}
|
||||
{isLogListVisible && (
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { create } from 'zustand';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { create } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
type ProductsStore = {
|
||||
products: productsSchema;
|
||||
selectedProduct: { productUuid: string; productName: string };
|
||||
|
||||
setSelectedProduct: (productUuid: string, productName: string) => void;
|
||||
clearSelectedProduct: () => void;
|
||||
|
||||
// Product-level actions
|
||||
addProduct: (productName: string, productUuid: string) => void;
|
||||
@@ -20,39 +24,17 @@ type ProductsStore = {
|
||||
// Point-level actions
|
||||
addPoint: (productUuid: string, modelUuid: string, point: PointsScheme) => EventsSchema | undefined;
|
||||
removePoint: (productUuid: string, modelUuid: string, pointUuid: string) => EventsSchema | undefined;
|
||||
updatePoint: (
|
||||
productUuid: string,
|
||||
modelUuid: string,
|
||||
pointUuid: string,
|
||||
updates: Partial<PointsScheme>
|
||||
) => EventsSchema | undefined;
|
||||
updatePoint: (productUuid: string, modelUuid: string, pointUuid: string, updates: Partial<PointsScheme>) => EventsSchema | undefined;
|
||||
|
||||
// Action-level actions
|
||||
addAction: (
|
||||
productUuid: string,
|
||||
modelUuid: string,
|
||||
pointUuid: string,
|
||||
action: ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction
|
||||
) => EventsSchema | undefined;
|
||||
addAction: (productUuid: string, modelUuid: string, pointUuid: string, action: ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction) => EventsSchema | undefined;
|
||||
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
||||
updateAction: (
|
||||
productUuid: string,
|
||||
actionUuid: string,
|
||||
updates: Partial<ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction>
|
||||
) => EventsSchema | undefined;
|
||||
updateAction: (productUuid: string, actionUuid: string, updates: Partial<ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction>) => EventsSchema | undefined;
|
||||
|
||||
// Trigger-level actionss
|
||||
addTrigger: (
|
||||
productUuid: string,
|
||||
actionUuid: string,
|
||||
trigger: TriggerSchema
|
||||
) => EventsSchema | undefined;
|
||||
addTrigger: (productUuid: string, actionUuid: string, trigger: TriggerSchema) => EventsSchema | undefined;
|
||||
removeTrigger: (productUuid: string, triggerUuid: string) => EventsSchema | undefined;
|
||||
updateTrigger: (
|
||||
productUuid: string,
|
||||
triggerUuid: string,
|
||||
updates: Partial<TriggerSchema>
|
||||
) => EventsSchema | undefined;
|
||||
updateTrigger: (productUuid: string, triggerUuid: string, updates: Partial<TriggerSchema>) => EventsSchema | undefined;
|
||||
|
||||
// Renaming functions
|
||||
renameProduct: (productUuid: string, newName: string) => void;
|
||||
@@ -68,9 +50,9 @@ type ProductsStore = {
|
||||
getPointByUuid: (productUuid: string, modelUuid: string, pointUuid: string) => PointsScheme | undefined;
|
||||
getActionByUuid: (productUuid: string, actionUuid: string) => (ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction) | undefined;
|
||||
getActionByPointUuid: (productUuid: string, pointUuid: string) => (ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction | CraneAction) | undefined;
|
||||
getModelUuidByPointUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
|
||||
getModelUuidByActionUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
|
||||
getPointUuidByActionUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
|
||||
getModelUuidByPointUuid: (productUuid: string, actionUuid: string) => string | undefined;
|
||||
getModelUuidByActionUuid: (productUuid: string, actionUuid: string) => string | undefined;
|
||||
getPointUuidByActionUuid: (productUuid: string, actionUuid: string) => string | undefined;
|
||||
getTriggerByUuid: (productUuid: string, triggerUuid: string) => TriggerSchema | undefined;
|
||||
getTriggersByTriggeredPointUuid: (productUuid: string, triggeredPointUuid: string) => TriggerSchema[];
|
||||
getTriggeringModels: (productUuid: string, actionUUid: string) => EventsSchema[];
|
||||
@@ -81,16 +63,30 @@ export const createProductStore = () => {
|
||||
return create<ProductsStore>()(
|
||||
immer((set, get) => ({
|
||||
products: [],
|
||||
selectedProduct: { productUuid: "", productName: "" },
|
||||
|
||||
setSelectedProduct: (productUuid, productName) => {
|
||||
set((state) => {
|
||||
state.selectedProduct.productUuid = productUuid;
|
||||
state.selectedProduct.productName = productName;
|
||||
});
|
||||
},
|
||||
clearSelectedProduct: () => {
|
||||
set((state) => {
|
||||
state.selectedProduct.productUuid = "";
|
||||
state.selectedProduct.productName = "";
|
||||
});
|
||||
},
|
||||
|
||||
// Product-level actions
|
||||
addProduct: (productName, productUuid) => {
|
||||
set((state) => {
|
||||
const existingProduct = state.products.find(p => p.productUuid === productUuid);
|
||||
const existingProduct = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (!existingProduct) {
|
||||
const newProduct = {
|
||||
productName,
|
||||
productUuid: productUuid,
|
||||
eventDatas: []
|
||||
eventDatas: [],
|
||||
};
|
||||
state.products.push(newProduct);
|
||||
}
|
||||
@@ -106,18 +102,20 @@ export const createProductStore = () => {
|
||||
clearProducts: () => {
|
||||
set((state) => {
|
||||
state.products = [];
|
||||
state.selectedProduct.productUuid = "";
|
||||
state.selectedProduct.productName = "";
|
||||
});
|
||||
},
|
||||
|
||||
removeProduct: (productUuid) => {
|
||||
set((state) => {
|
||||
state.products = state.products.filter(p => p.productUuid !== productUuid);
|
||||
state.products = state.products.filter((p) => p.productUuid !== productUuid);
|
||||
});
|
||||
},
|
||||
|
||||
updateProduct: (productUuid, updates) => {
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
Object.assign(product, updates);
|
||||
}
|
||||
@@ -127,9 +125,9 @@ export const createProductStore = () => {
|
||||
// Event-level actions
|
||||
addEvent: (productUuid, event) => {
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const existingEvent = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === event.modelUuid);
|
||||
const existingEvent = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === event.modelUuid);
|
||||
if (!existingEvent) {
|
||||
product.eventDatas.push(event);
|
||||
}
|
||||
@@ -139,9 +137,9 @@ export const createProductStore = () => {
|
||||
|
||||
removeEvent: (productUuid, modelUuid) => {
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
product.eventDatas = product.eventDatas.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
|
||||
product.eventDatas = product.eventDatas.filter((e) => "modelUuid" in e && e.modelUuid !== modelUuid);
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -152,21 +150,21 @@ export const createProductStore = () => {
|
||||
const actionsToDelete = new Set<string>();
|
||||
|
||||
for (const product of state.products) {
|
||||
const eventIndex = product.eventDatas.findIndex(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
const eventIndex = product.eventDatas.findIndex((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (eventIndex !== -1) {
|
||||
const event = product.eventDatas[eventIndex];
|
||||
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action) {
|
||||
actionsToDelete.add(point.action.actionUuid);
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action) {
|
||||
if ("action" in point && point.action) {
|
||||
actionsToDelete.add(point.action.actionUuid);
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
actionsToDelete.add(action.actionUuid);
|
||||
}
|
||||
@@ -181,43 +179,34 @@ export const createProductStore = () => {
|
||||
for (const event of product.eventDatas) {
|
||||
let eventModified = false;
|
||||
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.triggers) {
|
||||
const originalLength = point.action.triggers.length;
|
||||
point.action.triggers = point.action.triggers.filter(trigger => {
|
||||
return !(
|
||||
(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid) ||
|
||||
(actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ''))
|
||||
);
|
||||
point.action.triggers = point.action.triggers.filter((trigger) => {
|
||||
return !(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid || actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ""));
|
||||
});
|
||||
if (point.action.triggers.length !== originalLength) {
|
||||
eventModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.triggers) {
|
||||
if ("action" in point && point.action?.triggers) {
|
||||
const originalLength = point.action.triggers.length;
|
||||
point.action.triggers = point.action.triggers.filter((trigger: TriggerSchema) => {
|
||||
return !(
|
||||
(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid) ||
|
||||
(actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ''))
|
||||
);
|
||||
return !(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid || actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ""));
|
||||
});
|
||||
if (point.action.triggers.length !== originalLength) {
|
||||
eventModified = true;
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if (action.triggers) {
|
||||
const originalLength = action.triggers.length;
|
||||
action.triggers = action.triggers.filter((trigger: TriggerSchema) => {
|
||||
return !(
|
||||
(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid) ||
|
||||
(actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ''))
|
||||
);
|
||||
return !(trigger.triggeredAsset?.triggeredModel?.modelUuid === modelUuid || actionsToDelete.has(trigger.triggeredAsset?.triggeredAction?.actionUuid || ""));
|
||||
});
|
||||
if (action.triggers.length !== originalLength) {
|
||||
eventModified = true;
|
||||
@@ -239,9 +228,9 @@ export const createProductStore = () => {
|
||||
updateEvent: (productUuid, modelUuid, updates) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
const event = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (event) {
|
||||
Object.assign(event, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
@@ -255,16 +244,16 @@ export const createProductStore = () => {
|
||||
addPoint: (productUuid, modelUuid, point) => {
|
||||
let updatedEvent: EventsSchema | undefined = undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
if (event && 'points' in event) {
|
||||
const existingPoint = (event as ConveyorEventSchema).points.find(p => p.uuid === point.uuid);
|
||||
const event = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (event && "points" in event) {
|
||||
const existingPoint = (event as ConveyorEventSchema).points.find((p) => p.uuid === point.uuid);
|
||||
if (!existingPoint) {
|
||||
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
} else if (event && 'point' in event) {
|
||||
} else if (event && "point" in event) {
|
||||
const existingPoint = (event as any).point?.uuid === point.uuid;
|
||||
if (!existingPoint) {
|
||||
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
|
||||
@@ -279,13 +268,13 @@ export const createProductStore = () => {
|
||||
removePoint: (productUuid, modelUuid, pointUuid) => {
|
||||
let updatedEvent: EventsSchema | undefined = undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
if (event && 'points' in event) {
|
||||
(event as ConveyorEventSchema).points = (event as ConveyorEventSchema).points.filter(p => p.uuid !== pointUuid);
|
||||
const event = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (event && "points" in event) {
|
||||
(event as ConveyorEventSchema).points = (event as ConveyorEventSchema).points.filter((p) => p.uuid !== pointUuid);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||
} else if (event && "point" in event && (event as any).point.uuid === pointUuid) {
|
||||
// For events with single point, we can't remove it, only reset to empty
|
||||
}
|
||||
}
|
||||
@@ -296,16 +285,16 @@ export const createProductStore = () => {
|
||||
updatePoint: (productUuid, modelUuid, pointUuid, updates) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
if (event && 'points' in event) {
|
||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||
const event = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (event && "points" in event) {
|
||||
const point = (event as ConveyorEventSchema).points.find((p) => p.uuid === pointUuid);
|
||||
if (point) {
|
||||
Object.assign(point, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||
} else if (event && "point" in event && (event as any).point.uuid === pointUuid) {
|
||||
Object.assign((event as any).point, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
@@ -318,22 +307,22 @@ export const createProductStore = () => {
|
||||
addAction: (productUuid, modelUuid, pointUuid, action) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
if (event && 'points' in event) {
|
||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||
const event = product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
if (event && "points" in event) {
|
||||
const point = (event as ConveyorEventSchema).points.find((p) => p.uuid === pointUuid);
|
||||
if (point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
|
||||
point.action = action as any;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||
if ('action' in (event as any).point) {
|
||||
} else if (event && "point" in event && (event as any).point.uuid === pointUuid) {
|
||||
if ("action" in (event as any).point) {
|
||||
if (!(event as any).point.action || (event as any).point.action.actionUuid !== action.actionUuid) {
|
||||
(event as any).point.action = action;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
} else if ('actions' in (event as any).point) {
|
||||
} else if ("actions" in (event as any).point) {
|
||||
const existingAction = (event as any).point.actions.find((a: any) => a.actionUuid === action.actionUuid);
|
||||
if (!existingAction) {
|
||||
(event as any).point.actions.push(action);
|
||||
@@ -349,17 +338,17 @@ export const createProductStore = () => {
|
||||
removeAction: (productUuid, actionUuid) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
// Handle ConveyorEventSchema
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if (event.type === "roboticArm") {
|
||||
if ('actions' in point) {
|
||||
if ("actions" in point) {
|
||||
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
|
||||
if (index !== -1) {
|
||||
point.actions.splice(index, 1);
|
||||
@@ -368,7 +357,7 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
} else if (event.type === "human") {
|
||||
if ('actions' in point) {
|
||||
if ("actions" in point) {
|
||||
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
|
||||
if (index !== -1) {
|
||||
point.actions.splice(index, 1);
|
||||
@@ -377,7 +366,7 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
} else if (event.type === "crane") {
|
||||
if ('actions' in point) {
|
||||
if ("actions" in point) {
|
||||
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
|
||||
if (index !== -1) {
|
||||
point.actions.splice(index, 1);
|
||||
@@ -385,7 +374,7 @@ export const createProductStore = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
} else if ("action" in point && point.action?.actionUuid === actionUuid) {
|
||||
point.action = undefined;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
@@ -400,10 +389,10 @@ export const createProductStore = () => {
|
||||
updateAction: (productUuid, actionUuid, updates) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && point.action.actionUuid === actionUuid) {
|
||||
Object.assign(point.action, updates);
|
||||
@@ -411,13 +400,13 @@ export const createProductStore = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action.actionUuid === actionUuid) {
|
||||
Object.assign(point.action, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) {
|
||||
Object.assign(action, updates);
|
||||
@@ -436,13 +425,13 @@ export const createProductStore = () => {
|
||||
addTrigger: (productUuid, actionUuid, trigger) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && point.action.actionUuid === actionUuid) {
|
||||
const existingTrigger = point.action.triggers.find(t => t.triggerUuid === trigger.triggerUuid);
|
||||
const existingTrigger = point.action.triggers.find((t) => t.triggerUuid === trigger.triggerUuid);
|
||||
if (!existingTrigger) {
|
||||
point.action.triggers.push(trigger);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
@@ -450,16 +439,16 @@ export const createProductStore = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action.actionUuid === actionUuid) {
|
||||
const existingTrigger = point.action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
|
||||
if (!existingTrigger) {
|
||||
point.action.triggers.push(trigger);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
return;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) {
|
||||
const existingTrigger = action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
|
||||
@@ -480,30 +469,30 @@ export const createProductStore = () => {
|
||||
removeTrigger: (productUuid, triggerUuid) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && 'triggers' in point.action) {
|
||||
const Trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
|
||||
if (point.action && "triggers" in point.action) {
|
||||
const Trigger = point.action.triggers.find((t) => t.triggerUuid === triggerUuid);
|
||||
if (Trigger) {
|
||||
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
|
||||
point.action.triggers = point.action.triggers.filter((t) => t.triggerUuid !== triggerUuid);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && 'triggers' in point.action) {
|
||||
if ("action" in point && "triggers" in point.action) {
|
||||
const Trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (Trigger) {
|
||||
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if ('triggers' in action) {
|
||||
if ("triggers" in action) {
|
||||
const Trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (Trigger) {
|
||||
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||
@@ -522,13 +511,13 @@ export const createProductStore = () => {
|
||||
updateTrigger: (productUuid, triggerUuid, updates) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && 'triggers' in point.action) {
|
||||
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
|
||||
if (point.action && "triggers" in point.action) {
|
||||
const trigger = point.action.triggers.find((t) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
Object.assign(trigger, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
@@ -536,18 +525,18 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && 'triggers' in point.action) {
|
||||
if ("action" in point && "triggers" in point.action) {
|
||||
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
Object.assign(trigger, updates);
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if ('triggers' in action) {
|
||||
if ("triggers" in action) {
|
||||
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
Object.assign(trigger, updates);
|
||||
@@ -567,7 +556,7 @@ export const createProductStore = () => {
|
||||
// Renaming functions
|
||||
renameProduct: (productUuid, newName) => {
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
product.productName = newName;
|
||||
}
|
||||
@@ -577,10 +566,10 @@ export const createProductStore = () => {
|
||||
renameAction: (productUuid, actionUuid, newName) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && point.action.actionUuid === actionUuid) {
|
||||
point.action.actionName = newName;
|
||||
@@ -588,13 +577,13 @@ export const createProductStore = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action.actionUuid === actionUuid) {
|
||||
point.action.actionName = newName;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) {
|
||||
action.actionName = newName;
|
||||
@@ -612,13 +601,13 @@ export const createProductStore = () => {
|
||||
renameTrigger: (productUuid, triggerUuid, newName) => {
|
||||
let updatedEvent: EventsSchema | undefined;
|
||||
set((state) => {
|
||||
const product = state.products.find(p => p.productUuid === productUuid);
|
||||
const product = state.products.find((p) => p.productUuid === productUuid);
|
||||
if (product) {
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action && 'triggers' in point.action) {
|
||||
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
|
||||
if (point.action && "triggers" in point.action) {
|
||||
const trigger = point.action.triggers.find((t) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
trigger.triggerName = newName;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
@@ -626,18 +615,18 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && 'triggers' in point.action) {
|
||||
if ("action" in point && "triggers" in point.action) {
|
||||
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
trigger.triggerName = newName;
|
||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||
return;
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if ('triggers' in action) {
|
||||
if ("triggers" in action) {
|
||||
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||
if (trigger) {
|
||||
trigger.triggerName = newName;
|
||||
@@ -656,13 +645,13 @@ export const createProductStore = () => {
|
||||
|
||||
// Helper functions
|
||||
getProductById: (productUuid) => {
|
||||
return get().products.find(p => p.productUuid === productUuid);
|
||||
return get().products.find((p) => p.productUuid === productUuid);
|
||||
},
|
||||
|
||||
getEventByModelUuid: (productUuid, modelUuid) => {
|
||||
const product = get().getProductById(productUuid);
|
||||
if (!product) return undefined;
|
||||
return product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
return product.eventDatas.find((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
},
|
||||
|
||||
getEventByActionUuid: (productUuid, actionUuid) => {
|
||||
@@ -670,17 +659,17 @@ export const createProductStore = () => {
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.actionUuid === actionUuid) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action?.actionUuid === actionUuid) {
|
||||
return event;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) {
|
||||
return event;
|
||||
@@ -696,19 +685,19 @@ export const createProductStore = () => {
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.triggers?.some(t => t.triggerUuid === triggerUuid)) {
|
||||
if (point.action?.triggers?.some((t) => t.triggerUuid === triggerUuid)) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point) {
|
||||
if ("action" in point) {
|
||||
if (point.action?.triggers?.some((t: any) => t.triggerUuid === triggerUuid)) {
|
||||
return event;
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if (action.triggers?.some((t: any) => t.triggerUuid === triggerUuid)) {
|
||||
return event;
|
||||
@@ -725,11 +714,11 @@ export const createProductStore = () => {
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ((event as ConveyorEventSchema).points.some(p => p.uuid === pointUuid)) {
|
||||
if ("points" in event) {
|
||||
if ((event as ConveyorEventSchema).points.some((p) => p.uuid === pointUuid)) {
|
||||
return event;
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
if ((event as any).point?.uuid === pointUuid) {
|
||||
return event;
|
||||
}
|
||||
@@ -742,30 +731,30 @@ export const createProductStore = () => {
|
||||
const event = get().getEventByModelUuid(productUuid, modelUuid);
|
||||
if (!event) return undefined;
|
||||
|
||||
if ('points' in event) {
|
||||
return (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||
} else if ('point' in event && (event as any).point.uuid === pointUuid) {
|
||||
if ("points" in event) {
|
||||
return (event as ConveyorEventSchema).points.find((p) => p.uuid === pointUuid);
|
||||
} else if ("point" in event && (event as any).point.uuid === pointUuid) {
|
||||
return (event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getActionByUuid: (productUuid, actionUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.actionUuid === actionUuid) {
|
||||
return point.action;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action?.actionUuid === actionUuid) {
|
||||
return point.action;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) return action;
|
||||
}
|
||||
@@ -775,17 +764,17 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getActionByPointUuid: (productUuid, pointUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.uuid === pointUuid) {
|
||||
return point.action;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if (point.uuid === pointUuid) {
|
||||
return point.action;
|
||||
@@ -796,17 +785,17 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getModelUuidByPointUuid: (productUuid, pointUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.uuid === pointUuid) {
|
||||
return event.modelUuid;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if (point.uuid === pointUuid) {
|
||||
return event.modelUuid;
|
||||
@@ -817,21 +806,21 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getModelUuidByActionUuid: (productUuid, actionUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.actionUuid === actionUuid) {
|
||||
return event.modelUuid;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action?.actionUuid === actionUuid) {
|
||||
return event.modelUuid;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) return event.modelUuid;
|
||||
}
|
||||
@@ -841,21 +830,21 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getPointUuidByActionUuid: (productUuid, actionUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.actionUuid === actionUuid) {
|
||||
return point.uuid;
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||
if ("action" in point && point.action?.actionUuid === actionUuid) {
|
||||
return point.uuid;
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||
if (action) return point.uuid;
|
||||
}
|
||||
@@ -865,11 +854,11 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getTriggerByUuid: (productUuid, triggerUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return undefined;
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
for (const trigger of point.action?.triggers || []) {
|
||||
if (trigger.triggerUuid === triggerUuid) {
|
||||
@@ -877,15 +866,15 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point) {
|
||||
if ("action" in point) {
|
||||
for (const trigger of point.action?.triggers || []) {
|
||||
if (trigger.triggerUuid === triggerUuid) {
|
||||
return trigger;
|
||||
}
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
for (const trigger of action.triggers || []) {
|
||||
if (trigger.triggerUuid === triggerUuid) {
|
||||
@@ -900,7 +889,7 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getTriggeringModels: (productUuid: string, actionUuid: string) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return [];
|
||||
|
||||
const triggeringModels: EventsSchema[] = [];
|
||||
@@ -909,35 +898,32 @@ export const createProductStore = () => {
|
||||
if (!targetModelUuid) return [];
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.triggers) {
|
||||
for (const trigger of point.action.triggers) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid &&
|
||||
trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid && trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
triggeringModels.push(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
|
||||
if ('action' in point && point.action?.triggers) {
|
||||
if ("action" in point && point.action?.triggers) {
|
||||
for (const trigger of point.action.triggers) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid &&
|
||||
trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid && trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
triggeringModels.push(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if (action.triggers) {
|
||||
for (const trigger of action.triggers) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid &&
|
||||
trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
if (trigger.triggeredAsset?.triggeredModel?.modelUuid === targetModelUuid && trigger.triggeredAsset?.triggeredAction?.actionUuid === actionUuid) {
|
||||
triggeringModels.push(event);
|
||||
break;
|
||||
}
|
||||
@@ -952,13 +938,13 @@ export const createProductStore = () => {
|
||||
},
|
||||
|
||||
getTriggersByTriggeredPointUuid: (productUuid, triggeredPointUuid) => {
|
||||
const product = get().products.find(p => p.productUuid === productUuid);
|
||||
const product = get().products.find((p) => p.productUuid === productUuid);
|
||||
if (!product) return [];
|
||||
|
||||
const triggers: TriggerSchema[] = [];
|
||||
|
||||
for (const event of product.eventDatas) {
|
||||
if ('points' in event) {
|
||||
if ("points" in event) {
|
||||
for (const point of (event as ConveyorEventSchema).points) {
|
||||
if (point.action?.triggers) {
|
||||
for (const trigger of point.action.triggers) {
|
||||
@@ -968,15 +954,15 @@ export const createProductStore = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ('point' in event) {
|
||||
} else if ("point" in event) {
|
||||
const point = (event as any).point;
|
||||
if ('action' in point && point.action?.triggers) {
|
||||
if ("action" in point && point.action?.triggers) {
|
||||
for (const trigger of point.action.triggers) {
|
||||
if (trigger.triggeredAsset?.triggeredPoint?.pointUuid === triggeredPointUuid) {
|
||||
triggers.push(trigger);
|
||||
}
|
||||
}
|
||||
} else if ('actions' in point) {
|
||||
} else if ("actions" in point) {
|
||||
for (const action of point.actions) {
|
||||
if (action.triggers) {
|
||||
for (const trigger of action.triggers) {
|
||||
@@ -996,10 +982,10 @@ export const createProductStore = () => {
|
||||
getIsEventInProduct: (productUuid, modelUuid) => {
|
||||
const product = get().getProductById(productUuid);
|
||||
if (!product) return false;
|
||||
return product.eventDatas.some(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||
}
|
||||
return product.eventDatas.some((e) => "modelUuid" in e && e.modelUuid === modelUuid);
|
||||
},
|
||||
}))
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export type ProductStoreType = ReturnType<typeof createProductStore>;
|
||||
@@ -90,34 +90,6 @@ export const useSelectedAsset = create<SelectedAssetState>()(
|
||||
}))
|
||||
);
|
||||
|
||||
interface SelectedProductState {
|
||||
selectedProduct: { productUuid: string; productName: string };
|
||||
setSelectedProduct: (productUuid: string, productName: string) => void;
|
||||
clearSelectedProduct: () => void;
|
||||
}
|
||||
|
||||
export const createSelectedProductStore = () => {
|
||||
return create<SelectedProductState>()(
|
||||
immer((set) => ({
|
||||
selectedProduct: { productUuid: '', productName: '' },
|
||||
setSelectedProduct: (productUuid, productName) => {
|
||||
set((state) => {
|
||||
state.selectedProduct.productUuid = productUuid;
|
||||
state.selectedProduct.productName = productName;
|
||||
});
|
||||
},
|
||||
clearSelectedProduct: () => {
|
||||
set((state) => {
|
||||
state.selectedProduct.productUuid = '';
|
||||
state.selectedProduct.productName = '';
|
||||
});
|
||||
},
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
export type SelectedProductType = ReturnType<typeof createSelectedProductStore>;
|
||||
|
||||
interface SelectedActionState {
|
||||
selectedAction: { actionId: string | null; actionName: string | null };
|
||||
setSelectedAction: (actionId: string, actionName: string) => void;
|
||||
|
||||
Reference in New Issue
Block a user