#pragma once
|
#include <string>
|
#include <vector>
|
#include <algorithm>
|
#include <cstdint>
|
#include <optional>
|
#include <chrono>
|
#include <functional>
|
#include "ProcessJob.h"
|
|
|
// ¡ª¡ª ±ê×¼/ÏîÄ¿ÄÚÔ¼¶¨µÄÊôÐÔÃû£¨A:40£©¡ª¡ª
|
// ˵Ã÷£º²»ÒÔ¿Õ¸ñ¿ªÍ·/½á⣬×Ö·û·¶Î§ 0x20-0x7E£¬ÇÒ²»Äܰüº¬ > : ? * ~
|
inline constexpr const char* CJ_ATTR_CJID = "CJID"; // A:n
|
inline constexpr const char* CJ_ATTR_PRIORITY = "Priority"; // U1
|
inline constexpr const char* CJ_ATTR_PRJOBLIST = "PRJOBLIST"; // L:n of A:n (PJID[])
|
|
namespace SERVO {
|
/// CJ ״̬£¨Ìù½ü E40 ÓïÒ壩
|
enum class CJState : uint8_t {
|
NoState = 0,
|
Queued,
|
Executing,
|
Paused,
|
Completed,
|
Aborted,
|
Failed
|
};
|
|
/// ´´½¨/Ð޸Ľá¹ûÖеĴíÎóÏî
|
struct CJError {
|
uint16_t code; // ×Ô¶¨Òå´íÎóÂ루Àý£º2001=PJ_NOT_FOUND, 2002=NOT_JOINABLE£©
|
std::string text; // ½¨Òé°üº¬¶¨Î»ÐÅÏ¢£¨ATTRID/PJID£©
|
};
|
|
/// CControlJob£ºControl Job ¹ÜÀíÀà
|
class CControlJob {
|
public:
|
CControlJob();
|
explicit CControlJob(std::string cjId);
|
explicit CControlJob(CControlJob& src);
|
|
// ¡ª¡ª »ù±¾ÊôÐÔ ¡ª¡ª //
|
const std::string& id() const noexcept { return m_cjId; }
|
CJState state() const noexcept { return m_state; }
|
uint8_t priority() const noexcept { return m_priority; }
|
void setPriority(uint8_t p) noexcept { m_priority = p; }
|
std::string getStateText();
|
|
// ¡ª¡ª PJ Áбíά»¤£¨È¥ÖØ£©¡ª¡ª //
|
bool addPJ(const std::string& pjId); // ÒÑ´æÔÚÔò²»Öظ´Ìí¼Ó
|
bool addPJs(const std::vector<std::string>& ids); // ·µ»ØÊÇ·ñÓÐÐÂÔö
|
bool removePJ(const std::string& pjId); // ´æÔÚÔòÒÆ³ý
|
bool containsPJ(const std::string& pjId) const;
|
const std::vector<std::string>& pjIds() const noexcept { return m_pjIds; }
|
bool setPJs(const std::vector<CProcessJob*>& pjs);
|
bool removePjPointer(const std::string& id);
|
bool addPjPointer(CProcessJob* pj);
|
void clearPJs() { m_pjIds.clear(); }
|
const std::vector<CProcessJob*>& getPjs() { return m_pjs; };
|
|
// ¡ª¡ª УÑé ¡ª¡ª //
|
struct ValidationIssue { uint32_t code; std::string text; };
|
|
// УÑé CJ ÊÇ·ñ¿É´´½¨/¸üУ¨ÀýÈ磺PJ ÊÇ·ñ´æÔÚ¡¢ÊÇ·ñ¿É¼ÓÈ룩
|
// getPjExistsFn(pjId)->bool£ºPJ ÊÇ·ñ´æÔÚ
|
// canJoinFn(pjId)->bool £ºPJ µ±Ç°ÊÇ·ñÔÊÐí¼ÓÈë CJ£¨Èç PJ ״̬Ϊ Queued µÈ£©
|
bool validateForCreate(
|
const std::function<bool(uint32_t& code, std::string& msg)>& canCreateCjFn,
|
const std::function<bool(const std::string&)>& getPjExistsFn,
|
const std::function<bool(const std::string&)>& canJoinFn
|
);
|
const std::vector<ValidationIssue>& CControlJob::issues();
|
|
// ¡ª¡ª S14F9 ¡ú S14F10 µÄ¡°Ó¦Óýá¹û¡±Ä£ÐÍ ¡ª¡ª //
|
struct CreateRequest {
|
std::optional<uint8_t> priority; // ÈôÓÐÔò¸²¸Ç
|
std::vector<std::string> requestedPjIds;// ÏëÒª°ó¶¨µÄ PJ Áбí
|
};
|
struct CreateResult {
|
std::vector<std::string> acceptedPjIds; // ³É¹¦°ó¶¨µÄ PJ£¨ÓÃÓÚ»ØÏÔ PRJOBLIST£©
|
std::vector<CJError> errors; // ʧ°ÜÏº¬ PJID ˵Ã÷£©
|
uint8_t objack{ 0 }; // 0=È«³É¹¦, 1=²¿·Ö³É¹¦, 2=ȫʧ°Ü
|
};
|
|
// Ó¦Óô´½¨/¸üÐÂÇëÇó£ºÖ»°ó¶¨ÔÊÐíµÄ PJ£¬²¢Éú³É OBJACK/´íÎóÇåµ¥
|
// getPjExistsFn / canJoinFn ͬÉÏ
|
CreateResult applyCreate(
|
const CreateRequest& req,
|
const std::function<bool(const std::string&)>& getPjExistsFn,
|
const std::function<bool(const std::string&)>& canJoinFn
|
);
|
|
// ¡ª¡ª ״̬»ú ¡ª¡ª //
|
bool queue(); // NoState -> Queued
|
bool start(); // Queued -> Executing
|
bool pause(); // Executing -> Paused
|
bool resume(); // Paused -> Executing
|
bool complete(); // Executing/Paused -> Completed
|
bool abort(); // ·ÇÖÕ̬ -> Aborted
|
bool fail(std::string reason); // ÈÎÒâ -> Failed
|
|
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; }
|
|
// ¡ª¡ª »ã×Ü״̬¸¨Öú£¨¿ÉÑ¡£©¡ª¡ª //
|
// ¸ù¾ÝÍⲿÌṩµÄ¡°PJ ÊÇ·ñÒÑÍê³É¡±Åжϣ¬³¢ÊÔ°Ñ CJ ¾ÛºÏÖÃΪ Completed¡£
|
// isPjCompletedFn(pjId)->bool
|
bool tryAggregateComplete(const std::function<bool(const std::string&)>& isPjCompletedFn);
|
|
// ¹¤¾ß£ºÍ³Ò»×Ö·û´®ÏÞÖÆ
|
static void clampString(std::string& s, size_t maxLen);
|
static bool asciiPrintable(const std::string& s);
|
|
static constexpr uint32_t CJ_MAGIC = 0x434A5031; // "CJP1"
|
static constexpr uint16_t CJ_VERSION = 0x0001;
|
|
void serialize(std::ostream& os) const;
|
static bool deserialize(std::istream& is, CControlJob& out, std::string* err = nullptr);
|
|
private:
|
void markQueued();
|
void markStart();
|
void markEnd();
|
|
protected:
|
// ¡ª¡ª ±êʶ & ÅäÖà ¡ª¡ª //
|
std::string m_cjId;
|
uint8_t m_priority{ 5 }; // ȱʡÓÅÏȼ¶£¨×Ô¶¨£©
|
|
// ¡ª¡ª ×é³É ¡ª¡ª //
|
std::vector<std::string> m_pjIds;
|
std::vector<CProcessJob*> m_pjs;
|
|
// ¡ª¡ª ״̬ / Îı¾ ¡ª¡ª //
|
CJState m_state{ CJState::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; // CJID / PJID µÈ
|
|
// ´íÎóÁбí
|
std::vector<ValidationIssue> m_issues;
|
};
|
}
|