The binary data namespace


#1

My Juce project is old, and predates the effective use of binary data, so moving to using it has allowed me to just delete all these messy scripts I was using to package binary data myself.

Now I'm using it, I find myself using it for more and more configuration things.

I see one problem arising in the future - and that's name collisions. The naming of binary data is a global namespace, so you want something better to avoid collisions than "being careful".

Testing shows that if you create multiple binary resources of the same name, they get indices 2, 3, etc in alphabetical order (i.e. "randomly" from the point of view of my program).

I've managed to avoid doing this, but if I did do this and didn't notice, I'd possibly get a mysterious bug.

File suffixes are useful - but I'm already using file suffixes to prevent this to some extent, distinguishing between .svg, .xml and .def (serialized protocol buffers).  But now I have a lot of small .def files and I'm organizing them in subdirectories...

Various solutions come to mind, any of which might be useful.  After some scribbling, my feeling is that the following idea is both really simple to implement, really general, and wouldn't affect existing users at all.

When you click on a folder in File view, you see a page that lists the files and has a check box for "Compile" and "Add to Binary Resources". 

All this would stay the same - but there would be an additional single line below this:  "Prefix for binary resources", set to empty by default.  Any string in there would be added as a prefix to all binary resource variable names contained in that folder.

 


#2

Good request! I'm a bit busy, but if you want to suggest a few tweaks to make it happen.. wink


#3

Great, as long as I have your BDFL approval, I'll put this on my list - which might be delayed somewhat as so far I'm still dealing with the bad consequences of accidentally upgrading to XCode 5...


#4

I think I've found a solution to this. So here is what git diff prints out.


diff --git a/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.cpp b/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.cpp
index b835756..72942cb 100644
--- a/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.cpp    
+++ b/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.cpp    
@@ -41,17 +41,26 @@ ResourceFile::~ResourceFile()
 }
 
 //==============================================================================
-void ResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem)
+void ResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem, const String& prefix)
 {
     if (projectItem.isGroup())
     {
+        String ns = "";
+        if (projectItem.shouldBeAddedToBinaryResources())
+        {
+          ns = prefix
+            + CodeHelpers::makeValidIdentifier(
+              projectItem.getName().replaceCharacter(' ','_')
+              , false, true, false)
+            + "_";
+        }
         for (int i = 0; i < projectItem.getNumChildren(); ++i)
-            addResourcesFromProjectItem (projectItem.getChild(i));
+            addResourcesFromProjectItem (projectItem.getChild(i), ns);
     }
     else
     {
         if (projectItem.shouldBeAddedToBinaryResources())
-            addFile (projectItem.getFile());
+            addFile (projectItem.getFile(), prefix);
     }
 }
 
@@ -61,11 +70,11 @@ void ResourceFile::setClassName (const String& name)
     className = name;
 }
 
-void ResourceFile::addFile (const File& file)
+void ResourceFile::addFile (const File& file, const String& prefix)
 {
     files.add (file);
 
-    const String variableNameRoot (CodeHelpers::makeBinaryDataIdentifierName (file));
+    const String variableNameRoot (prefix + CodeHelpers::makeBinaryDataIdentifierName (file));
     String variableName (variableNameRoot);
 
     int suffix = 2;
diff --git a/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.h b/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.h
index 49990e0..edd6289 100644
--- a/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.h    
+++ b/extras/Introjucer/Source/Project Saving/jucer_ResourceFile.h    
@@ -41,7 +41,7 @@ public:
     void setClassName (const String& className);
     String getClassName() const       { return className; }
 
-    void addFile (const File& file);
+    void addFile (const File& file, const String& prefix = "");
     String getDataVariableFor (const File& file) const;
     String getSizeVariableFor (const File& file) const;
 
@@ -61,7 +61,7 @@ private:
 
     Result writeHeader (MemoryOutputStream&);
     Result writeCpp (MemoryOutputStream&, const File& headerFile, int& index, int maxFileSize);
-    void addResourcesFromProjectItem (const Project::Item& node);
+    void addResourcesFromProjectItem (const Project::Item& node, const String& prefix = "");
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResourceFile)
 };
diff --git a/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h b/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h
index 1d6c4a3..5f22764 100644
--- a/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h
+++ b/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h
@@ -123,10 +123,10 @@ private:
             {
                 addAndMakeVisible (compileButton);
                 compileButton.getToggleStateValue().referTo (item.getShouldCompileValue());
-
-                addAndMakeVisible (resourceButton);
-                resourceButton.getToggleStateValue().referTo (item.getShouldAddToResourceValue());
             }
+
+            addAndMakeVisible (resourceButton);
+            resourceButton.getToggleStateValue().referTo (item.getShouldAddToResourceValue());
         }
 
         void paint (Graphics& g) override
diff --git a/extras/Introjucer/Source/Project/jucer_ProjectTree_Group.h b/extras/Introjucer/Source/Project/jucer_ProjectTree_Group.h
index 3e18a93..a02afeb 100644
--- a/extras/Introjucer/Source/Project/jucer_ProjectTree_Group.h
+++ b/extras/Introjucer/Source/Project/jucer_ProjectTree_Group.h
@@ -127,6 +127,12 @@ public:
         m.addItem (4, "Disable compiling of all enclosed files");
 
         m.addSeparator();
+        if (item.shouldBeAddedToBinaryResources())
+            m.addItem (9, "Do not use group as namespace for binary files");
+        else
+            m.addItem (10, "Use group as namespace for binary files");
+
+        m.addSeparator();
         m.addItem (5, "Sort Items Alphabetically");
         m.addItem (6, "Sort Items Alphabetically (Groups first)");
         m.addSeparator();
@@ -150,6 +156,8 @@ public:
             case 6:     item.sortAlphabetically (true); break;
             case 7:     triggerAsyncRename (item); break;
             case 8:     deleteAllSelectedItems(); break;
+            case 9:     item.getShouldAddToResourceValue() = false; break;
+            case 10:    item.getShouldAddToResourceValue() = true; break;
             default:    processCreateFileMenuItem (resultCode); break;
         }
     }
diff --git a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp
index 7ba1299..b59d0d3 100644
--- a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp
+++ b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.cpp
@@ -123,9 +123,9 @@ namespace CodeHelpers
                 + "_INCLUDED";
     }
 
-    String makeBinaryDataIdentifierName (const File& file)
+    String makeBinaryDataIdentifierName (const File& file, const String& prefix)
     {
-        return makeValidIdentifier (file.getFileName()
+        return makeValidIdentifier (prefix + file.getFileName()
                                         .replaceCharacters (" .", "__")
                                         .retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"),
                                     false, true, false);
diff --git a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h
index 0d25ef7..aaef5b3 100644
--- a/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h
+++ b/extras/Introjucer/Source/Utility/jucer_CodeHelpers.h
@@ -34,7 +34,7 @@ namespace CodeHelpers
     String createIncludeStatement (const File& includedFile, const File& targetFile);
     String createIncludeStatement (const String& includePath);
     String makeHeaderGuardName (const File& file);
-    String makeBinaryDataIdentifierName (const File& file);
+    String makeBinaryDataIdentifierName (const File& file, const String& prefix = "");
 
     String stringLiteral (const String& text, int maxLineLength = -1);
     String floatLiteral (double value, int numDecPlaces);
 

It simply allows to use group names as namespaces if needed.