LAPTOP-SNT8I5JK\Boounion
2025-09-13 b17d444a0da9cabf775f90be04d14fac113bb9fb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <cstdint>
#include <chrono>
#include <optional>
 
namespace SERVO {
    /// PJ ÉúÃüÖÜÆÚ£¨Ìù½ü E40 ³£¼û״̬£©
    enum class PJState : uint8_t {
        NoState = 0,
        Queued,
        SettingUp,
        InProcess,
        Paused,
        Aborting,
        Completed,
        Aborted,
        Failed
    };
 
    /// Åä·½Ö¸¶¨·½Ê½£¨¶ÔÓ¦ S16F15 Àï PRRECIPEMETHOD£©
    enum class RecipeMethod : uint8_t {
        NoTuning = 1,   // 1 - recipe without variable tuning
        WithTuning = 2  // 2 - recipe with variable tuning
    };
 
    /// Æô¶¯²ßÂÔ£¨¶ÔÓ¦ S16F15 Àï PRPROCESSSTART£©
    enum class StartPolicy : uint8_t {
        Queued = 0,   // ½¨Á¢ºóÅŶÓ
        AutoStart = 1 // Ìõ¼þÂú×ãÔò×Ô¶¯Æô¶¯
    };
 
    /** Åä·½²ÎÊý¶Ô£¨S16F15 ÖРRCPPARNM / RCPPARVAL£© */
    struct PJParam {
        std::string name;   // RCPPARNM
        std::string value;  // RCPPARVAL
    };
 
    /**
    {L:2
        CARRIERID
        {L:j
            SLOTID
        }
    }
     */
    struct CarrierSlotInfo {
        std::string carrierId;          // CARRIERID
        std::vector<uint8_t> slots;     // SLOTID[]
        std::vector<void*> contexts;    // Glass
    };
 
    /// ¼òµ¥×ÊÔ´ÊÓͼ½Ó¿Ú£º¹© Validate() ²éѯ£¨ÓÉÉ豸¶ËʵÏÖÕßÔÚÍⲿÌṩ£©
    struct IResourceView {
        virtual ~IResourceView() = default;
        virtual bool isProcessJobsEmpty() const = 0;
        virtual bool recipeExists(const std::string& ppid) const = 0;
        virtual bool carrierPresent(const std::string& carrierId) const = 0;
        virtual bool slotUsable(const std::string& carrierId, uint16_t slot) const = 0;
        virtual bool ceidDefined(uint32_t ceid) const = 0;
        // ÄãÒ²¿ÉÒÔÀ©Õ¹£ºport״̬¡¢Õ¼ÓÃÇé¿ö¡¢CJ/PJ¿Õ¼äµÈ
    };
 
    /// PJ Ö÷Àà
    /**
     * ProcessJob ¡ª¡ª Óë S16F15£¨PRJobMultiCreate£©×Ö¶ÎÒ»Ò»¶ÔÓ¦µÄ³ÐÔØÀà
     *
     * S16F15 ½á¹¹£¨ºËÐĽÚÑ¡£©£º
     * {L:6
     *   PRJOBID                -> m_pjId
     *   MF                     -> m_mf
     *   {L:n { CARRIERID {L:j SLOTID} } } 
     *   {L:3
     *     PRRECIPEMETHOD       -> m_recipeType
     *     RCPSPEC£¨PPID£©      -> m_recipeSpec
     *     {L:m { RCPPARNM RCPPARVAL }}     -> m_params
     *   }
     *   PRPROCESSSTART         -> m_startPolicy
     *   {L:k PRPAUSEEVENTID}   -> m_pauseEvents
     * }
     */
    class CProcessJob {
    public:
        // ¡ª¡ª ¹¹Ôì / »ù±¾ÉèÖࡪ¡ª
        CProcessJob();
        explicit CProcessJob(std::string pjId);
 
        const std::string& id() const noexcept { return m_pjId; }
        const std::string& parentCjId() const noexcept { return m_parentCjId; }
        PJState state() const noexcept { return m_state; }
        StartPolicy startPolicy() const noexcept { return m_startPolicy; }
        RecipeMethod recipeMethod() const noexcept { return m_recipeMethod; }
        const std::string& recipeSpec() const noexcept { return m_recipeSpec; } // PPID »ò Spec
        std::string getStateText();
 
        // °ó¶¨¸¸ CJ
        void setParentCjId(std::string cjId);
 
        // Åä·½
        void setRecipe(RecipeMethod method, std::string spec);
 
        // Æô¶¯²ßÂÔ
        void setStartPolicy(StartPolicy sp) { m_startPolicy = sp; }
 
        // ²ÎÊý
        void addParam(std::string name, std::string value);
        void setParams(std::vector<PJParam> params);
 
        // ÔÝͣʼþ
        void addPauseEvent(uint32_t ceid);
        void setPauseEvents(std::vector<uint32_t> ceids);
 
