Added comdel system generation
// todo display generation
This commit is contained in:
		
							parent
							
								
									74a7ef3e7a
								
							
						
					
					
						commit
						45a668fc46
					
				| @ -38,5 +38,5 @@ add_executable(SchemeEditor | |||||||
|   comdel/parser/comdellexer.cpp |   comdel/parser/comdellexer.cpp | ||||||
|   main.cpp |   main.cpp | ||||||
|   mainwindow.ui |   mainwindow.ui | ||||||
|         comdel/domain/comdelvalidator.cpp comdel/domain/comdelvalidator.h comdel/display/dialogmanager.cpp comdel/display/dialogmanager.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h) |         comdel/domain/comdelvalidator.cpp comdel/domain/comdelvalidator.h comdel/display/dialogmanager.cpp comdel/display/dialogmanager.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h) | ||||||
| target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets) | target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets) | ||||||
|  | |||||||
| @ -5,10 +5,30 @@ | |||||||
| #include <QGraphicsScene> | #include <QGraphicsScene> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| 
 | 
 | ||||||
| #include "dialogmanager.h" |  | ||||||
| 
 |  | ||||||
| namespace display { | namespace display { | ||||||
| 
 | 
 | ||||||
|  | void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { | ||||||
|  |     QMenu menu; | ||||||
|  |     menu.addAction("Izmjeni ime", [this](){}); | ||||||
|  |     menu.addSeparator(); | ||||||
|  |     for(auto attr: this->instance->attributes) { | ||||||
|  |         bool enabled = attr.attribute.getPopup().has_value(); | ||||||
|  | 
 | ||||||
|  |         auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr.name), | ||||||
|  |                                      [&attr, this]() {}); | ||||||
|  |         action->setEnabled(enabled); | ||||||
|  |     } | ||||||
|  |     menu.exec(event->screenPos()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { | ||||||
|  |     QMenu menu; | ||||||
|  |     menu.addAction("Izmjeni ime", [this](){}); | ||||||
|  |     menu.exec(event->screenPos()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
| ComponentWrapper *ComponentWrapper::ofWire(domain::WireInstance *wire) { | ComponentWrapper *ComponentWrapper::ofWire(domain::WireInstance *wire) { | ||||||
|     auto component = new ComponentWrapper(); |     auto component = new ComponentWrapper(); | ||||||
|     component->wireInstance = wire; |     component->wireInstance = wire; | ||||||
| @ -125,5 +145,5 @@ void PinItem::clear() { | |||||||
|         delete item; |         delete item; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | */ | ||||||
| } // namespace display
 | } // namespace display
 | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace display { | namespace display { | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
| class ComponentItem: public QGraphicsItemGroup | class ComponentItem: public QGraphicsItemGroup | ||||||
| { | { | ||||||
| public: | public: | ||||||
| @ -68,6 +69,73 @@ private: | |||||||
|     ComponentItem *componentItem; |     ComponentItem *componentItem; | ||||||
|     std::vector<PinItem*> pinItems; |     std::vector<PinItem*> pinItems; | ||||||
| }; | }; | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | class Pin: public QGraphicsItemGroup | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     domain::Pin pin; | ||||||
|  | public: | ||||||
|  |     Pin(domain::Pin pin): pin(pin) { | ||||||
|  |         pin.getDisplay().render(this); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class Component: public QGraphicsItemGroup | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     std::shared_ptr<domain::ComponentInstance> instance; | ||||||
|  | public: | ||||||
|  |     Component(const std::shared_ptr<domain::ComponentInstance>& instance): instance(instance) { | ||||||
|  |         instance->component.getDisplay().render(this); | ||||||
|  |     } | ||||||
|  |     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class Bus: public QGraphicsItemGroup | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     Bus(const std::shared_ptr<domain::BusInstance>& instance) { | ||||||
|  |         instance->bus.getDisplay()->render(this); | ||||||
|  |     } | ||||||
|  |     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class ComponentGroup: public QGraphicsItemGroup | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     std::shared_ptr<domain::ComponentInstance> componentInstance; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) { | ||||||
|  |         setFlag(ItemIsMovable, true); | ||||||
|  |         setHandlesChildEvents(false); | ||||||
|  | 
 | ||||||
|  |         addToGroup(new display::Component(instance)); | ||||||
|  | 
 | ||||||
|  |         for(auto &pin: instance->component.getPins()) { | ||||||
|  |             addToGroup(new display::Pin(pin)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         setPos(instance->position.first, instance->position.second); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class BusGroup: public QGraphicsItemGroup | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     std::shared_ptr<domain::BusInstance> busInstance; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) { | ||||||
|  |         setFlag(ItemIsMovable, true); | ||||||
|  |         setHandlesChildEvents(false); | ||||||
|  | 
 | ||||||
|  |         addToGroup(new display::Bus(instance)); | ||||||
|  | 
 | ||||||
|  |         setPos(instance->position.first, instance->position.second); | ||||||
|  |     } | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| } // namespace display
 | } // namespace display
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -9,20 +9,18 @@ Schema::Schema() | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void Schema::setSchema(domain::Schema* schema) | void Schema::setSchema(domain::Schema* _schema) | ||||||
| { | { | ||||||
|     scene.clear(); |     scene.clear(); | ||||||
|     this->schema = schema; |     this->schema = _schema; | ||||||
|     if(schema != nullptr) { |     if(schema != nullptr) { | ||||||
|         for(auto &instance: schema->componentInstances) { |         for(auto &instance: schema->componentInstances) { | ||||||
|             ComponentWrapper *component = ComponentWrapper::ofComponent(instance.get()); |             scene.addItem(new display::ComponentGroup(instance)); | ||||||
|             component->setPos(instance->position.first, instance->position.second); |  | ||||||
|             scene.addItem(component); |  | ||||||
|         } |         } | ||||||
|         for(auto &instance: schema->busInstances) { |         for(auto &instance: schema->busInstances) { | ||||||
|             ComponentWrapper *bus = ComponentWrapper::ofBus(instance.get()); |             if(instance->bus.getDisplay().has_value()) { | ||||||
|             bus->setPos(instance->position.first, instance->position.second); |                 scene.addItem(new display::BusGroup(instance)); | ||||||
|             scene.addItem(bus); |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,7 +20,6 @@ private: | |||||||
|     QGraphicsScene scene; |     QGraphicsScene scene; | ||||||
| 
 | 
 | ||||||
|     domain::Schema* schema; |     domain::Schema* schema; | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace display
 | } // namespace display
 | ||||||
|  | |||||||
							
								
								
									
										273
									
								
								comdel/domain/comdel_generator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								comdel/domain/comdel_generator.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,273 @@ | |||||||
|  | //
 | ||||||
|  | // Created by bbr on 08.05.22..
 | ||||||
|  | //
 | ||||||
|  | 
 | ||||||
|  | #include <set> | ||||||
|  | #include "comdel_generator.h" | ||||||
|  | 
 | ||||||
|  | namespace domain { | ||||||
|  | 
 | ||||||
|  | void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream &buffer) { | ||||||
|  |     buffer << "@source " << librarySource << std::endl << std::endl; | ||||||
|  | 
 | ||||||
|  |     buffer << "@schema {" << std::endl; | ||||||
|  | 
 | ||||||
|  |     for(auto &componentInstance: schema->componentInstances) { | ||||||
|  |         buffer << "\t"   << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl; | ||||||
|  |         buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl; | ||||||
|  | 
 | ||||||
|  |         for(auto &attribute: componentInstance->attributes) { | ||||||
|  |             buffer << "\t\t" << "@attribute " << attribute.name << " " << attribute.value.stringify() << std::endl; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         buffer << "\t}" << std::endl << std::endl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for(auto &busInstance: schema->busInstances) { | ||||||
|  |         buffer << "\t"   << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl; | ||||||
|  |         buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl; | ||||||
|  |         buffer << "\t\t" << "@size " << busInstance->size << std::endl; | ||||||
|  |         buffer << "\t}" << std::endl << std::endl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for(auto &conn: schema->connections) { | ||||||
|  |         auto busConn = dynamic_cast<domain::BusConnectionInstance*>(conn.get()); | ||||||
|  |         if(busConn) { | ||||||
|  |             buffer << "\t"  << "@connection (" << busConn->instance->name << "." << busConn->connection.getComponent().pin << ", " << busConn->bus->name << ") {" << std::endl; | ||||||
|  | 
 | ||||||
|  |             for(auto attribute: busConn->attributes) { | ||||||
|  |                 buffer << "\t\t" << "@attribute " << attribute.name << " " << attribute.value.stringify() << std::endl; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             buffer << "\t"  << "}" << std::endl; | ||||||
|  |         } | ||||||
|  |         auto dirConn = dynamic_cast<domain::DirectConnectionInstance*>(conn.get()); | ||||||
|  |         if(dirConn) { | ||||||
|  |             buffer  << "\t"  << "@connection (" << dirConn->instance->name << "." << dirConn->connection.getComponent().pin << ", " | ||||||
|  |                     << dirConn->bus->name << ", " | ||||||
|  |                     << dirConn->secondInstance->name << "." << dirConn->connection.getSecondComponent()->pin | ||||||
|  |                     << ") {" << std::endl; | ||||||
|  | 
 | ||||||
|  |             for(auto attribute: dirConn->attributes) { | ||||||
|  |                 buffer << "\t\t" << "@attribute " << attribute.name << " " << attribute.value.stringify() << std::endl; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             buffer << "\t"  << "}" << std::endl; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     buffer << "}" << std::endl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::set<std::string> createImports(Schema *schema); | ||||||
|  | 
 | ||||||
|  | std::map<string, string> generateWires(Schema *schema, ostream &ostream); | ||||||
|  | 
 | ||||||
|  |     void generateSubComponents(Schema *schema, map <string, string> &wires, ostream &buffer); | ||||||
|  | 
 | ||||||
|  |     void generateComdelFile(Schema *schema, Library &library, std::ostream &buffer) { | ||||||
|  |     buffer << library.getHeader() << std::endl; | ||||||
|  | 
 | ||||||
|  |     std::set<std::string> imports = createImports(schema); | ||||||
|  | 
 | ||||||
|  |     for(auto& import: imports) { | ||||||
|  |        buffer << "#include \"" << library.getComponentDirectory() << "\\" << import << "\"" << std::endl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     buffer << "\n\n" << std::endl; | ||||||
|  | 
 | ||||||
|  |     buffer << "component System" << std::endl << "{" << std::endl; | ||||||
|  | 
 | ||||||
|  |     auto wires = generateWires(schema, buffer); | ||||||
|  | 
 | ||||||
|  |     generateSubComponents(schema, wires, buffer); | ||||||
|  | 
 | ||||||
|  |     buffer << "}"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void generateWire(std::string &name, Wire& wire, ostream &buffer); | ||||||
|  | 
 | ||||||
|  | std::map<string, string> generateWires(Schema *schema, ostream &buffer) { | ||||||
|  |     std::set<string> usedNames; | ||||||
|  |     std::map<string, string> usedMappings; | ||||||
|  |     for(auto &bus: schema->busInstances) { | ||||||
|  |         buffer << "\t//" << bus->name << std::endl; | ||||||
|  |         for(auto& wire: bus->bus.getWires()) { | ||||||
|  |             std::string name = wire.getName(); | ||||||
|  |             if(usedNames.count(wire.getName()) > 0) { | ||||||
|  |                 name = bus->name + "__" + wire.getName(); | ||||||
|  |             } | ||||||
|  |             if(wire.isHidden()) { | ||||||
|  |                 name = "--" + name; | ||||||
|  |             } | ||||||
|  |             usedNames.insert(name); | ||||||
|  |             usedMappings.insert(std::make_pair(bus->name + "." + wire.getName(), name)); | ||||||
|  | 
 | ||||||
|  |             generateWire(name, wire, buffer); | ||||||
|  |         } | ||||||
|  |         buffer << std::endl << std::endl; | ||||||
|  |     } | ||||||
|  |     return usedMappings; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void generateWire(std::string &name, Wire& wire, ostream &buffer) { | ||||||
|  |     buffer << "\t"; | ||||||
|  |     switch (wire.getType()) { | ||||||
|  |         case Wire::R_WIRE: | ||||||
|  |             buffer << "r_wire"; | ||||||
|  |             break; | ||||||
|  |         case Wire::WIRED_AND: | ||||||
|  |             buffer << "wired_and"; | ||||||
|  |             break; | ||||||
|  |         case Wire::WIRED_OR: | ||||||
|  |             buffer << "wired_or"; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             buffer << "wire"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(wire.getWidth() != 1) { | ||||||
|  |         buffer << "<" << wire.getWidth() << ">"; | ||||||
|  |     } | ||||||
|  |     buffer << " " << name << ";" << std::endl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::set<std::string> createImports(Schema *schema) { | ||||||
|  |     std::set<std::string> importSet; | ||||||
|  |     for(auto &component: schema->componentInstances) { | ||||||
|  |         importSet.insert(component->component.getSource()); | ||||||
|  |     } | ||||||
|  |     return importSet; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames, stringstream &buffer); | ||||||
|  | 
 | ||||||
|  |     void | ||||||
|  |     generateSingleAutomaticPin(DirectConnectionInstance *instance, string name, string pin, | ||||||
|  |                                map <string, string> &wireNames, | ||||||
|  |                                stringstream &buffer); | ||||||
|  | 
 | ||||||
|  |     void generateSubComponents(Schema *schema, map<string, string> &wires, ostream &buffer) { | ||||||
|  | 
 | ||||||
|  |     buffer << "\t// components --------------------------------------------" << std::endl; | ||||||
|  | 
 | ||||||
|  |     for(auto& component: schema->componentInstances) { | ||||||
|  |         buffer << "\tsubcomponent " << component->component.getName() << " " << component->name; | ||||||
|  |         if(!component->attributes.empty()) { | ||||||
|  |             buffer << "<"; | ||||||
|  |             buffer << component->attributes[0].value.stringify(); | ||||||
|  |             for(int i=1; i<component->attributes.size(); i++) { | ||||||
|  |                 buffer << ", " << component->attributes[i].value.stringify(); | ||||||
|  |             } | ||||||
|  |             buffer << ">"; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         stringstream tempOutput; | ||||||
|  | 
 | ||||||
|  |         for(auto &pin: component->component.getPins()) { | ||||||
|  |             if(schema->hasConnection(component->name, pin.getName())) { | ||||||
|  |                 auto conn = schema->getConnection(component->name, pin.getName()); | ||||||
|  |                 auto busConn = dynamic_cast<BusConnectionInstance*>(conn); | ||||||
|  |                 if(busConn != nullptr) { | ||||||
|  |                     for(auto wire: busConn->connection.getWires()) { | ||||||
|  |                         if(wire.isType(Value::ATTRIBUTE_REFERENCE)) { | ||||||
|  |                             auto attribute = busConn->getAttribute(wire.asReference()); | ||||||
|  |                             if(wire.isType(Value::WIRE_REFERENCE)) { | ||||||
|  |                                 tempOutput << wires[busConn->bus->name + "." + attribute.value.asReference()] << ", "; | ||||||
|  |                             } else if(wire.isType(Value::NIL)) { | ||||||
|  |                                 tempOutput << "*, "; | ||||||
|  |                             } else { | ||||||
|  |                                 tempOutput << attribute.value.stringify() << ", "; | ||||||
|  |                             } | ||||||
|  |                         } else { | ||||||
|  |                             if(wire.isType(Value::WIRE_REFERENCE)) { | ||||||
|  |                                 tempOutput << wires[busConn->bus->name + "." + wire.asReference()] << ", "; | ||||||
|  |                             } else if(wire.isType(Value::NIL)) { | ||||||
|  |                                 tempOutput << "*, "; | ||||||
|  |                             } else { | ||||||
|  |                                 tempOutput << wire.stringify() << ", "; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 auto dirConn = dynamic_cast<DirectConnectionInstance*>(conn); | ||||||
|  |                 if(dirConn != nullptr) { | ||||||
|  |                     if(dirConn->bus->bus.getType() == Bus::AUTOMATIC) { | ||||||
|  |                         generateAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput); | ||||||
|  |                     } else { | ||||||
|  |                         generateSingleAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 // if no connection exists than defaults must exist
 | ||||||
|  |                 for(auto& wire: *pin.getWires()) { | ||||||
|  |                     tempOutput << wire.stringify() << ", "; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         auto wireList = tempOutput.str(); | ||||||
|  |         wireList.pop_back(); | ||||||
|  |         wireList.pop_back(); // remove last COMMA(", ")
 | ||||||
|  | 
 | ||||||
|  |         buffer << "(" << wireList << ");" << std::endl; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void generateSingleAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map <string, string> &wireNames, stringstream &buffer) { | ||||||
|  |     std::vector<Value> wires; | ||||||
|  |     std::string selected; | ||||||
|  |     std::vector<Value> defaults; | ||||||
|  |     if(connection->instance->name == name && connection->connection.getComponent().pin == pin) { | ||||||
|  |         wires = connection->connection.getWires(); | ||||||
|  |         selected = connection->attributes[0].value.asReference(); | ||||||
|  |         defaults = *connection->instance->component.getPin(pin).getWires(); | ||||||
|  |     } else { | ||||||
|  |         wires = *connection->connection.getSecondWires(); | ||||||
|  |         selected = connection->attributes[1].value.asReference(); | ||||||
|  |         defaults = *connection->secondInstance->component.getPin(pin).getWires(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for(int i=0; i<wires.size(); i++) { | ||||||
|  |         if(wires[i].isType(Value::STRING)) { | ||||||
|  |             if(wires[i].asString() == selected) { | ||||||
|  |                 buffer << wireNames[connection->bus->name + "." + connection->bus->bus.getWires()[0].getName()] << ", "; | ||||||
|  |             } else { | ||||||
|  |                 buffer << defaults[i].stringify(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             buffer << wires[i].stringify() << ", "; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames, stringstream &buffer) { | ||||||
|  |     std::vector<Value> wires; | ||||||
|  |     if(connection->instance->name == name && connection->connection.getComponent().pin == pin) { | ||||||
|  |         wires = connection->connection.getWires(); | ||||||
|  |     } else { | ||||||
|  |         wires = *connection->connection.getSecondWires(); | ||||||
|  |     } | ||||||
|  |     for(auto& wire: wires) { | ||||||
|  |         if(wire.isType(Value::ATTRIBUTE_REFERENCE)) { | ||||||
|  |             auto attribute = connection->getAttribute(wire.asReference()); | ||||||
|  |             if(wire.isType(Value::WIRE_REFERENCE)) { | ||||||
|  |                 buffer << wireNames[connection->bus->name + "." + attribute.value.asReference()] << ", "; | ||||||
|  |             } else if(wire.isType(Value::NIL)) { | ||||||
|  |                 buffer << "*, "; | ||||||
|  |             } else { | ||||||
|  |                 buffer << attribute.value.stringify() << ", "; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             if(wire.isType(Value::WIRE_REFERENCE)) { | ||||||
|  |                 buffer << wireNames[connection->bus->name + "." + wire.asReference()] << ", "; | ||||||
|  |             } else if(wire.isType(Value::NIL)) { | ||||||
|  |                 buffer << "*, "; | ||||||
|  |             } else { | ||||||
|  |                 buffer << wire.stringify() << ", "; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // domain
 | ||||||
							
								
								
									
										16
									
								
								comdel/domain/comdel_generator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								comdel/domain/comdel_generator.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | #ifndef COMDEL_GENERATOR_H | ||||||
|  | #define COMDEL_GENERATOR_H | ||||||
|  | 
 | ||||||
|  | #include <sstream> | ||||||
|  | #include "schema.h" | ||||||
|  | #include "library.h" | ||||||
|  | 
 | ||||||
|  | namespace domain { | ||||||
|  | 
 | ||||||
|  | void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream &buffer); | ||||||
|  | 
 | ||||||
|  | void generateComdelFile(Schema *schema, Library &library, std::ostream &buffer); | ||||||
|  | 
 | ||||||
|  | } // domain
 | ||||||
|  | 
 | ||||||
|  | #endif //COMDEL_GENERATOR_H
 | ||||||
| @ -7,6 +7,16 @@ ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector< | |||||||
|     : instance(instance), attributes(attributes), connection(connection) |     : instance(instance), attributes(attributes), connection(connection) | ||||||
| {} | {} | ||||||
| 
 | 
 | ||||||
|  | InstanceAttribute ConnectionInstance::getAttribute(string attribute) { | ||||||
|  |     for(auto& attr: attributes) { | ||||||
|  |         if(attr.name == attribute) { | ||||||
|  |             return attr; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     throw std::exception(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection) | BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection) | ||||||
|     : ConnectionInstance(instance, attributes, connection), bus(bus) |     : ConnectionInstance(instance, attributes, connection), bus(bus) | ||||||
| {} | {} | ||||||
|  | |||||||
| @ -20,6 +20,8 @@ public: | |||||||
|     std::vector<InstanceAttribute> attributes; |     std::vector<InstanceAttribute> attributes; | ||||||
| 
 | 
 | ||||||
|     ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, Connection connection); |     ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, Connection connection); | ||||||
|  | 
 | ||||||
|  |     InstanceAttribute getAttribute(string attribute); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection conn | |||||||
|     : name(name), type(type), tooltip(tooltip), connection(connection), display(display), wires(wires) |     : name(name), type(type), tooltip(tooltip), connection(connection), display(display), wires(wires) | ||||||
| {} | {} | ||||||
| 
 | 
 | ||||||
| std::string Pin::getName() { | std::string &Pin::getName() { | ||||||
|     return name; |     return name; | ||||||
| } | } | ||||||
| Pin::PinType Pin::getType() { | Pin::PinType Pin::getType() { | ||||||
|  | |||||||
| @ -50,7 +50,7 @@ private: | |||||||
| public: | public: | ||||||
|     Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, Display display, std::optional<std::vector<Value>> wires); |     Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, Display display, std::optional<std::vector<Value>> wires); | ||||||
| 
 | 
 | ||||||
|     std::string getName(); |     std::string &getName(); | ||||||
|     PinType getType(); |     PinType getType(); | ||||||
|     std::string getTooltip(); |     std::string getTooltip(); | ||||||
|     Display &getDisplay(); |     Display &getDisplay(); | ||||||
|  | |||||||
| @ -6,4 +6,23 @@ Schema::Schema() | |||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool Schema::hasConnection(string& component, string& pin) { | ||||||
|  |     return getConnection(component, pin) != nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ConnectionInstance* Schema::getConnection(string& component, string& pin) { | ||||||
|  |     for(auto& conn: connections) { | ||||||
|  |         if(conn->instance->name == component && conn->connection.getComponent().pin == pin) { | ||||||
|  |             return conn.get(); | ||||||
|  |         } | ||||||
|  |         auto dirConn = dynamic_cast<DirectConnectionInstance*>(conn.get()); | ||||||
|  |         if(dirConn != nullptr) { | ||||||
|  |             if(dirConn->secondInstance->name == component && conn->connection.getSecondComponent()->pin == pin) { | ||||||
|  |                 return dirConn; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -35,6 +35,9 @@ public: | |||||||
|         } |         } | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     bool hasConnection(string& component, string& pin); | ||||||
|  |     ConnectionInstance* getConnection(string& component, string& pin); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -217,7 +217,7 @@ struct WireNode: public AstNode | |||||||
|     IdentifierNode name; |     IdentifierNode name; | ||||||
|     NumberNode size; |     NumberNode size; | ||||||
| 
 | 
 | ||||||
|     bool hidden; |     bool hidden = false; | ||||||
| 
 | 
 | ||||||
|     bool hasTerminateWith; |     bool hasTerminateWith; | ||||||
|     ValueNode terminateWith; |     ValueNode terminateWith; | ||||||
|  | |||||||
| @ -273,9 +273,9 @@ | |||||||
|         INT2 wired_and, |         INT2 wired_and, | ||||||
|         INT3 wired_and, |         INT3 wired_and, | ||||||
|         SIZE<3>, |         SIZE<3>, | ||||||
|         IACK, |         IACK hidden, | ||||||
|         BREQ, |         BREQ hidden, | ||||||
|         BACK |         BACK hidden | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @bus PIOSabirnica automatic { | @bus PIOSabirnica automatic { | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ | |||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <comdel/domain/comdelvalidator.h> | #include <comdel/domain/comdelvalidator.h> | ||||||
| #include <fstream> | #include <fstream> | ||||||
|  | #include <comdel/domain/comdel_generator.h> | ||||||
| 
 | 
 | ||||||
| MainWindow::MainWindow(QWidget *parent) | MainWindow::MainWindow(QWidget *parent) | ||||||
|     : QMainWindow(parent) |     : QMainWindow(parent) | ||||||
| @ -37,6 +38,7 @@ void MainWindow::setupUi() | |||||||
|     ui->toolBar->addAction("Load library", this, &MainWindow::onLoadLibrary); |     ui->toolBar->addAction("Load library", this, &MainWindow::onLoadLibrary); | ||||||
|     ui->toolBar->addAction("Load schema", this, &MainWindow::onLoadSchema); |     ui->toolBar->addAction("Load schema", this, &MainWindow::onLoadSchema); | ||||||
|     ui->toolBar->addAction("Save schema", this, &MainWindow::onStoreScheme); |     ui->toolBar->addAction("Save schema", this, &MainWindow::onStoreScheme); | ||||||
|  |     ui->toolBar->addAction("Generate system", this, &MainWindow::onGenerateComdel); | ||||||
| 
 | 
 | ||||||
|     connect(ui->actionValidate, &QAction::triggered, this, &MainWindow::onValidateSchema); |     connect(ui->actionValidate, &QAction::triggered, this, &MainWindow::onValidateSchema); | ||||||
| 
 | 
 | ||||||
| @ -156,45 +158,31 @@ void MainWindow::onStoreScheme() { | |||||||
| 
 | 
 | ||||||
|     std::ostringstream buffer; |     std::ostringstream buffer; | ||||||
| 
 | 
 | ||||||
|     buffer << "@source " << this->librarySource << std::endl << std::endl; |     domain::generateSchemaFile(librarySource, schema, buffer); | ||||||
| 
 |  | ||||||
|     buffer << "@schema {" << std::endl; |  | ||||||
| 
 |  | ||||||
|     for(auto &componentInstance: schema->componentInstances) { |  | ||||||
|         buffer << "\t"   << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl; |  | ||||||
|         buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl; |  | ||||||
| 
 |  | ||||||
|         for(auto &attribute: componentInstance->attributes) { |  | ||||||
|             buffer << "\t\t" << "@attribute " << attribute.name << " " << attribute.value.stringify() << std::endl; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         buffer << "\t}" << std::endl << std::endl; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for(auto &busInstance: schema->busInstances) { |  | ||||||
|         buffer << "\t"   << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl; |  | ||||||
|         buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl; |  | ||||||
|         buffer << "\t\t" << "@size " << busInstance->size << std::endl; |  | ||||||
|         buffer << "\t}" << std::endl << std::endl; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for(auto &conn: schema->connections) { |  | ||||||
|         auto busConn = dynamic_cast<domain::BusConnectionInstance*>(conn.get()); |  | ||||||
|         if(busConn) { |  | ||||||
|             buffer << "\t"  << "@connection (" << busConn->instance->name << "." << busConn->connection.getComponent().pin << ", " << busConn->bus->name << ") {" << std::endl; |  | ||||||
|             buffer << "\t"  << "}" << std::endl; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     buffer << "}" << std::endl; |  | ||||||
| 
 |  | ||||||
|     auto value = buffer.str(); |  | ||||||
| 
 | 
 | ||||||
|     std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary); |     std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary); | ||||||
|     out<<buffer.str(); |     out<<buffer.str(); | ||||||
|     out.close(); |     out.close(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void MainWindow::onGenerateComdel() { | ||||||
|  |     if(schema == nullptr) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto filename = QFileDialog::getSaveFileName(this, | ||||||
|  |                                                  tr("Save schema"), "/home", tr("Comdel system (*.system)")); | ||||||
|  | 
 | ||||||
|  |     std::ostringstream buffer; | ||||||
|  | 
 | ||||||
|  |     domain::generateComdelFile(schema, library.value(), buffer); | ||||||
|  | 
 | ||||||
|  |     std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary); | ||||||
|  |     out<<buffer.str(); | ||||||
|  |     out.close(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void MainWindow::onValidateSchema(bool /*toggled*/) { | void MainWindow::onValidateSchema(bool /*toggled*/) { | ||||||
|     if(schema == nullptr) { |     if(schema == nullptr) { | ||||||
|         return; |         return; | ||||||
|  | |||||||
| @ -40,11 +40,13 @@ private slots: | |||||||
|     void onLoadSchema(); |     void onLoadSchema(); | ||||||
|     void onValidateSchema(bool toggled); |     void onValidateSchema(bool toggled); | ||||||
|     void onStoreScheme(); |     void onStoreScheme(); | ||||||
|  |     void onGenerateComdel(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::string librarySource; |     std::string librarySource; | ||||||
|     Ui::MainWindow *ui; |     Ui::MainWindow *ui; | ||||||
|     QPlainTextEdit *log; |     QPlainTextEdit *log; | ||||||
|     std::vector<domain::ValidationError> validationErrors; |     std::vector<domain::ValidationError> validationErrors; | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| #endif // MAIN_WINDOW_H
 | #endif // MAIN_WINDOW_H
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user