Skip to content

Commit 9516af0

Browse files
committed
better patch loading checks and routine, avoid most of the loading bugs and crashes
1 parent 2d41f8e commit 9516af0

File tree

3 files changed

+118
-50
lines changed

3 files changed

+118
-50
lines changed

src/PatchObject.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ void PatchObject::setPatchfile(string pf) {
10011001

10021002
//--------------------------------------------------------------
10031003
void PatchObject::keyPressed(ofKeyEventArgs &e,map<int,shared_ptr<PatchObject>> &patchObjects){
1004+
unusedArgs(patchObjects);
10041005
if(!willErase){
10051006

10061007
}
@@ -1010,12 +1011,12 @@ void PatchObject::keyPressed(ofKeyEventArgs &e,map<int,shared_ptr<PatchObject>>
10101011
void PatchObject::keyReleased(ofKeyEventArgs &e,map<int,shared_ptr<PatchObject>> &patchObjects){
10111012
if(!willErase){
10121013
if(e.key == OF_KEY_BACKSPACE){
1013-
for (int j=0;j<linksToDisconnect.size();j++){
1014+
for (int j=0;j<static_cast<int>(linksToDisconnect.size());j++){
10141015
disconnectLink(patchObjects,linksToDisconnect.at(j));
10151016
}
10161017
linksToDisconnect.clear();
10171018

1018-
for(int j=0;j<objectsSelected.size();j++){
1019+
for(int j=0;j<static_cast<int>(objectsSelected.size());j++){
10191020
if(objectsSelected.at(j) == this->nId){
10201021
ofNotifyEvent(removeEvent, objectsSelected.at(j));
10211022
this->setWillErase(true);
@@ -1024,7 +1025,7 @@ void PatchObject::keyReleased(ofKeyEventArgs &e,map<int,shared_ptr<PatchObject>>
10241025
objectsSelected.clear();
10251026
// OSX: CMD-D, WIN/LINUX: CTRL-D (DUPLICATE SELECTED OBJECTS)
10261027
}else if(e.hasModifier(MOD_KEY) && e.keycode == 68){
1027-
for(int j=0;j<objectsSelected.size();j++){
1028+
for(int j=0;j<static_cast<int>(objectsSelected.size());j++){
10281029
if(objectsSelected.at(j) == this->nId){
10291030
ofNotifyEvent(duplicateEvent, objectsSelected.at(j));
10301031
}

src/ofxVisualProgramming.cpp

Lines changed: 112 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ void ofxVisualProgramming::drawInspector(){
421421

422422
//--------------------------------------------------------------
423423
void ofxVisualProgramming::drawLivePatchingSession(){
424-
if(weAlreadyHaveObject("live patching") && livePatchingObiID != -1 && currentSubpatch == "root"){
424+
if(weAlreadyHaveObject("live patching") && livePatchingObiID != -1 && currentSubpatch == "root" && !patchObjects.empty() && patchObjects.find(livePatchingObiID) != patchObjects.end()){
425425
if(patchObjects[livePatchingObiID]->inletsConnected[0] && static_cast<ofTexture *>(patchObjects[livePatchingObiID]->_inletParams[0])->isAllocated()){
426426
float lpDrawW, lpDrawH, lpPosX, lpPosY;
427427
if(static_cast<ofTexture *>(patchObjects[livePatchingObiID]->_inletParams[0])->getWidth() >= static_cast<ofTexture *>(patchObjects[livePatchingObiID]->_inletParams[0])->getHeight()){ // horizontal texture
@@ -618,13 +618,8 @@ void ofxVisualProgramming::audioProcess(float *input, int bufferSize, int nChann
618618
void ofxVisualProgramming::addObject(string name,ofVec2f pos){
619619

620620
// check if object exists
621-
bool exists = false;
622-
for(ofxVPObjects::factory::objectRegistry::iterator it = ofxVPObjects::factory::getObjectRegistry().begin(); it != ofxVPObjects::factory::getObjectRegistry().end(); it++ ){
623-
if(it->first == name){
624-
exists = true;
625-
break;
626-
}
627-
}
621+
bool exists = isObjectInLibrary(name);
622+
628623
if(!exists && name != "audio device"){
629624
return;
630625
}
@@ -939,6 +934,33 @@ void ofxVisualProgramming::clearObjectsMap(){
939934
}
940935
}
941936

937+
//--------------------------------------------------------------
938+
bool ofxVisualProgramming::isObjectInLibrary(string name){
939+
bool exists = false;
940+
for(ofxVPObjects::factory::objectRegistry::iterator it = ofxVPObjects::factory::getObjectRegistry().begin(); it != ofxVPObjects::factory::getObjectRegistry().end(); it++ ){
941+
if(it->first == name){
942+
exists = true;
943+
break;
944+
}
945+
}
946+
947+
return exists;
948+
}
949+
950+
//--------------------------------------------------------------
951+
bool ofxVisualProgramming::isObjectIDInPatchMap(int id){
952+
bool exists = false;
953+
954+
for(map<int,shared_ptr<PatchObject>>::iterator it = patchObjects.begin(); it != patchObjects.end(); it++ ){
955+
if(it->first == id){
956+
exists = true;
957+
break;
958+
}
959+
}
960+
961+
return exists;
962+
}
963+
942964
//--------------------------------------------------------------
943965
string ofxVisualProgramming::getSubpatchParent(string subpatchName){
944966
for(map<string,vector<string>>::iterator it = subpatchesTree.begin(); it != subpatchesTree.end(); it++ ){
@@ -1089,6 +1111,10 @@ bool ofxVisualProgramming::connect(int fromID, int fromOutlet, int toID,int toIn
10891111

10901112
checkSpecialConnection(fromID,toID,linkType);
10911113

1114+
#ifdef NDEBUG
1115+
std::cout << "Connect from " << patchObjects[fromID]->getName() << " to " << patchObjects[toID]->getName() << std::endl;
1116+
#endif
1117+
10921118
connected = true;
10931119
}
10941120

@@ -1191,10 +1217,37 @@ void ofxVisualProgramming::newTempPatchFromFile(string patchFile){
11911217
ofFile::copyFromTo(fileToRead.getAbsolutePath(),newPatchFile.getAbsolutePath(),true,true);
11921218

11931219
ofDirectory dataFolderOrigin;
1194-
dataFolderOrigin.listDir(fileToRead.getEnclosingDirectory()+"/data/");
1195-
std::filesystem::path tp = ofToDataPath("temp/data/",true);
1220+
dataFolderOrigin.listDir(fileToRead.getEnclosingDirectory()+"data/");
11961221

1197-
dataFolderOrigin.copyTo(tp,true,true);
1222+
if(dataFolderOrigin.exists()){
1223+
1224+
// remove previous data content
1225+
ofDirectory oldData;
1226+
oldData.listDir(ofToDataPath("temp/data/",true));
1227+
#ifdef NDEBUG
1228+
std::cout << "Removing content from directory: " << oldData.getAbsolutePath() << std::endl;
1229+
#endif
1230+
for(size_t i=0;i<oldData.getFiles().size();i++){
1231+
oldData.getFile(i).remove();
1232+
#ifdef NDEBUG
1233+
std::cout << "Removing file: " << oldData.getFile(i).getAbsolutePath() << std::endl;
1234+
#endif
1235+
}
1236+
1237+
string oldDataPath = oldData.getAbsolutePath();
1238+
1239+
1240+
// copy new data content
1241+
#ifdef NDEBUG
1242+
std::cout << "Copying from " << dataFolderOrigin.getAbsolutePath() << " to " << oldDataPath << std::endl;
1243+
#endif
1244+
if(dataFolderOrigin.canRead() && oldData.canWrite()){
1245+
for(size_t i=0;i<dataFolderOrigin.getFiles().size();i++){
1246+
ofFile::copyFromTo(dataFolderOrigin.getFile(i).getAbsolutePath(),oldDataPath+"/"+dataFolderOrigin.getFile(i).getFileName(),true,true);
1247+
}
1248+
}
1249+
1250+
}
11981251

11991252
newFileCounter++;
12001253

@@ -1461,22 +1514,28 @@ void ofxVisualProgramming::loadPatch(string patchFile){
14611514
string objname = XML.getValue("name","");
14621515
bool loaded = false;
14631516

1464-
shared_ptr<PatchObject> tempObj = selectObject(objname);
1465-
if(tempObj != nullptr){
1466-
loaded = tempObj->loadConfig(mainWindow,*engine,i,patchFile);
1467-
if(loaded){
1468-
tempObj->setPatchfile(currentPatchFile);
1469-
tempObj->setIsRetina(isRetina);
1470-
ofAddListener(tempObj->removeEvent ,this,&ofxVisualProgramming::removeObject);
1471-
ofAddListener(tempObj->resetEvent ,this,&ofxVisualProgramming::resetObject);
1472-
ofAddListener(tempObj->reconnectOutletsEvent ,this,&ofxVisualProgramming::reconnectObjectOutlets);
1473-
ofAddListener(tempObj->duplicateEvent ,this,&ofxVisualProgramming::duplicateObject);
1474-
// Insert the new patch into the map
1475-
patchObjects[tempObj->getId()] = tempObj;
1476-
actualObjectID = tempObj->getId();
1477-
lastAddedObjectID = tempObj->getId();
1478-
1479-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
1517+
if(isObjectInLibrary(objname)){
1518+
shared_ptr<PatchObject> tempObj = selectObject(objname);
1519+
if(tempObj != nullptr){
1520+
loaded = tempObj->loadConfig(mainWindow,*engine,i,patchFile);
1521+
if(loaded){
1522+
tempObj->setPatchfile(currentPatchFile);
1523+
tempObj->setIsRetina(isRetina);
1524+
ofAddListener(tempObj->removeEvent ,this,&ofxVisualProgramming::removeObject);
1525+
ofAddListener(tempObj->resetEvent ,this,&ofxVisualProgramming::resetObject);
1526+
ofAddListener(tempObj->reconnectOutletsEvent ,this,&ofxVisualProgramming::reconnectObjectOutlets);
1527+
ofAddListener(tempObj->duplicateEvent ,this,&ofxVisualProgramming::duplicateObject);
1528+
// Insert the new patch into the map
1529+
patchObjects[tempObj->getId()] = tempObj;
1530+
actualObjectID = tempObj->getId();
1531+
lastAddedObjectID = tempObj->getId();
1532+
1533+
#ifdef NDEBUG
1534+
std::cout << "Loading "<< tempObj->getName() << std::endl;
1535+
#endif
1536+
1537+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
1538+
}
14801539
}
14811540
}
14821541
XML.popTag();
@@ -1486,31 +1545,37 @@ void ofxVisualProgramming::loadPatch(string patchFile){
14861545
// Load Links
14871546
for(int i=0;i<totalObjects;i++){
14881547
if(XML.pushTag("object", i)){
1489-
int fromID = XML.getValue("id", -1);
1490-
if (XML.pushTag("outlets")){
1491-
int totalOutlets = XML.getNumTags("link");
1492-
for(int j=0;j<totalOutlets;j++){
1493-
if (XML.pushTag("link",j)){
1494-
int linkType = XML.getValue("type", 0);
1495-
int totalLinks = XML.getNumTags("to");
1496-
for(int z=0;z<totalLinks;z++){
1497-
if(XML.pushTag("to",z)){
1498-
int toObjectID = XML.getValue("id", 0);
1499-
int toInletID = XML.getValue("inlet", 0);
1500-
1501-
if(connect(fromID,j,toObjectID,toInletID,linkType)){
1502-
//ofLog(OF_LOG_NOTICE,"Connected object %s, outlet %i TO object %s, inlet %i",patchObjects[fromID]->getName().c_str(),z,patchObjects[toObjectID]->getName().c_str(),toInletID);
1503-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
1504-
}
1548+
string objname = XML.getValue("name","");
1549+
if(isObjectInLibrary(objname)){
1550+
int fromID = XML.getValue("id", -1);
1551+
if (XML.pushTag("outlets")){
1552+
int totalOutlets = XML.getNumTags("link");
1553+
for(int j=0;j<totalOutlets;j++){
1554+
if (XML.pushTag("link",j)){
1555+
int linkType = XML.getValue("type", 0);
1556+
int totalLinks = XML.getNumTags("to");
1557+
for(int z=0;z<totalLinks;z++){
1558+
if(XML.pushTag("to",z)){
1559+
int toObjectID = XML.getValue("id", 0);
1560+
int toInletID = XML.getValue("inlet", 0);
1561+
1562+
// fix loading patches with non-existent objects (older OFXVP versions)
1563+
if(isObjectIDInPatchMap(toObjectID)){
1564+
if(connect(fromID,j,toObjectID,toInletID,linkType)){
1565+
//ofLog(OF_LOG_NOTICE,"Connected object %s, outlet %i TO object %s, inlet %i",patchObjects[fromID]->getName().c_str(),z,patchObjects[toObjectID]->getName().c_str(),toInletID);
1566+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
1567+
}
1568+
}
15051569

1506-
XML.popTag();
1570+
XML.popTag();
1571+
}
15071572
}
1573+
XML.popTag();
15081574
}
1509-
XML.popTag();
15101575
}
1511-
}
15121576

1513-
XML.popTag();
1577+
XML.popTag();
1578+
}
15141579
}
15151580
XML.popTag();
15161581
}

src/ofxVisualProgramming.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class ofxVisualProgramming : public pdsp::Wrapper {
9898
bool weAlreadyHaveObject(string name);
9999
void deleteObject(int id);
100100
void clearObjectsMap();
101+
bool isObjectInLibrary(string name);
102+
bool isObjectIDInPatchMap(int id);
101103

102104
string getSubpatchParent(string subpatchName);
103105

0 commit comments

Comments
 (0)