| 977 | |
| 978 | |
| 979 | void Engine::addCable_NoLock(Cable* cable) { |
| 980 | assert(cable); |
| 981 | // Check cable properties |
| 982 | assert(cable->inputModule); |
| 983 | assert(cable->outputModule); |
| 984 | Input& input = cable->inputModule->inputs[cable->inputId]; |
| 985 | Output& output = cable->outputModule->outputs[cable->outputId]; |
| 986 | bool inputWasConnected = false; |
| 987 | bool outputWasConnected = false; |
| 988 | for (Cable* cable2 : internal->cables) { |
| 989 | // Check that the cable is not already added |
| 990 | assert(cable2 != cable); |
| 991 | // Check that cable isn't similar to another cable |
| 992 | // assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId && cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)); |
| 993 | // Check if input is already connected to a cable |
| 994 | if (cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId) |
| 995 | inputWasConnected = true; |
| 996 | // Check if output is already connected to a cable |
| 997 | if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId) |
| 998 | outputWasConnected = true; |
| 999 | } |
| 1000 | // Set ID if unset or collides with an existing ID |
| 1001 | while (cable->id < 0 || internal->cablesCache.find(cable->id) != internal->cablesCache.end()) { |
| 1002 | // Generate random 52-bit ID |
| 1003 | cable->id = random::u64() % (1ull << 53); |
| 1004 | } |
| 1005 | // Add the cable |
| 1006 | internal->cables.push_back(cable); |
| 1007 | // Sort cable by input so they are grouped in stepFrame() |
| 1008 | std::sort(internal->cables.begin(), internal->cables.end(), [](Cable* a, Cable* b) { |
| 1009 | return std::make_tuple(a->inputModule, a->inputId) < std::make_tuple(b->inputModule, b->inputId); |
| 1010 | }); |
| 1011 | // Set default number of input/output channels |
| 1012 | if (!inputWasConnected) { |
| 1013 | input.channels = 1; |
| 1014 | } |
| 1015 | if (!outputWasConnected) { |
| 1016 | output.channels = 1; |
| 1017 | } |
| 1018 | // Add caches |
| 1019 | internal->cablesCache[cable->id] = cable; |
| 1020 | // Dispatch input port event |
| 1021 | if (!inputWasConnected) { |
| 1022 | Module::PortChangeEvent e; |
| 1023 | e.connecting = true; |
| 1024 | e.type = Port::INPUT; |
| 1025 | e.portId = cable->inputId; |
| 1026 | cable->inputModule->onPortChange(e); |
| 1027 | } |
| 1028 | // Dispatch output port event if its state went from disconnected to connected. |
| 1029 | if (!outputWasConnected) { |
| 1030 | Module::PortChangeEvent e; |
| 1031 | e.connecting = true; |
| 1032 | e.type = Port::OUTPUT; |
| 1033 | e.portId = cable->outputId; |
| 1034 | cable->outputModule->onPortChange(e); |
| 1035 | } |
| 1036 | } |
nothing calls this directly
no test coverage detected