New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate resource graph on bundle #7802
Conversation
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Outdated
Show resolved
Hide resolved
* merge * remove import
# Conflicts: # com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
@britzl I added my fix into your branch and resolved the conflict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Some performance improvement possibility when storing the result.
Also some questions and notes.
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/archive/ArchiveBuilder.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceNode.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceNode.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceGraphs.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceNode.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Please time it with Family Island to make sure we don't add too much time to it.
@@ -467,7 +477,7 @@ public Task<?> createTask(IResource inputResource, Class<? extends Builder<?>> b | |||
builder.setProject(this); | |||
task = builder.create(inputResource); | |||
if (task != null) { | |||
TimeProfiler.addData("output", task.getOutputsString()); | |||
TimeProfiler.addData("output", StringUtil.truncate(task.getOutputsString(), 1000)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in a big project it thousands of paths, I decided to truncate too long strings
@@ -208,13 +181,16 @@ public void write(RandomAccessFile archiveIndex, RandomAccessFile archiveData, P | |||
Collections.sort(entries); // Since it has no hash, it sorts on path | |||
|
|||
for (int i = entries.size() - 1; i >= 0; --i) { | |||
TimeProfiler.start("Write file"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more info about file archiving
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/archive/ArchiveBuilder.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceGraph.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceGraph.java
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceNode.java
Outdated
Show resolved
Hide resolved
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/graph/ResourceGraph.java
Outdated
Show resolved
Hide resolved
private Set<String> excludedResources = new HashSet<>(); | ||
private HashMap<String, ResourceNode> pathToNode = new HashMap<>(); | ||
private HashMap<String, List<String>> pathToDependants = new HashMap<>(); | ||
private HashMap<String, HashSet<String>> pathToDependants = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using of a HashSet instead of a List helps to make sure that all the resource entries are unique
} | ||
flagAllNonExcludedResources(child, visited); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Visit all the nodes in non-excluded collections once and flag them as used in the main bundle. We can exclude everything else.
} | ||
|
||
public List<String> getDependants(String filepath) throws IOException { | ||
public HashSet<ResourceNode> getAllDependants(ResourceNode node) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's easier to operate with nodes instead of strings here
if (!child.relativeFilepath.endsWith("collectionproxyc")) { | ||
dependants.addAll(getDependants(child.relativeFilepath)); | ||
if (!child.checkType(ResourceNode.Type.CollectionProxy)) { | ||
dependants.addAll(getAllDependants(child)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I avoid operations over strings as much as possible. I use already known info about the node (as type e.g. collection proxy)
HashSet<ResourceNode> allProxyDependants = this.getAllDependants(proxyNode); | ||
for (ResourceNode dependant : allProxyDependants) { | ||
// Exclude resources referenced from the main bundle | ||
if (dependant.isInMainBundle()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exclude resources we use at least once in the main bundle
public boolean checkType(Type type) { | ||
// ExcludedCollectionProxy is CollectionProxy but CollectionProxy isn't ExcludedCollectionProxy | ||
if (this.nodeType == Type.ExcludedCollectionProxy) { | ||
return type == Type.CollectionProxy || type == Type.ExcludedCollectionProxy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old approach with excluded
flag was confusing.
Semantically the flag was about resource (flag on a collection proxy), not a ResourceNode, so I moved it into types to make sure it's clear now.
Also, we have inMainBundle
that helps to figure out if resource excluded or not.
@@ -460,90 +489,9 @@ public void testCreateManifest_Resources() throws NoSuchAlgorithmException, Inva | |||
} | |||
|
|||
if (current.getUrl().equals("/main/level1.collectionproxyc")) { | |||
assertEquals(5, current.getDependantsCount()); | |||
printDeps(data, current); | |||
assertEquals(4, current.getDependantsCount()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Old code worked wrong:
root
+--/main/main.collectionc
+--/main/main.goc
| +--/main/main.scriptc
|
+--/main/shared_go.goc
|
+--/main/dynamic.collectionc
| +--/main/dynamic.goc
|
+--/main/level1.collectionproxyc
+--/main/level1.collectionc
+--/main/dynamic.goc
+--/main/level1.goc
| +--/main/level1.scriptc
| +--/main/shared_go.goc
|
+--/main/level2.collectionproxyc
+--/main/level2.collectionc
+--/main/dynamic.goc
+--/main/level2.goc
+--/main/level2.soundc
new code includes only:
[junit] /main/level1.goc
[junit] /main/level1.scriptc
[junit] /main/level2.collectionproxyc
[junit] /main/level1.collectionc
old code includes:
[junit] /main/level1.goc
[junit] /main/level1.scriptc
[junit] /main/shared_go.goc
[junit] /main/level2.collectionproxyc
[junit] /main/level1.collectionc
But /main/shared_go.goc
used in the main bundle and shouldn't be included.
com.dynamo.cr/com.dynamo.cr.bob/src/com/dynamo/bob/pipeline/GameProjectBuilder.java
Outdated
Show resolved
Hide resolved
if (shouldPublishLU) { | ||
generator.writeFieldName("isInMainBundle"); | ||
generator.writeBoolean(node.isInMainBundle()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@britzl isInMainBundle
isn't useful if a user doesn't use LiveUpdate, and it may mislead a developer. So, I don't include this data if LU is off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* Initial commit * Update ResourceNodeGraph.java * Update ResourceNodeGraph.java * Fix imports for tests * Improved tostring * Forgot to call visitor.leave() on early out * Split resource and graph builds * Merged set and graph creation * Use resources instead of resource paths * Cache hex digests * Added hex digest to resource nodes * Added hashCode and equals to resource nodes * Set hex digests on all nodes in a resource graph * Changed how the archive builder is created * Fix keep-unused * Set excluded resources * Merge dev + fixes (defold#7989) * merge * remove import * Change from absolute to relative paths * Use relative paths in resource nodes * Added timers * Added option to write graph directly to stream * Reworked the resource graph * Fixed tests * Moved test * take into account only unique children * fix issue with ManifestBuilder * fix issue with resurce exclusion * fix an issue in tests * semantics refactoring * remove old comment * do not include information about the main bundle if user doesn't use LU --------- Co-authored-by: Alexey Gulev <me@agulev.com>
When building a project using the bob.jar command line tool a resource graph in json format will be saved as
build/default/game.graph.json
. The resource graph will list all resources included in the game archive, starting at the top level (project root) and following a parent-child hierarchy from the game.project file down through the bootstrap collection to each leaf resource. Example of a graph:Fixes #7753
PR checklist