        // ¡ª¡ª Ð£Ñé ¡ª¡ª
        struct ValidationIssue {
            uint32_t code;      // ×Ô¶¨Òå´íÎóÂë
            std::string text;   // Îı¾ÃèÊö
        };
        // ·µ»ØÎÊÌâÇåµ¥£¨¿Õ=ͨ¹ý£©
        bool validate(const IResourceView& rv);
        const std::vector<ValidationIssue>& issues() const;
 
        // ¡ª¡ª ×´Ì¬»ú£¨´øÊØÎÀ£©¡ª¡ª
        bool queue();           // NoState -> Queued
        bool start();           // Queued/SettingUp -> InProcess
        bool enterSettingUp();  // Queued -> SettingUp
        bool pause();           // InProcess -> Paused
        bool resume();          // Paused -> InProcess
        bool complete();        // InProcess -> Completed
        bool abort();           // Any (δÖÕ̬) -> Aborted
        bool fail(std::string reason); // ÈÎÒâ̬ -> Failed£¨¼Ç¼ʧ°ÜÔ­Òò£©
 
        // ¡ª¡ª ·ÃÎÊÆ÷£¨ÓÃÓÚÉϱ¨/²éѯ£©¡ª¡ª
        const std::vector<PJParam>& params() const noexcept { return m_params; }
        const std::vector<uint32_t>& pauseEvents() const noexcept { return m_pauseEvents; }
        const std::string& failReason() const noexcept { return m_failReason; }
 
        // Ê±¼ä´Á£¨¿ÉÓÃÓÚ±¨±í/×·ËÝ£©
        std::optional<std::chrono::system_clock::time_point> tQueued() const { return m_tQueued; }
        std::optional<std::chrono::system_clock::time_point> tStart()  const { return m_tStart; }
        std::optional<std::chrono::system_clock::time_point> tEnd()    const { return m_tEnd; }
 
        // ³¤¶ÈÏÞÖÆ¹¤¾ß£¨¿ÉÔÚ¼¯³Éʱͳһ²ßÂÔ£©
        static void clampString(std::string& s, size_t maxLen);
        static bool asciiPrintable(const std::string& s);
 
        // Çå¿Õ²¢ÕûÌåÉèÖÃ
        void setCarriers(std::vector<CarrierSlotInfo> carriers);
 
        // ×·¼ÓÒ»¸öÔØ¾ß
        void addCarrier(std::string carrierId, std::vector<uint8_t> slots);
 
        // ·ÃÎÊÆ÷
        const std::vector<CarrierSlotInfo>& carriers() const noexcept { return m_carriers; }
        CarrierSlotInfo* getCarrier(const std::string& strId);
 
        // Åж¨ÊÇ·ñ¡°°´Ôؾß/¿¨Î»¡±·½Ê½
        bool usesCarrierSlots() const noexcept { return !m_carriers.empty(); }
 
 
    public:
        // ====== °æ±¾Í·³£Á¿£¨½¨Òé±£Áô£¬±ãÓÚ¼æÈÝ£©======
        static constexpr uint32_t PJ_FILE_MAGIC = 0x504A4A31; // "PJJ1"
        static constexpr uint16_t PJ_FILE_VERSION = 0x0001;
 
        // ====== Á÷ʽÐòÁл¯½Ó¿Ú ======
        void serialize(std::ostream& os) const;
        static bool deserialize(std::istream& is, CProcessJob& out, std::string* err = nullptr);
 
    private:
        // ÄÚ²¿×´Ì¬×ªÒưïÖú
        void markQueued();
        void markStart();
        void markEnd();
 
    private:
        // ±êʶ
        std::string m_pjId;
        std::string m_parentCjId;
 
        // Åä·½
        RecipeMethod m_recipeMethod{ RecipeMethod::NoTuning };
        std::string  m_recipeSpec; // PPID / Spec
 
        // ÎïÁÏ
        static constexpr uint8_t MATERIAL_FORMAT = 14; // substrate
        std::vector<CarrierSlotInfo> m_carriers;   // {L:n { CARRIERID {L:j SLOTID} }}
 
        // ²ÎÊý / ÔÝͣʼþ
        std::vector<PJParam>    m_params;
        std::vector<uint32_t>   m_pauseEvents;
 
        // ×´Ì¬ & ¼Ç¼
        StartPolicy m_startPolicy{ StartPolicy::Queued }; // 0=Queued, 1=AutoStart
        PJState m_state{ PJState::NoState };
        std::string m_failReason;
 
        // Ê±¼ä´Á
        std::optional<std::chrono::system_clock::time_point> m_tQueued;
        std::optional<std::chrono::system_clock::time_point> m_tStart;
        std::optional<std::chrono::system_clock::time_point> m_tEnd;
 
        // Ô¼Êø£¨¿É°´ÄãÃÇЭÒéµ÷Õû£©
        static constexpr size_t MAX_ID_LEN = 64;   // PJID/ CJID/ CarrierID/ MID/ PPID
        static constexpr size_t MAX_PARAM_K = 32;   // ²ÎÊýÃû
        static constexpr size_t MAX_PARAM_V = 64;   // ²ÎÊýÖµ
 
        // ´íÎóÁбí
        std::vector<ValidationIssue> m_issues;
    };
}