| | |
| | | #include "stdafx.h" |
| | | #include "CControlJob.h" |
| | | #include <cctype> |
| | | #include "SerializeUtil.h" |
| | | |
| | | static inline std::string trimCopy(std::string s) { |
| | | auto notspace = [](int ch) { return !std::isspace(ch); }; |
| | | s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace)); |
| | | s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end()); |
| | | s.erase(s.begin(), |
| | | std::find_if(s.begin(), s.end(), |
| | | [](char c) { return !std::isspace(static_cast<unsigned char>(c)); })); |
| | | s.erase(std::find_if(s.rbegin(), s.rend(), |
| | | [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }).base(), |
| | | s.end()); |
| | | return s; |
| | | } |
| | | |
| | | namespace SERVO { |
| | | CControlJob::CControlJob() |
| | | { |
| | | |
| | | } |
| | | |
| | | CControlJob::CControlJob(std::string cjId) |
| | | : m_cjId(trimCopy(std::move(cjId))) |
| | | { |
| | |
| | | return true; |
| | | } |
| | | |
| | | bool CControlJob::addPjPointer(CProcessJob* pj) |
| | | { |
| | | for (auto item : m_pjs) { |
| | | if (item->id().compare(pj->id()) == 0) return false; |
| | | } |
| | | |
| | | m_pjs.push_back(pj); |
| | | return true; |
| | | } |
| | | |
| | | bool CControlJob::removePjPointer(const std::string& id) |
| | | { |
| | | for(auto iter = m_pjs.begin(); iter != m_pjs.end(); ++iter) { |
| | | if ((*iter)->id().compare(id) == 0) { |
| | | m_pjs.erase(iter); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | bool CControlJob::removePJ(const std::string& pjId) { |
| | | auto it = std::find(m_pjIds.begin(), m_pjIds.end(), pjId); |
| | | if (it == m_pjIds.end()) return false; |
| | |
| | | const std::vector<CControlJob::ValidationIssue>& CControlJob::issues() |
| | | { |
| | | return m_issues; |
| | | } |
| | | |
| | | void CControlJob::clearIssues() |
| | | { |
| | | m_issues.clear(); |
| | | } |
| | | |
| | | bool CControlJob::validateForCreate( |
| | |
| | | return true; |
| | | } |
| | | |
| | | bool CControlJob::abort() { |
| | | bool CControlJob::abort(std::string reason) { |
| | | if (m_state == CJState::Completed || m_state == CJState::Aborted || m_state == CJState::Failed) |
| | | return false; |
| | | m_failReason = trimCopy(reason); |
| | | clampString(m_failReason, 128); |
| | | m_state = CJState::Aborted; |
| | | markEnd(); |
| | | return true; |
| | |
| | | return c >= 0x20 && c <= 0x7E; |
| | | }); |
| | | } |
| | | |
| | | void CControlJob::serialize(std::ostream& os) const { |
| | | write_pod(os, CJ_MAGIC); |
| | | write_pod(os, CJ_VERSION); |
| | | |
| | | // 标识/优先级/状态/失败原因 |
| | | write_string(os, id()); // 或 m_cjId |
| | | write_pod<uint8_t>(os, priority()); // 或 m_priority |
| | | write_pod<uint8_t>(os, static_cast<uint8_t>(state())); // 或 m_state |
| | | write_string(os, failReason()); // 或 m_failReason |
| | | |
| | | // 时间戳 |
| | | write_opt_time(os, tQueued()); |
| | | write_opt_time(os, tStart()); |
| | | write_opt_time(os, tEnd()); |
| | | |
| | | // 关联 PJ 列表 |
| | | write_vec_str(os, pjIds()); // 或 m_pjIds |
| | | } |
| | | |
| | | bool CControlJob::deserialize(std::istream& is, CControlJob& out, std::string* err) { |
| | | auto fail = [&](const char* msg) { if (err) *err = msg; return false; }; |
| | | |
| | | uint32_t magic = 0; if (!read_pod(is, magic)) return fail("read CJ magic"); |
| | | if (magic != CJ_MAGIC) return fail("bad CJ magic"); |
| | | |
| | | uint16_t ver = 0; if (!read_pod(is, ver)) return fail("read CJ version"); |
| | | if (ver != CJ_VERSION) return fail("unsupported CJ version"); |
| | | |
| | | std::string cjId; |
| | | if (!read_string(is, cjId)) return fail("read CJID"); |
| | | |
| | | uint8_t prio = 0; |
| | | if (!read_pod(is, prio)) return fail("read Priority"); |
| | | |
| | | uint8_t st = 0; |
| | | if (!read_pod(is, st)) return fail("read State"); |
| | | |
| | | std::string failText; |
| | | if (!read_string(is, failText)) return fail("read failReason"); |
| | | |
| | | std::optional<std::chrono::system_clock::time_point> tQ, tS, tE; |
| | | if (!read_opt_time(is, tQ)) return fail("read tQueued"); |
| | | if (!read_opt_time(is, tS)) return fail("read tStart"); |
| | | if (!read_opt_time(is, tE)) return fail("read tEnd"); |
| | | |
| | | std::vector<std::string> pjIds; |
| | | if (!read_vec_str(is, pjIds)) return fail("read PJIDs"); |
| | | |
| | | // —— 写回对象(直接改成员,或通过 setter)—— |
| | | // 若你有 setter:out.setId(...)/setPriority(...)/setState(...)/setFailReason(...) |
| | | out = CControlJob(cjId); |
| | | out.setPriority(prio); |
| | | |
| | | out.m_state = static_cast<CJState>(st); |
| | | out.m_failReason = std::move(failText); |
| | | out.m_tQueued = std::move(tQ); |
| | | out.m_tStart = std::move(tS); |
| | | out.m_tEnd = std::move(tE); |
| | | out.m_pjIds = std::move(pjIds); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | std::string CControlJob::getStateText() |
| | | { |
| | | switch (m_state) |
| | | { |
| | | case SERVO::CJState::NoState: |
| | | return "NoState"; |
| | | break; |
| | | case SERVO::CJState::Queued: |
| | | return "Queued"; |
| | | break; |
| | | case SERVO::CJState::Executing: |
| | | return "Executing"; |
| | | break; |
| | | case SERVO::CJState::Paused: |
| | | return "Paused"; |
| | | break; |
| | | case SERVO::CJState::Completed: |
| | | return "Completed"; |
| | | break; |
| | | case SERVO::CJState::Aborted: |
| | | return "Aborted"; |
| | | break; |
| | | case SERVO::CJState::Failed: |
| | | return "Failed"; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ""; |
| | | } |
| | | } |