35Q_DECLARE_METATYPE(vector<string>)
36Q_DECLARE_METATYPE(vector<VuoCompilerNodeClass *>)
37Q_DECLARE_METATYPE(vector<VuoCompilerType *>)
40set<VuoModuleManager *> VuoModuleManager::allModuleManagers;
49 this->compiler = compiler;
52 composition =
nullptr;
54 nodeLibrary =
nullptr;
56 allModuleManagers.insert(
this);
58 qRegisterMetaType< vector<string> >();
59 qRegisterMetaType< vector<VuoCompilerNodeClass *> >();
60 qRegisterMetaType< vector<VuoCompilerType *> >();
61 qRegisterMetaType< ModulesModifiedSet >();
70 composition =
nullptr;
72 nodeLibrary =
nullptr;
74 for (
auto callbackIter : callbackForNodeClass)
75 Block_release(callbackIter.second.first);
76 callbackForNodeClass.clear();
78 allModuleManagers.erase(
this);
90 this->composition = composition;
98 this->codeWindow = codeWindow;
106 this->nodeLibrary = nodeLibrary;
135 map<string, VuoCompilerType *> types;
137 auto shouldCopy = [limitToSpecializationTargets] (pair<string, VuoCompilerType *> i)
142 std::copy_if(loadedSingletonTypes.begin(), loadedSingletonTypes.end(),
143 std::inserter(types, types.end()),
154 return loadedGenericCompoundTypes;
163 set<string> listTypes;
166 for (
auto i : singletonTypes)
178 return knownNodeSets;
189 if (typeName ==
"VuoLayer")
192 auto typeIter = loadedSingletonTypes.find(typeName);
193 if (typeIter != loadedSingletonTypes.end())
195 VuoNodeSet *nodeSet = typeIter->second->getBase()->getNodeSet();
200 return getPrimaryAffiliatedNodeSetForType(typeName);
217 vector<string> typeConverters;
224 return otherTypeAsGeneric ?
235 auto typeConverterCanSpecializeToQueriedTypes = [=](pair<VuoType *, VuoType *> converterInOut,
string &outSpecialization)
237 VuoType *converterInType = converterInOut.first;
239 if (converterGenericInType)
241 if (! genericTypeCanSpecializeTo(converterGenericInType, fromTypeName, genericInType))
246 else if (converterInType->
getModuleKey() != fromTypeName)
249 VuoType *converterOutType = converterInOut.second;
251 if (converterGenericOutType)
253 if (! genericTypeCanSpecializeTo(converterGenericOutType, toTypeName, genericOutType))
258 else if (converterOutType->
getModuleKey() != toTypeName)
261 if (converterGenericInType && converterGenericOutType &&
269 for (
auto const &i : loadedTypeConverterNodeClasses)
271 string specialization;
272 if (typeConverterCanSpecializeToQueriedTypes(i.first, specialization))
274 if (specialization.empty())
275 typeConverters.insert(typeConverters.end(), i.second.cbegin(), i.second.cend());
277 for (
string unspecializedTypeConverter : i.second)
282 return typeConverters;
294 callbackForNodeClass[nodeClassName] = make_pair(callbackOnHeap,
false);
306 callbackForNodeClass[nodeClassName] = make_pair(callbackOnHeap,
true);
314 auto callbackIter = callbackForNodeClass.find(nodeClassName);
315 if (callbackIter != callbackForNodeClass.end())
317 Block_release(callbackIter->second.first);
318 callbackForNodeClass.erase(callbackIter);
333 set<string> compositionIdentifiers;
338 list< pair<string, VuoCompilerNodeClass *> > nodesToVisit;
342 if (node->hasCompiler())
345 node->getCompiler()->getIdentifier());
346 nodesToVisit.push_back(make_pair(fullyQualifiedNodeIdentifier, node->getNodeClass()->getCompiler()));
350 while (! nodesToVisit.empty())
352 pair<string, VuoCompilerNodeClass *> v = nodesToVisit.front();
353 string currNodeIdentifier = v.first;
355 nodesToVisit.pop_front();
357 if (currNodeClass == nodeClass)
358 compositionIdentifiers.insert(currNodeIdentifier);
364 if (containedNodeClass)
367 nodesToVisit.push_back(make_pair(fullyQualifiedNodeIdentifier, containedNodeClass));
374 return compositionIdentifiers;
381 const map<
string, pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
382 const map<string, VuoCompilerModule *> &modulesRemoved,
VuoCompilerIssues *issues)
391 vector<VuoCompilerModule *> modulesAddedOrModified;
392 for (
auto m : modulesAdded)
393 modulesAddedOrModified.push_back(m.second);
394 for (
auto m : modulesModified)
395 modulesAddedOrModified.push_back(m.second.second);
397 vector<VuoCompilerModule *> modulesRemovedOrModified;
398 for (
auto m : modulesRemoved)
399 modulesRemovedOrModified.push_back(m.second);
400 for (
auto m : modulesModified)
401 modulesRemovedOrModified.push_back(m.second.first);
403 vector<VuoCompilerNodeClass *> nodeClassesAddedOrModified;
404 vector<VuoCompilerType *> typesAddedOrModified;
409 nodeClassesAddedOrModified.push_back(nodeClass);
414 typesAddedOrModified.push_back(type);
418 vector<string> nodeClassesRemovedOrModified;
419 vector<string> typesRemovedOrModified;
420 vector<string> librariesRemovedOrModified;
423 string moduleKey =
module->getPseudoBase()->getModuleKey();
426 nodeClassesRemovedOrModified.push_back(moduleKey);
431 typesRemovedOrModified.push_back(moduleKey);
433 librariesRemovedOrModified.push_back(moduleKey);
437 set< pair<VuoCompilerModule *, VuoCompilerModule *> > modulesModifiedSet;
438 for (
auto m : modulesModified)
439 modulesModifiedSet.insert(m.second);
442 librariesRemovedOrModified, modulesModifiedSet, issues);
449void VuoModuleManager::updateWithModulesBeingLoaded(
const vector<string> &nodeClassesToRemove,
const vector<VuoCompilerNodeClass *> &nodeClassesToAdd,
450 const vector<string> &typesToRemove,
const vector<VuoCompilerType *> &typesToAdd,
451 const vector<string> &librariesToRemove,
455 update(nodeClassesToRemove, nodeClassesToAdd, typesToRemove, typesToAdd, librariesToRemove, modulesModified, issues);
464 map<string, VuoCompilerNodeClass *> nodeClassesMap = compiler->
getNodeClasses();
465 map<string, VuoCompilerType *> typesMap = compiler->
getTypes();
467 vector<VuoCompilerNodeClass *> nodeClasses;
468 for (map<string, VuoCompilerNodeClass *>::iterator i = nodeClassesMap.begin(); i != nodeClassesMap.end(); ++i)
469 nodeClasses.push_back(i->second);
471 vector<VuoCompilerType *> types;
472 for (map<string, VuoCompilerType *>::iterator i = typesMap.begin(); i != typesMap.end(); ++i)
473 types.push_back(i->second);
476 update(vector<string>(), nodeClasses, vector<string>(), types, vector<string>(), set< pair<VuoCompilerModule *, VuoCompilerModule *> >(), &issues);
488void VuoModuleManager::update(
const vector<string> &nodeClassesToRemove,
const vector<VuoCompilerNodeClass *> &nodeClassesToAdd,
489 const vector<string> &typesToRemove,
const vector<VuoCompilerType *> &typesToAdd,
490 const vector<string> &librariesToRemove,
491 const set< pair<VuoCompilerModule *, VuoCompilerModule *> > &modulesModified,
496 updateLoadedNodeClasses(nodeClassesToRemove, nodeClassesToAdd);
497 updateLoadedTypes(typesToRemove, typesToAdd);
503 map<string, VuoCompilerNodeClass *> dependenciesInvalidated;
504 set<string> dependenciesLost;
505 map<string, string> originalGenericNodeClassName;
506 if (! (nodeClassesToRemove.empty() && typesToRemove.empty() && librariesToRemove.empty()) )
510 set<string> dependencies = compiler->getDependenciesForComposition(composition->
getBase()->
getCompiler());
512 vector<string> sortedDependencies(dependencies.begin(), dependencies.end());
513 std::sort(sortedDependencies.begin(), sortedDependencies.end());
515 vector<string> sortedNodeClassesToRemove(nodeClassesToRemove.begin(), nodeClassesToRemove.end());
516 std::sort(sortedNodeClassesToRemove.begin(), sortedNodeClassesToRemove.end());
518 vector<string> sortedTypesToRemove(typesToRemove.begin(), typesToRemove.end());
519 std::sort(sortedTypesToRemove.begin(), sortedTypesToRemove.end());
521 vector<string> sortedLibrariesToRemove(librariesToRemove.begin(), librariesToRemove.end());
522 std::sort(sortedLibrariesToRemove.begin(), sortedLibrariesToRemove.end());
524 set<string> dependenciesInvalidatedSet;
525 std::set_intersection(sortedNodeClassesToRemove.begin(), sortedNodeClassesToRemove.end(),
526 sortedDependencies.begin(), sortedDependencies.end(),
527 std::inserter(dependenciesInvalidatedSet, dependenciesInvalidatedSet.end()));
528 std::set_intersection(sortedTypesToRemove.begin(), sortedTypesToRemove.end(),
529 sortedDependencies.begin(), sortedDependencies.end(),
530 std::inserter(dependenciesInvalidatedSet, dependenciesInvalidatedSet.end()));
531 std::set_intersection(sortedLibrariesToRemove.begin(), sortedLibrariesToRemove.end(),
532 sortedDependencies.begin(), sortedDependencies.end(),
533 std::inserter(dependenciesInvalidatedSet, dependenciesInvalidatedSet.end()));
537 for (
VuoNode *node : composition->getBase()->getNodes())
539 if (node->getNodeClass()->hasCompiler())
541 set<string> nodeClassDependencies = node->getNodeClass()->getCompiler()->getDependencies();
542 set<string> nodeClassDependenciesInvalidated;
543 std::set_intersection(nodeClassDependencies.begin(), nodeClassDependencies.end(),
544 typesToRemove.begin(), typesToRemove.end(),
545 std::inserter(nodeClassDependenciesInvalidated, nodeClassDependenciesInvalidated.end()));
547 if (! nodeClassDependenciesInvalidated.empty())
548 dependenciesInvalidatedSet.insert(node->getNodeClass()->getClassName());
554 for (
VuoNode *node : composition->getBase()->getNodes())
556 if (node->getNodeClass()->hasCompiler())
559 if (specializedNodeClass)
562 if (find(nodeClassesToRemove.begin(), nodeClassesToRemove.end(), genericNodeClassName) != nodeClassesToRemove.end())
564 dependenciesInvalidatedSet.insert(genericNodeClassName);
565 originalGenericNodeClassName[ specializedNodeClass->
getBase()->
getClassName() ] = genericNodeClassName;
573 for (set<string>::iterator i = dependenciesInvalidatedSet.begin(); i != dependenciesInvalidatedSet.end(); ++i)
575 string dependency = *i;
577 bool foundReplacement =
false;
578 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::const_iterator j = modulesModified.begin(); j != modulesModified.end(); ++j)
580 if (j->first->getPseudoBase()->getModuleKey() == dependency)
583 if (replacementNodeClass)
584 dependenciesInvalidated[dependency] = replacementNodeClass;
586 foundReplacement =
true;
591 if (! foundReplacement)
592 dependenciesLost.insert(dependency);
598 map<string, VuoCompilerNodeClass *> dependenciesAdded;
599 if (! nodeClassesToAdd.empty())
608 string addedNodeClassName = addedNodeClass->getBase()->getClassName();
609 if (addedNodeClassName == nodeClassName)
611 dependenciesAdded[nodeClassName] = addedNodeClass;
615 dependenciesAdded[addedNodeClassName] = addedNodeClass;
616 originalGenericNodeClassName[nodeClassName] = addedNodeClassName;
624 if (! (dependenciesInvalidated.empty() && dependenciesLost.empty() && dependenciesAdded.empty()) )
633 string nodeClassName = node->getNodeClass()->getClassName();
635 auto nameIter = originalGenericNodeClassName.find(nodeClassName);
636 bool isSpecializedNodeClass = (nameIter != originalGenericNodeClassName.end());
637 if (isSpecializedNodeClass)
638 nodeClassName = nameIter->second;
640 VuoCompilerNodeClass *replacementNodeClass = NULL;
641 map<string, VuoCompilerNodeClass *>::const_iterator invIter = dependenciesInvalidated.find(nodeClassName);
642 if (invIter != dependenciesInvalidated.end())
644 replacementNodeClass = invIter->second;
648 map<string, VuoCompilerNodeClass *>::const_iterator addIter = dependenciesAdded.find(nodeClassName);
649 if (addIter != dependenciesAdded.end())
651 replacementNodeClass = addIter->second;
655 VuoNode *replacementNode =
nullptr;
656 if (replacementNodeClass)
658 if (isSpecializedNodeClass)
661 if (replacementNodeClass)
662 replacementNode = composition->
createBaseNode(replacementNodeClass, node);
664 else if (dependenciesLost.find(nodeClassName) != dependenciesLost.end())
685 for (set< pair<VuoCompilerModule *, VuoCompilerModule *> >::const_iterator i = modulesModified.begin(); i != modulesModified.end(); ++i)
690 if (oldNodeClass && newNodeClass)
696 string snapshotWithNewModules = composition->
takeSnapshot();
708 nodeLibrary->updateNodeClassList(nodeClassesToRemove, nodeClassesToAdd);
713 for (vector<VuoCompilerNodeClass *>::const_iterator i = nodeClassesToAdd.begin(); i != nodeClassesToAdd.end(); ++i)
715 string nodeClassName = (*i)->getBase()->getClassName();
716 auto callbackIter = callbackForNodeClass.find(nodeClassName);
717 if (callbackIter != callbackForNodeClass.end())
719 CallbackType callback = callbackIter->second.first;
722 if (! callbackIter->second.second)
723 cancelCallbackForNodeClass(nodeClassName);
730 if (isResponsibleForReportingErrors(
this, errors, nodeClassesToAdd))
735 codeWindow->setIssues(errors);
737 showErrorDialog(errors);
744 codeWindow->setIssues(&noIssues);
755 const vector<VuoCompilerNodeClass *> &nodeClassesToAdd)
768 string nodeClassName;
775 else if (! nodeClassesToAdd.empty())
778 nodeClassName = nodeClassesToAdd.front()->getBase()->getClassName();
785 if (! nodeClassName.empty())
787 if (m->codeWindow->getNodeClassName() == nodeClassName)
788 managerWithCodeEditor = m;
791 else if (m->composition)
793 if (! issuePath.empty())
795 string issueDir, file, ext;
798 managerWithCompositionLocal = m;
807 VuoModuleManager *responsibleManager = (managerWithCodeEditor ? managerWithCodeEditor :
808 (managerWithCompositionLocal ? managerWithCompositionLocal :
810 return responsibleManager == currManager;
818 QString errorSummary = VuoEditor::tr(
"There was a problem loading one or more nodes into your library.");
819 QString errorDisclosureDetails = QString::fromStdString(errors->
getLongDescription(
false));
821 QStringList brokenModulePaths;
823 brokenModulePaths.append(QString::fromStdString(issue.
getFilePath()));
824 brokenModulePaths.removeDuplicates();
826 QMessageBox messageBox;
829 messageBox.setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowMaximizeButtonHint);
833 messageBox.setTextFormat(Qt::RichText);
834 messageBox.setStandardButtons(QMessageBox::Discard | QMessageBox::Cancel);
835 messageBox.setButtonText(QMessageBox::Discard, VuoEditor::tr(
"Move Broken Nodes to Trash"));
836 messageBox.setButtonText(QMessageBox::Cancel, VuoEditor::tr(
"Not Now"));
837 messageBox.setDefaultButton(QMessageBox::Discard);
838 messageBox.setText(errorSummary);
839 messageBox.setStyleSheet(
"#qt_msgbox_informativelabel, QMessageBoxDetailsText {" + fonts->
getCSS(fonts->
dialogBodyFont()) +
"}");
840 messageBox.setDetailedText(errorDisclosureDetails);
843 static_cast<QPushButton *
>(messageBox.button(QMessageBox::Cancel))->setAutoDefault(
false);
844 messageBox.button(QMessageBox::Cancel)->setFocus();
848 if (messageBox.exec() == QMessageBox::Discard)
853 foreach (QString path, brokenModulePaths)
866void VuoModuleManager::updateLoadedNodeClasses(
const vector<string> &nodeClassesToRemove,
867 const vector<VuoCompilerNodeClass *> &nodeClassesToAdd)
871 VuoNodeSet *nodeSet = nodeClassToAdd->getBase()->getNodeSet();
873 knownNodeSets.insert(nodeSet->
getName());
876 for (
auto i = loadedTypeConverterNodeClasses.begin(); i != loadedTypeConverterNodeClasses.end(); ++i)
878 set<string> stillLoaded;
879 std::set_difference(i->second.begin(), i->second.end(),
880 nodeClassesToRemove.begin(), nodeClassesToRemove.end(),
881 std::inserter(stillLoaded, stillLoaded.end()));
882 i->second = stillLoaded;
905 if (inType != outType)
906 loadedTypeConverterNodeClasses[{inType, outType}].insert(nodeClass->
getClassName());
915void VuoModuleManager::updateLoadedTypes(
const vector<string> &typesToRemove,
const vector<VuoCompilerType *> &typesToAdd)
917 for (
auto i = loadedSingletonTypes.begin(); i != loadedSingletonTypes.end(); )
919 if (std::find(typesToRemove.begin(), typesToRemove.end(), i->first) != typesToRemove.end())
920 i = loadedSingletonTypes.erase(i);
925 for (
auto i = loadedGenericCompoundTypes.begin(); i != loadedGenericCompoundTypes.end(); )
927 if (std::find(typesToRemove.begin(), typesToRemove.end(), i->first) != typesToRemove.end())
928 i = loadedGenericCompoundTypes.erase(i);
935 string typeName = typeToAdd->getBase()->getModuleKey();
939 if (typeName ==
"VuoList")
940 loadedGenericCompoundTypes[typeName] = typeToAdd;
942 loadedSingletonTypes[typeName] = typeToAdd;
944 VuoNodeSet *nodeSet = typeToAdd->getBase()->getNodeSet();
946 knownNodeSets.insert(nodeSet->
getName());
955string VuoModuleManager::getPrimaryAffiliatedNodeSetForType(
const string &typeName)
957 map<string, string> nodeSetForType;
958 nodeSetForType[
"VuoAnchor"] =
"vuo.layer";
959 nodeSetForType[
"VuoAudioSamples"] =
"vuo.audio";
960 nodeSetForType[
"VuoBlendMode"] =
"vuo.image";
961 nodeSetForType[
"VuoCoordinateUnit"] =
"vuo.window";
962 nodeSetForType[
"VuoCubemap"] =
"vuo.image";
963 nodeSetForType[
"VuoCursor"] =
"vuo.window";
964 nodeSetForType[
"VuoCurve"] =
"vuo.motion";
965 nodeSetForType[
"VuoCurveEasing"] =
"vuo.motion";
966 nodeSetForType[
"VuoDiode"] =
"vuo.math";
967 nodeSetForType[
"VuoFont"] =
"vuo.font";
968 nodeSetForType[
"VuoHorizontalAlignment"] =
"vuo.layer";
969 nodeSetForType[
"VuoImageColorDepth"] =
"vuo.image";
970 nodeSetForType[
"VuoImageWrapMode"] =
"vuo.image";
971 nodeSetForType[
"VuoIntegerRange"] =
"vuo.math";
972 nodeSetForType[
"VuoInteraction"] =
"vuo.ui";
973 nodeSetForType[
"VuoInteractionType"] =
"vuo.ui";
974 nodeSetForType[
"VuoListPosition"] =
"vuo.list";
975 nodeSetForType[
"VuoLoopType"] =
"vuo.motion";
976 nodeSetForType[
"VuoMathExpressionList"] =
"vuo.math";
977 nodeSetForType[
"VuoMesh"] =
"vuo.mesh";
978 nodeSetForType[
"VuoModifierKey"] =
"vuo.keyboard";
979 nodeSetForType[
"VuoOrientation"] =
"vuo.ui";
980 nodeSetForType[
"VuoRange"] =
"vuo.math";
981 nodeSetForType[
"VuoRectangle"] =
"vuo.image";
982 nodeSetForType[
"VuoRenderedLayers"] =
"vuo.ui";
983 nodeSetForType[
"VuoScreen"] =
"vuo.screen";
984 nodeSetForType[
"VuoShader"] =
"vuo.shader";
985 nodeSetForType[
"VuoSortOrder"] =
"vuo.list";
986 nodeSetForType[
"VuoTextCase"] =
"vuo.text";
987 nodeSetForType[
"VuoTextComparison"] =
"vuo.text";
988 nodeSetForType[
"VuoTextSort"] =
"vuo.text";
989 nodeSetForType[
"VuoTransform"] =
"vuo.transform";
990 nodeSetForType[
"VuoTransform2d"] =
"vuo.transform";
991 nodeSetForType[
"VuoTree"] =
"vuo.tree";
992 nodeSetForType[
"VuoUrl"] =
"vuo.url";
993 nodeSetForType[
"VuoUuid"] =
"vuo.ui";
994 nodeSetForType[
"VuoVerticalAlignment"] =
"vuo.layer";
995 nodeSetForType[
"VuoWave"] =
"vuo.motion";
996 nodeSetForType[
"VuoWindowDescription"] =
"vuo.window";
997 nodeSetForType[
"VuoWindowProperty"] =
"vuo.window";
998 nodeSetForType[
"VuoWindowReference"] =
"vuo.window";
999 nodeSetForType[
"VuoWrapMode"] =
"vuo.math";
1001 map<string, string>::iterator i = nodeSetForType.find(typeName);
1002 if (i != nodeSetForType.end())