Skip to content

Commit

Permalink
Provide on-demand, one-time asset generation instead of maintaining a…
Browse files Browse the repository at this point in the history
…ssets based on imageChanged events from Photoshop
  • Loading branch information
mcilroyc committed May 26, 2017
1 parent e15e68b commit 9befd17
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 1,470 deletions.
3 changes: 2 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module.exports = function (grunt) {

jshint : {
options : {
jshintrc : ".jshintrc"
jshintrc : ".jshintrc",
reporterOutput: ""
},
js : [
"*.js",
Expand Down
223 changes: 0 additions & 223 deletions lib/assetmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@

var MAX_PATH_LENGTH = os.platform() === "darwin" ? 255 : 260;

/**
* Return the keys for a set as integers.
*
* @private
* @param {{number: *}} set A set
* @return {Array.<number>} The keys of the set as integers
*/
function _intKeys(set) {
return Object.keys(set).map(function (key) {
return parseInt(key, 10);
});
}

/**
* The asset manager maintains a set of assets for a given document. On
* initialization, it parses the layers' names into a set of components,
Expand Down Expand Up @@ -77,9 +64,6 @@
this._renderManager = renderManager;
this._fileManager = new FileManager(generator, config, logger);
this._errorManager = new ErrorManager(generator, config, logger, this._fileManager);

this._handleChange = this._handleChange.bind(this);
this._handleCompsChange = this._handleCompsChange.bind(this);
}

util.inherits(AssetManager, events.EventEmitter);
Expand Down Expand Up @@ -485,218 +469,12 @@
return false;
};

/**
* Cancel outstanding rendering and remove artifacts.
* If forgetComponent is set then removed references to compComponents.
*
* @private
* @param {object} compComponents indexed by component Id
* @param {boolean} forgetComponent whether to derefernce the component
*/
AssetManager.prototype._cleanupCompComponents = function (compComponents, forgetComponent) {
Object.keys(compComponents).forEach(function (componentId) {
var comp = this._componentManager.getComponent(componentId);
if (comp) {
if (forgetComponent) {
this._componentManager.removeComponent(componentId);
}
if (this._hasPendingRender(componentId)) {
this._renderManager.cancel(componentId);
}
this._fileManager.removeFileWithin(comp.assetPath);
}
}.bind(this));
};

/**
* Handle the document's change events for the comps list. If comps have changed
* reparse those comps and their dependencies into components, and add the
* comp ids into the work set.
*
* @private
* @param {object} change A change object emitted by the Document instance
* managed by this AssetManager instance.
*/
AssetManager.prototype._handleCompsChange = function (change) {
Object.keys(change).forEach(function (compId) {
var compComponents = this._componentManager.getComponentsByComp(compId),
ccTemp;

if (change[compId].type === "removed") {
this._errorManager.removeErrors(compId, this._errorManager.LAYER_COMP);
this._cleanupCompComponents(compComponents, true);

} else {
if (change[compId].name) {
this._errorManager.removeErrors(compId, this._errorManager.LAYER_COMP);
this._cleanupCompComponents(compComponents, true);
compComponents = [];
this._addComponentsForComp(change[compId], this._document, compComponents);
} else {
ccTemp = [];
Object.keys(compComponents).forEach(function (cmp) {
ccTemp.push(compComponents[cmp]);
});
this._cleanupCompComponents(compComponents, false);
compComponents = ccTemp;
}
compComponents.forEach(function (component) {
this._requestRender(component);
}, this);
}
}.bind(this));
};

/**
* Handle the document's change events. If the document is closed, finish
* processing. If layers are changed, reparse those layers and their
* dependencies to into components, and add the layer ids to the work set.
*
* @private
* @param {object} change A change object emitted by the Document instance
* managed by this AssetManager instance.
*/
AssetManager.prototype._handleChange = function (change) {
this._logger.debug("handleChange:", change);

if (change.file) {
if (this._document.saved && !change.file.hasOwnProperty("previousSaved")) {
// If the file has been renamed, asset generation will be disabled, so do nothing here
return;
}
this._fileManager.updateBasePath(this._document);
}

if (change.generatorSettings) {
this._reset();
return;
}

if (change.comps) {
this._handleCompsChange(change.comps);
}

// if the layer was just renamed; then reparse it and figure out if component
// settings have changed; if so, add it to the work set; otherwise, just
// fire off any relevant rename events;

if (change.layers) {
var changedLayerIds = _intKeys(change.layers);

// Close the set of changed layers with their dependencies
var dependentLayers = changedLayerIds.reduce(function (dependentLayers, id) {
var layerChange = change.layers[id],
layer = layerChange.layer,
dependencies = layer.getDependentLayers();

return _intKeys(dependencies).reduce(function (dependentLayers, layerId) {
var dependentLayer = dependencies[layerId];
dependentLayers[dependentLayer.id] = dependentLayer;
return dependentLayers;
}, dependentLayers);
}.bind(this), {});

// Find all the component specifications for all the changed layers and their dependencies
var specificationsByLayer = _intKeys(dependentLayers).reduce(function (specifications, layerId) {
var layer = dependentLayers[layerId],
validSpecifications = [];

this._errorManager.removeErrors(layerId);

this._componentManager.findAllComponents(layer)
.forEach(function (specification) {
var component = specification.component,
errors = specification.errors;

if (component) {
validSpecifications.push(component);
} else if (errors) {
errors.forEach(function (error) {
this._errorManager.addError(layer, error);
}, this);
}
}, this);

specifications[layer.id] = validSpecifications;

return specifications;
}.bind(this), {});

// Determine whether or not the changes necessitate a complete reset.
// E.g., has a default component changed?
var resetRequired = _intKeys(specificationsByLayer).some(function (layerId) {
var specifications = specificationsByLayer[layerId];

return specifications.some(function (specification) {
return specification.hasOwnProperty("default");
});
}, this);

if (resetRequired) {
this._reset();
return;
}

// Compute the set of removed layers;
// subtract the removed layers from the set of changed layers above
var removedLayerIds = changedLayerIds.filter(function (layerId) {
var layerChange = change.layers[layerId];
if (layerChange.type === "removed") {
if (specificationsByLayer.hasOwnProperty(layerId)) {
delete specificationsByLayer[layerId];
}
return true;
}
}, this);

// Clear out the removed layer components;
// remove the assets from the old components and/or cancel their renders
removedLayerIds.forEach(function (layerId) {
var componentsToRemove = this._componentManager.getComponentsByLayer(layerId);

Object.keys(componentsToRemove).forEach(function (componentId) {
this._cleanupDerivedComponents(componentId);
this._componentManager.removeComponent(componentId);
}, this);

this._errorManager.removeErrors(layerId);
}, this);

_intKeys(specificationsByLayer).forEach(function (layerId) {
var layer = dependentLayers[layerId],
currentComponents = specificationsByLayer[layerId],
previousComponents = this._componentManager.getComponentsByLayer(layerId);

Object.keys(previousComponents).forEach(function (componentId) {
this._cleanupDerivedComponents(componentId);
this._componentManager.removeComponent(componentId);
}, this);

currentComponents.forEach(function (component) {
try {
var componentId = this._componentManager.addComponent(layer, component);
this._componentManager.getDerivedComponents(componentId).forEach(function (derivedComponent) {
this._requestRender(derivedComponent);
}, this);
} catch (ex) {
this._errorManager.addError(layer, ex.message);
}
}, this);
}, this);
}

if (change.layers || change.comps) {
this._errorManager.reportErrors();
}
};

/**
* Start generating assets for the document. All assets for the document will
* be regenerated initially, and new assets will continually be regenerated
* as a result of document changes.
*/
AssetManager.prototype.start = function () {
this._document.on("change", this._handleChange);
this._init();
};

Expand All @@ -706,7 +484,6 @@
* not be updated.
*/
AssetManager.prototype.stop = function () {
this._document.removeListener("change", this._handleChange);
this._renderManager.cancelAll(this._document.id);
this._fileManager.cancelAll();
};
Expand Down
Loading

0 comments on commit 9befd17

Please sign in to comment.