diff --git a/src/system/libplc/src/plc.cpp b/src/system/libplc/src/plc.cpp index d153b1a..af5591d 100644 --- a/src/system/libplc/src/plc.cpp +++ b/src/system/libplc/src/plc.cpp @@ -485,6 +485,20 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra if(has_comb) { + // 收集链级 Gate 的 R/S 属性(RS/SR 用) + const char *gateS = NULL, *gateR = NULL; + int isChainSRRS = 0; + if(gate_el) + { + int cgtTmp = gate_type_from_xml_str(gate_el->Attribute("type")); + if(cgtTmp == NODE_TYPE_SR_LATCH || cgtTmp == NODE_TYPE_RS_LATCH) + { + isChainSRRS = cgtTmp; + gateS = gate_el->Attribute("S"); + gateR = gate_el->Attribute("R"); + } + } + // 收集所有 Comb 的 Gate 索引(第一遍已解析) // Comb Gate → 链级 Gate (一个Comb一根线) if(gate_el) @@ -508,6 +522,18 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra l.src_id = cur->nodes[ci].id; l.dest_type = cur->nodes[cgi].type; l.dest_id = cur->nodes[cgi].id; + + // RS/SR: 根据 R/S 属性设置 dst_pin + if(isChainSRRS) + { + int combId = c->IntAttribute("id"); + char combRef[16]; + snprintf(combRef, sizeof(combRef), "Comb#%d", combId); + if(gateR && strcmp(gateR, combRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(gateS && strcmp(gateS, combRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1; + } } } } @@ -535,28 +561,40 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra } // 链级 Inputs → 链级 Gate(如 RS/SR 直接连 Input 信号) - if(gate_el && ins_el) - { - int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); - int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id")); - if(cgi >= 0) - { - for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig; - sig = sig->NextSiblingElement("Signal")) - { - if(cur->link_count >= MAX_LINKS_PER_GRAPH) break; - int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no")); - if(si >= 0) - { LogicLink &l = cur->links[cur->link_count++]; - memset(&l, 0, sizeof(l)); l.dst_pin = -1; - l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id; } - } - } - } + if(gate_el && ins_el) + { + int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); + int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id")); + if(cgi >= 0) + { + for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig; + sig = sig->NextSiblingElement("Signal")) + { + if(cur->link_count >= MAX_LINKS_PER_GRAPH) break; + int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no")); + if(si >= 0) + { LogicLink &l = cur->links[cur->link_count++]; + memset(&l, 0, sizeof(l)); l.dst_pin = -1; + l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; + l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id; - // RS/SR 的 R/S 属性引用的 Input 信号(无 块时也需创建链接) - if(gate_el) + // RS/SR: 根据 R/S 属性设置 dst_pin + if(isChainSRRS) + { + char inRef[16]; + snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no")); + if(gateR && strcmp(gateR, inRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(gateS && strcmp(gateS, inRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1; + } + } + } + } + } + + // RS/SR 的 R/S 属性引用的 Input 信号(仅当无 块时创建链接,避免重复) + if(gate_el && !ins_el) { int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); if(cgt == NODE_TYPE_SR_LATCH || cgt == NODE_TYPE_RS_LATCH) @@ -574,7 +612,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } + l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; + l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 0 : 1; } } if(r_attr2 && strncmp(r_attr2, "Input#", 6) == 0) { @@ -584,7 +623,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } + l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; + l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 1 : 0; } } } } @@ -608,7 +648,21 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id; } + l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id; + + // SR/RS: 根据 R/S 属性设置 dst_pin + if(gt == NODE_TYPE_SR_LATCH || gt == NODE_TYPE_RS_LATCH) + { + const char *sA = gate_el->Attribute("S"); + const char *rA = gate_el->Attribute("R"); + char inRef[16]; + snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no")); + if(rA && strcmp(rA, inRef) == 0) + l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(sA && strcmp(sA, inRef) == 0) + l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 0 : 1; + } + } } if(ous_el)