Comparar commits
129 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 7eb2c1a404 | |||
| 69cfc4dd77 | |||
| e88500df33 | |||
| 64ae1da03e | |||
| e24bf3171d | |||
| f301e9312f | |||
| 0b95219c2a | |||
| b05f96e77a | |||
| 063aac8730 | |||
| edeb783547 | |||
| b65c0b740a | |||
| 55d8b72e05 | |||
| 1d4469d2b9 | |||
| fda5be793d | |||
| a8666959c0 | |||
| f95125ab04 | |||
| a5cbfb2c89 | |||
| b43a580683 | |||
| 1f0f615fc4 | |||
| 3842439112 | |||
| 8229495b34 | |||
| b0135100ed | |||
| a628256682 | |||
| ddd6431d55 | |||
| a63287df92 | |||
| 3721257559 | |||
| dba9c4a25b | |||
| 11f7751843 | |||
| c05d7bb433 | |||
| 8e6bdfbeff | |||
| b4829adbc3 | |||
| a3cfa9f8e3 | |||
| 62a80d1f9f | |||
| b0ad46c66b | |||
| 7e2b83b5cc | |||
| 5193bbd931 | |||
| b513bcbec4 | |||
| 408ee8e0f4 | |||
| dd92726044 | |||
| 5d2098e6e1 | |||
| 341497323c | |||
| 1f71b254b5 | |||
| db97a492e1 | |||
| f863fc2638 | |||
| 3d6c654028 | |||
| 64f64ecd2a | |||
| 09b33792d9 | |||
| ab932c1a52 | |||
| 206f4ce6fc | |||
| 1618460984 | |||
| 41cfdfb007 | |||
| 57a60d6919 | |||
| ab3ba50886 | |||
| cc21727a7b | |||
| 1dbbf8a302 | |||
| 6f6ab1af1e | |||
| 09a51dd518 | |||
| 3e0b1c0e50 | |||
| 628c636129 | |||
| d2173bd9f3 | |||
| 2baf4a72bf | |||
| de1ca7a2d2 | |||
| 2b75f16b9a | |||
| 20618ddb40 | |||
| be97f4806e | |||
| cb97a14e59 | |||
| 6faa7d444a | |||
| 806780bd1f | |||
| 0207e73f6a | |||
| 2e0ddfaeb9 | |||
| c83d4ecbc5 | |||
| d5ec893264 | |||
| a467e67524 | |||
| 271f237eac | |||
| c0c36e8774 | |||
| 857be35efa | |||
| 87f73359ab | |||
| 3ea0099347 | |||
| 8ab026c5aa | |||
| 8e07b4de97 | |||
| 949100545d | |||
| f37ed09777 | |||
| 0bcc0981dc | |||
| 649df26bd4 | |||
| 970822ffee | |||
| 025728729c | |||
| c7d29110b5 | |||
| 0774c11ec2 | |||
| 6cc7565e97 | |||
| 90964afa23 | |||
| 12439b15b9 | |||
| 317f033997 | |||
| 716b4aacff | |||
| 6f8612233f | |||
| e5acb09206 | |||
| d8fac840b0 | |||
| 9bce45a786 | |||
| b8a82cf0fc | |||
| 5090df8358 | |||
| 6ca72a5b83 | |||
| 3a8454b582 | |||
| e25d376080 | |||
| b7a823cf37 | |||
| 504fe4652a | |||
| b8021f467c | |||
| 4d49036e81 | |||
| d738a54cb2 | |||
| c2213d216b | |||
| fd9d728b1e | |||
| 32a3802244 | |||
| c61009b67f | |||
| bb3ce453c4 | |||
| c9fb8fe855 | |||
| 814995214f | |||
| c993c1784b | |||
| 788abb1512 | |||
| 13f7f470e0 | |||
| a835c02e52 | |||
| c46d70ebe2 | |||
| e7d554578d | |||
| 289277aaf0 | |||
| 0671b7ade6 | |||
| f6da8485b5 | |||
| cbd31c51d2 | |||
| 9508351c54 | |||
| 6a7f22bd3e | |||
| 3c06fd6289 | |||
| e31206658d | |||
| 68f46eb5d2 |
@@ -0,0 +1,5 @@
|
||||
src/common/lua.js
|
||||
src/visualizers/widgets/TextEditor/lib/*
|
||||
src/common/js-yaml.min.js
|
||||
src/visualizers/Visualizers.json
|
||||
config/config.webgme.js
|
||||
@@ -0,0 +1,19 @@
|
||||
env:
|
||||
browser: true
|
||||
node: true
|
||||
mocha: true
|
||||
es6: true
|
||||
extends: 'eslint:recommended'
|
||||
rules:
|
||||
indent:
|
||||
- 2
|
||||
- 4
|
||||
linebreak-style:
|
||||
- 2
|
||||
- unix
|
||||
quotes:
|
||||
- 2
|
||||
- single
|
||||
semi:
|
||||
- 2
|
||||
- always
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
src/worker/tmp
|
||||
.env
|
||||
*.swp
|
||||
*.swo
|
||||
**.sass-cache
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
@@ -29,4 +31,5 @@ build/Release
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
tmp/
|
||||
test-tmp/
|
||||
blob-local-storage/
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"esversion": 6
|
||||
}
|
||||
+7
-5
@@ -1,4 +1,4 @@
|
||||
[](https://img.shields.io/badge/state-pre--alpha-red.svg)
|
||||
[](https://img.shields.io/badge/state-alpha-orange.svg)
|
||||
[](./LICENSE)
|
||||
[](https://travis-ci.org/dfst/deepforge)
|
||||
[](https://gitter.im/dfst/deepforge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
@@ -6,14 +6,16 @@
|
||||
# DeepForge
|
||||
DeepForge is an open-source visual development environment for deep learning. Currently, it supports Convolutional Neural Networks but we are planning on supporting additional deep learning classifiers such as RNNs and LSTMs. Additional features include real-time collaborative editing and version control.
|
||||
|
||||
## Quick Setup
|
||||
After cloning the repo, run
|
||||
## Quick Start
|
||||
Simply run the following command to install deepforge with its dependencies:
|
||||
|
||||
```
|
||||
npm install && npm start
|
||||
curl -o- https://raw.githubusercontent.com/dfst/deepforge/master/install.sh | bash
|
||||
```
|
||||
|
||||
Now, navigate to `localhost:8888` in a browser and create a new project. Select `nn` as the seed and start creating your neural nets!
|
||||
Next, follow the postinstall instructions to start MongoDB and DeepForge!
|
||||
|
||||
Finally, navigate to [http://localhost:8888](http://localhost:8888) to start using DeepForge! For more, detailed instructions,check out our [wiki](https://github.com/dfst/deepforge/wiki/Installation-Guide).
|
||||
|
||||
## Caffe Support?
|
||||
DeepForge uses Torch to perform the actual training and testing of the models. If you are interested in DeepForge using Caffe for actual training and testing, check out [DeepForge-Caffe](https://github.com/dfst/deepforge-caffe).
|
||||
|
||||
+7
-3
@@ -8,6 +8,10 @@ var gmeConfig = require('./config'),
|
||||
webgme.addToRequireJsPaths(gmeConfig);
|
||||
|
||||
myServer = new webgme.standaloneServer(gmeConfig);
|
||||
myServer.start(function () {
|
||||
//console.log('server up');
|
||||
});
|
||||
myServer.start(function (err) {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('DeepForge now listening on port', gmeConfig.server.port);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Run `npm start` and listen for 'DeepForge' then start worker
|
||||
var spawn = require('child_process').spawn,
|
||||
stdout = '',
|
||||
execJob,
|
||||
workerJob = null;
|
||||
|
||||
process.env.NODE_ENV = 'local';
|
||||
execJob = spawn('npm', [
|
||||
'start'
|
||||
]);
|
||||
execJob.stdout.pipe(process.stdout);
|
||||
execJob.stderr.pipe(process.stderr);
|
||||
|
||||
execJob.stdout.on('data', function(chunk) {
|
||||
if (!workerJob) {
|
||||
stdout += chunk;
|
||||
if (stdout.indexOf('DeepForge') > -1) {
|
||||
workerJob = spawn('npm', ['run', 'worker']);
|
||||
workerJob.stdout.pipe(process.stdout);
|
||||
workerJob.stderr.pipe(process.stderr);
|
||||
workerJob.on('close', code => code && process.exit(code));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
execJob.on('close', code => code && process.exit(code));
|
||||
+13
-3
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
/*globals process, __dirname, require*/
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs'),
|
||||
spawn = require('child_process').spawn,
|
||||
childProcess = require('child_process'),
|
||||
spawn = childProcess.spawn,
|
||||
projectConfig = require(__dirname + '/../config'),
|
||||
executorSrc = path.join(__dirname, '..', 'node_modules', 'webgme', 'src',
|
||||
'server', 'middleware', 'executor', 'worker'),
|
||||
@@ -12,13 +13,22 @@ var path = require('path'),
|
||||
address,
|
||||
config = {};
|
||||
|
||||
// Check torch support
|
||||
var result = childProcess.spawnSync('th', ['--help']);
|
||||
if (result.error) {
|
||||
console.error('Checking Torch7 dependency failed. Do you have Torch7 installed ' +
|
||||
'and in your PATH?\n\nFor Torch7 installation instructions, check out ' +
|
||||
'http://torch.ch/docs/getting-started.html');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var startExecutor = function() {
|
||||
// Start the executor
|
||||
var execJob = spawn('node', [
|
||||
'node_worker.js',
|
||||
workerConfigPath,
|
||||
workerTmp
|
||||
]);
|
||||
]);
|
||||
execJob.stdout.pipe(process.stdout);
|
||||
execJob.stderr.pipe(process.stderr);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
{
|
||||
"ArchEditor": {
|
||||
"hotkeys": "none",
|
||||
"LayerColors": {}
|
||||
"LayerColors": {}
|
||||
},
|
||||
"FloatingActionButton": {
|
||||
"hideOnEmpty": true
|
||||
},
|
||||
"GenericUIProjectNavigatorController": {
|
||||
"rootMenuClass": "deepforge-logo",
|
||||
"rootDisplayName": "DeepForge"
|
||||
},
|
||||
"CHFLayout": {
|
||||
"panels": [
|
||||
@@ -13,7 +20,7 @@
|
||||
},
|
||||
{
|
||||
"id": "Footer",
|
||||
"panel": "FooterControls/FooterControlsPanel",
|
||||
"panel": "Footer/FooterPanel",
|
||||
"container": "footer",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
@@ -31,5 +38,54 @@
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
"RootViz": {
|
||||
"nodes": [
|
||||
{
|
||||
"nodeName": "MyArchitectures",
|
||||
"icon": "shuffle",
|
||||
"rank": 1,
|
||||
"description": "Neural network architectures are stored here and can be used in pipelines."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyOperations",
|
||||
"icon": "mode_edit",
|
||||
"rank": 2,
|
||||
"color": "blue-grey",
|
||||
"description": "Operations are the building blocks of pipelines. Custom operations can be created and stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyPipelines",
|
||||
"icon": "input",
|
||||
"rank": 3,
|
||||
"description": "Pipelines compose operations together to effectively train, test and/or ensemble models."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyLayers",
|
||||
"icon": "clear_all",
|
||||
"rank": 4,
|
||||
"color": "blue-grey",
|
||||
"description": "Custom torch layers can be created and stored here for use in neural network architectures."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyArtifacts",
|
||||
"icon": "view_quilt",
|
||||
"rank": 5,
|
||||
"description": "Artifacts from pipeline executions are stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyExecutions",
|
||||
"icon": "list",
|
||||
"rank": 6,
|
||||
"color": "blue-grey",
|
||||
"description": "Executions are read-only snapshots of pipelines that have been executed. Past and current executing pipelines are stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyDataTypes",
|
||||
"icon": "settings",
|
||||
"rank": 7,
|
||||
"description": "Custom defined data types are stored here."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+11
-3
@@ -1,15 +1,23 @@
|
||||
/*globals require, module, process*/
|
||||
'use strict';
|
||||
|
||||
var config = require('./config.webgme'),
|
||||
validateConfig = require('webgme/config/validator');
|
||||
|
||||
require('dotenv').load({silent: true});
|
||||
|
||||
// Add/overwrite any additional settings here
|
||||
// config.server.port = 8080;
|
||||
// config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_my_app';
|
||||
config.server.port = process.env.PORT || config.server.port;
|
||||
config.mongo.uri = process.env.MONGO_URI || config.mongo.uri;
|
||||
config.requirejsPaths.deepforge = './src/common';
|
||||
config.seedProjects.defaultProject = 'nn';
|
||||
config.seedProjects.defaultProject = 'project';
|
||||
|
||||
config.plugin.allowBrowserExecution = true;
|
||||
config.plugin.allowServerExecution = true;
|
||||
|
||||
config.executor.enable = true;
|
||||
|
||||
config.visualization.extraCss.push('deepforge/styles/global.css');
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
|
||||
@@ -9,8 +9,7 @@ var config = require('./config.base'),
|
||||
// config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_my_app';
|
||||
|
||||
// Seeds for development are prefixed with 'dev'
|
||||
config.seedProjects.basePaths = config.seedProjects.basePaths
|
||||
.filter(path => path.indexOf('dev') === -1);
|
||||
config.seedProjects.basePaths = ['src/seeds/project'];
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Config for running deepforge w/ one local worker
|
||||
// jshint node: true
|
||||
'use strict';
|
||||
|
||||
var config = require('./config.default'),
|
||||
validateConfig = require('webgme/config/validator');
|
||||
|
||||
// Turn up the worker polling rate
|
||||
config.executor.workerRefreshInterval = 150;
|
||||
config.executor.clearOldDataAtStartUp = true,
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
@@ -11,14 +11,15 @@ var config = require('webgme/config/config.default'),
|
||||
config.plugin.basePaths.push('src/plugins');
|
||||
config.plugin.basePaths.push('node_modules/webgme-simple-nodes/src/plugins');
|
||||
config.visualization.layout.basePaths.push('node_modules/webgme-chflayout/src/layouts');
|
||||
config.visualization.decoratorPaths.push('src/decorators');
|
||||
config.visualization.decoratorPaths.push('node_modules/webgme-easydag/src/decorators');
|
||||
config.seedProjects.basePaths.push('src/seeds/nn');
|
||||
config.seedProjects.basePaths.push('src/seeds/devTests');
|
||||
config.seedProjects.basePaths.push('src/seeds/devMinimal');
|
||||
config.seedProjects.basePaths.push('src/seeds/devUtilTests');
|
||||
config.seedProjects.basePaths.push('src/seeds/pipeline');
|
||||
config.seedProjects.basePaths.push('src/seeds/devPipelineTests');
|
||||
config.seedProjects.basePaths.push('src/seeds/demo');
|
||||
config.seedProjects.basePaths.push('src/seeds/project');
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# Things to install:
|
||||
# - nvm
|
||||
|
||||
command -v git >/dev/null 2>&1 || { echo >&2 "I require git but it's not installed. Aborting."; exit 1; }
|
||||
|
||||
echo >&2 "Checking DeepForge dependencies...";
|
||||
command -v th >/dev/null 2>&1 || {
|
||||
# No torch!
|
||||
echo >&2 "Torch is not found. Installing...";
|
||||
git clone https://github.com/torch/distro.git ~/torch --recursive;
|
||||
cd ~/torch; bash install-deps;
|
||||
./install.sh;
|
||||
}
|
||||
|
||||
# profile (bash, zsh, profile, etc) borrowed from nvm's installer
|
||||
detect_profile() {
|
||||
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
|
||||
echo "$PROFILE"
|
||||
return
|
||||
fi
|
||||
|
||||
DETECTED_PROFILE=''
|
||||
local SHELLTYPE
|
||||
SHELLTYPE="$(basename "/$SHELL")"
|
||||
|
||||
if [ "$SHELLTYPE" = "bash" ]; then
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bashrc"
|
||||
elif [ -f "$HOME/.bash_profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bash_profile"
|
||||
fi
|
||||
elif [ "$SHELLTYPE" = "zsh" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zshrc"
|
||||
fi
|
||||
|
||||
if [ -z "$DETECTED_PROFILE" ]; then
|
||||
if [ -f "$HOME/.profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.profile"
|
||||
elif [ -f "$HOME/.bashrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bashrc"
|
||||
elif [ -f "$HOME/.bash_profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bash_profile"
|
||||
elif [ -f "$HOME/.zshrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zshrc"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
detect_profile
|
||||
|
||||
command -v node >/dev/null 2>&1 || {
|
||||
# No node! Install nvm
|
||||
echo >&2 "NodeJS is not found. Installing (using nvm)...";
|
||||
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash;
|
||||
source $DETECTED_PROFILE
|
||||
|
||||
# Install nodejs v6.2.0
|
||||
echo "Installing nodejs v6.2.0"
|
||||
nvm install v6.2.0
|
||||
nvm alias default v6.2.0
|
||||
|
||||
# Install npm@2
|
||||
npm install npm@2 -g
|
||||
|
||||
}
|
||||
|
||||
command -v node >/dev/null 2>&1 || {
|
||||
# No mongod!
|
||||
echo >&2 "MongoDB is not found. Installing...";
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
brew install mongodb
|
||||
fi
|
||||
}
|
||||
|
||||
echo >&2 "Installing DeepForge...";
|
||||
|
||||
# Clone deepforge into ~/deepforge
|
||||
git clone https://github.com/dfst/deepforge ~/deepforge
|
||||
cd ~/deepforge
|
||||
npm install
|
||||
|
||||
mkdir ~/deepforge/data 2> /dev/null
|
||||
echo "DeepForge is installed! To run it:"
|
||||
echo " 1) make sure MongoDB is running locally"
|
||||
echo " (start mongo w/ \"mongod --dbpath ~/deepforge/data\")"
|
||||
echo " 2) Run \"npm run local\" from ~/deepforge"
|
||||
+9
-4
@@ -3,18 +3,23 @@
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
"start-dev": "NODE_ENV=dev node app.js",
|
||||
"local": "node ./bin/start-local.js",
|
||||
"worker": "node ./bin/start-worker.js",
|
||||
"test": "node ./node_modules/mocha/bin/mocha --recursive test"
|
||||
"test": "node ./node_modules/mocha/bin/mocha --recursive test",
|
||||
"watch-test": "./node_modules/nodemon/bin/nodemon.js --exec 'node ./node_modules/mocha/bin/mocha --recursive test'",
|
||||
"build-nn": "node ./utils/nn-parser.js"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"version": "0.6.0",
|
||||
"dependencies": {
|
||||
"dotenv": "^2.0.0",
|
||||
"lodash.difference": "^4.1.2",
|
||||
"nodemon": "^1.9.2",
|
||||
"webgme": "^2.0.0",
|
||||
"webgme-autoviz": "^2.0.0",
|
||||
"webgme-autoviz": "^2.0.3",
|
||||
"webgme-breadcrumbheader": "^2.0.0",
|
||||
"webgme-chflayout": "^2.0.0",
|
||||
"webgme-easydag": "dfst/webgme-easydag",
|
||||
"webgme-fab": "^2.0.0",
|
||||
"webgme-fab": "dfst/webgme-fab",
|
||||
"webgme-simple-nodes": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* globals define */
|
||||
define([
|
||||
'deepforge/js-yaml.min'
|
||||
], function(
|
||||
@@ -148,28 +149,11 @@ define([
|
||||
|
||||
GraphChecker.prototype = new Importer();
|
||||
|
||||
// Check if two models are isomorphic
|
||||
var modelMatches = function(gmeNodes, text) {
|
||||
var nodes = convertNodes(gmeNodes),
|
||||
soln = yaml.load(text);
|
||||
|
||||
nodes.concat(soln).forEach(node => {
|
||||
node.next = node.next || [];
|
||||
node.attributes = node.attributes || {};
|
||||
});
|
||||
|
||||
return _modelMatches(nodes, soln);
|
||||
};
|
||||
|
||||
//////////////// Operators ////////////////
|
||||
// Check if two models are isomorphic
|
||||
var _modelMatches = function(soln, nodes) {
|
||||
var nodeMap = createMap(nodes),
|
||||
solnMap = createMap(soln),
|
||||
sInits, // soln start nodes
|
||||
nInits, // 'nodes' start nodes
|
||||
resMap = {}, // soln node id to node id
|
||||
solnIds = soln.map(n => n.id),
|
||||
nodeIds = nodes.map(n => n.id);
|
||||
solnMap = createMap(soln);
|
||||
|
||||
if (nodes.length !== soln.length) {
|
||||
return false;
|
||||
@@ -187,8 +171,7 @@ define([
|
||||
};
|
||||
|
||||
var getMostConstrained = function(soln, nodes) {
|
||||
var options = soln.map(sn => [sn, nodes.filter(n => nodesMatch(sn, n))]),
|
||||
startId;
|
||||
var options = soln.map(sn => [sn, nodes.filter(n => nodesMatch(sn, n))]);
|
||||
|
||||
options.sort((a, b) => b[1].length < a[1].length);
|
||||
return options[0];
|
||||
@@ -199,8 +182,7 @@ define([
|
||||
nodes = Object.keys(nodeMap).map(id => nodeMap[id]),
|
||||
snode = solnMap[id],
|
||||
options,
|
||||
used,
|
||||
node;
|
||||
used;
|
||||
|
||||
mappings = mappings || {};
|
||||
|
||||
@@ -247,14 +229,16 @@ define([
|
||||
snext.push(startId);
|
||||
}
|
||||
|
||||
var inferNext = (prev, curr) => {
|
||||
mappings2 = inferGraph(curr, solnMap, nodeMap, mappings2);
|
||||
return prev && mappings;
|
||||
};
|
||||
|
||||
for (var i = options.length; i--;) {
|
||||
mappings[id] = options[i].id; // need to clone the object
|
||||
|
||||
mappings2 = clone(mappings);
|
||||
result = snext.reduce((prev, curr) => {
|
||||
mappings2 = inferGraph(curr, solnMap, nodeMap, mappings2);
|
||||
return prev && mappings;
|
||||
}, true);
|
||||
result = snext.reduce(inferNext, true);
|
||||
|
||||
if (result) {
|
||||
return mappings2;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* globals define*/
|
||||
define([
|
||||
], function(
|
||||
) {
|
||||
@@ -25,7 +26,6 @@ define([
|
||||
var createLayerDict = function(core, meta) {
|
||||
var node,
|
||||
names = Object.keys(meta),
|
||||
attributes,
|
||||
layers = {};
|
||||
|
||||
for (var i = names.length; i--;) {
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,48 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
define([
|
||||
'q'
|
||||
], function(
|
||||
Q
|
||||
) {
|
||||
var PtrCodeGen = function() {
|
||||
};
|
||||
|
||||
PtrCodeGen.prototype.getPtrCodeHash = function(ptrId) {
|
||||
return this.core.loadByPath(this.rootNode, ptrId)
|
||||
.then(ptrNode => {
|
||||
// Look up the plugin to use
|
||||
var metanode = this.core.getMetaType(ptrNode),
|
||||
pluginId;
|
||||
|
||||
pluginId = this.core.getRegistry(ptrNode, 'validPlugins').split(' ').shift();
|
||||
this.logger.info(`generating code for ${this.core.getAttribute(ptrNode, 'name')} using ${pluginId}`);
|
||||
|
||||
var context = WebGMEGlobal.Client.getCurrentPluginContext(pluginId);
|
||||
|
||||
context.managerConfig.namespace = this.core.getNamespace(metanode);
|
||||
context.managerConfig.activeNode = this.core.getPath(ptrNode);
|
||||
|
||||
// Load and run the plugin
|
||||
return Q.nfcall(this.executePlugin.bind(this), pluginId, context);
|
||||
})
|
||||
.then(hashes => hashes[0]); // Grab the first asset for now
|
||||
};
|
||||
|
||||
PtrCodeGen.prototype.executePlugin = function(pluginId, config, callback) {
|
||||
// Call the Interpreter manager in a Q.ninvoke friendly way
|
||||
// I need to create a custom context for the given plugin:
|
||||
// - Set the activeNode to the given referenced node
|
||||
// - If the activeNode is namespaced, set META to the given namespace
|
||||
//
|
||||
// FIXME: Check if it is running in the browser or on the server
|
||||
WebGMEGlobal.Client.runBrowserPlugin(pluginId, config, (err, result) => {
|
||||
if (!result.success) {
|
||||
return callback(result.getError());
|
||||
}
|
||||
this.logger.info('Finished calling ' + pluginId);
|
||||
callback(null, result.artifacts);
|
||||
});
|
||||
};
|
||||
|
||||
return PtrCodeGen;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Audiowide';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/7pSgz2MbVvTCvvm7vukSHxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Audiowide';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/8XtYtNKEyyZh481XVWfVOltXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
.deepforge-logo .item-label {
|
||||
font-family: 'Audiowide', cursive;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/* globals define */
|
||||
// A mixin containing helpers for working with operations
|
||||
define([
|
||||
], function(
|
||||
) {
|
||||
'use strict';
|
||||
var OperationControl = function() {
|
||||
};
|
||||
|
||||
OperationControl.prototype.hasMetaName = function(id, name) {
|
||||
var node = this._client.getNode(id),
|
||||
bId = node.getBaseId(),
|
||||
baseName;
|
||||
|
||||
while (bId) {
|
||||
node = this._client.getNode(bId);
|
||||
baseName = node.getAttribute('name');
|
||||
if (baseName === name) {
|
||||
return true;
|
||||
}
|
||||
bId = node.getBaseId();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
OperationControl.prototype.getOperationInputs = function(node) {
|
||||
return this.getOperationData(node, 'Inputs');
|
||||
};
|
||||
|
||||
OperationControl.prototype.getOperationOutputs = function(node) {
|
||||
return this.getOperationData(node, 'Outputs');
|
||||
};
|
||||
|
||||
OperationControl.prototype.getOperationData = function(node, type) {
|
||||
var childrenIds = node.getChildrenIds(),
|
||||
typeId = childrenIds.find(cId => this.hasMetaName(cId, type));
|
||||
|
||||
return typeId ? this._client.getNode(typeId).getChildrenIds() : [];
|
||||
};
|
||||
|
||||
return OperationControl;
|
||||
});
|
||||
@@ -0,0 +1,141 @@
|
||||
/* globals define */
|
||||
// Shared methods for editing pipelines
|
||||
define([
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'deepforge/viz/OperationControl',
|
||||
'widgets/EasyDAG/AddNodeDialog',
|
||||
'underscore'
|
||||
], function(
|
||||
EasyDAGControl,
|
||||
OperationControl,
|
||||
AddNodeDialog,
|
||||
_
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var PipelineControl = function() {
|
||||
};
|
||||
|
||||
_.extend(PipelineControl.prototype, OperationControl.prototype);
|
||||
|
||||
PipelineControl.prototype.DEFAULT_DECORATOR = 'OperationDecorator';
|
||||
|
||||
PipelineControl.prototype._getAllDescendentIds =
|
||||
EasyDAGControl.prototype._getAllDescendentIds;
|
||||
PipelineControl.prototype._getAllValidChildren =
|
||||
EasyDAGControl.prototype._getAllValidChildren;
|
||||
PipelineControl.prototype._getNodeDecorator =
|
||||
EasyDAGControl.prototype._getNodeDecorator;
|
||||
|
||||
PipelineControl.prototype.onCreateInitialNode = function() {
|
||||
var initialNodes = this.getValidInitialNodes(),
|
||||
initialNode = initialNodes[0];
|
||||
|
||||
if (initialNodes.length > 1) {
|
||||
// Create the modal view with all possible subsequent nodes
|
||||
var dialog = new AddNodeDialog();
|
||||
|
||||
dialog.show(null, initialNodes.map(node => {
|
||||
return {node};
|
||||
}));
|
||||
dialog.onSelect = nodeInfo => {
|
||||
if (nodeInfo) {
|
||||
this.createNode(nodeInfo.node.id);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
this.createNode(initialNode.id);
|
||||
}
|
||||
};
|
||||
|
||||
PipelineControl.prototype.getValidInitialNodes = function () {
|
||||
// Get all nodes that have no inputs
|
||||
return this._getAllValidChildren(this._currentNodeId)
|
||||
.map(id => this._client.getNode(id))
|
||||
.filter(node => !node.isAbstract() && !node.isConnection())
|
||||
// Checking the name (below) is simply convenience so we can
|
||||
// still create operation prototypes from Operation (which we
|
||||
// wouldn't be able to do if it was abstract - which it probably
|
||||
// should be)
|
||||
.filter(node => node.getAttribute('name') !== 'Operation')
|
||||
.map(node => this._getObjectDescriptor(node.getId()));
|
||||
};
|
||||
|
||||
PipelineControl.prototype.createNode = function(baseId) {
|
||||
var parentId = this._currentNodeId,
|
||||
newNodeId = this._client.createChild({parentId, baseId});
|
||||
|
||||
return newNodeId;
|
||||
};
|
||||
|
||||
PipelineControl.prototype._getObjectDescriptor = function(id) {
|
||||
var desc = EasyDAGControl.prototype._getObjectDescriptor.call(this, id),
|
||||
node = this._client.getNode(id);
|
||||
|
||||
if (this.hasMetaName(id, 'Operation')) {
|
||||
// Only decorate operations in the currently active node
|
||||
if (this._currentNodeId !== desc.parentId) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
// Add inputs and outputs
|
||||
var childrenIds = node.getChildrenIds(),
|
||||
inputId = childrenIds.find(cId => this.hasMetaName(cId, 'Inputs')),
|
||||
outputId = childrenIds.find(cId => this.hasMetaName(cId, 'Outputs')),
|
||||
inputs,
|
||||
outputs;
|
||||
|
||||
inputs = inputId ? this._client.getNode(inputId).getChildrenIds() : [];
|
||||
outputs = outputId ? this._client.getNode(outputId).getChildrenIds() : [];
|
||||
|
||||
// Add the inputs, outputs in the form:
|
||||
// [ name, baseId ]
|
||||
desc.inputs = inputs.map(id => this.formatIO(id));
|
||||
desc.outputs = outputs.map(id => this.formatIO(id));
|
||||
|
||||
// Remove the 'code' attribute
|
||||
if (desc.attributes.code) {
|
||||
delete desc.attributes.code;
|
||||
}
|
||||
|
||||
} else if (desc.isConnection) {
|
||||
// Set src, dst to siblings and add srcPort, dstPort
|
||||
desc.srcPort = desc.src;
|
||||
desc.dstPort = desc.dst;
|
||||
|
||||
// Get the src/dst that are in the currentNode
|
||||
desc.src = this.getSiblingContaining(desc.src);
|
||||
desc.dst = this.getSiblingContaining(desc.dst);
|
||||
|
||||
if (desc.src === null || desc.dst === null) {
|
||||
this._logger.warn(`Could not get src/dst for ${desc.id}`);
|
||||
}
|
||||
} else if (this.hasMetaName(desc.id, 'Data')) { // port
|
||||
// Add nodeId for container
|
||||
desc.nodeId = this.getSiblingContaining(desc.id);
|
||||
// It is a data port if it has a parentId and the parent is either
|
||||
// 'Inputs' or 'Outputs'
|
||||
desc.isDataPort = desc.parentId &&
|
||||
(this.hasMetaName(desc.parentId, 'Inputs') || this.hasMetaName(desc.parentId, 'Outputs'));
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
PipelineControl.prototype.getSiblingContaining = function(containedId) {
|
||||
var n = this._client.getNode(containedId);
|
||||
while (n && n.getParentId() !== this._currentNodeId) {
|
||||
n = this._client.getNode(n.getParentId());
|
||||
}
|
||||
return n && n.getId();
|
||||
};
|
||||
|
||||
PipelineControl.prototype.formatIO = function(id) {
|
||||
var node = this._client.getNode(id);
|
||||
return {
|
||||
id: id,
|
||||
name: node.getAttribute('name')
|
||||
};
|
||||
};
|
||||
|
||||
return PipelineControl;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/ArtifactOpDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
ArtifactOpDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ArtifactOpDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'ArtifactOpDecorator';
|
||||
|
||||
ArtifactOpDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('ArtifactOpDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(ArtifactOpDecorator.prototype, __parent_proto__);
|
||||
ArtifactOpDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
ArtifactOpDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: ArtifactOpDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return ArtifactOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.artifactop-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.artifactop-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.artifactop-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.artifactop-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.artifactop-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.artifactop-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.artifactop-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .artifactop-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,102 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'decorators/DcOpDecorator/EasyDAG/DcOpDecorator.EasyDAGWidget',
|
||||
'css!./ArtifactOpDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ArtifactOpDecorator,
|
||||
DECORATOR_ID = 'ArtifactOpDecorator',
|
||||
CAST_OPTS = {
|
||||
ArtifactLoader: {
|
||||
ptr: 'artifact',
|
||||
metaTgt: false
|
||||
},
|
||||
ArtifactFinder: {
|
||||
ptr: 'type',
|
||||
metaTgt: true
|
||||
}
|
||||
};
|
||||
|
||||
// ArtifactOp nodes need to be able to...
|
||||
// - dynamically change their outputs (downcast)
|
||||
ArtifactOpDecorator = function (options) {
|
||||
options.color = options.color || '#b0bec5';
|
||||
DecoratorBase.call(this, options);
|
||||
// set the opts...
|
||||
this.castOpts = CAST_OPTS[this._node.baseName];
|
||||
};
|
||||
|
||||
_.extend(ArtifactOpDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
ArtifactOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
ArtifactOpDecorator.prototype.getTargetFilterFnFor = function() {
|
||||
return id => {
|
||||
var node = this.client.getNode(id),
|
||||
isMetaTgt = node.getId() === node.getMetaTypeId();
|
||||
return isMetaTgt === this.castOpts.metaTgt;
|
||||
};
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.savePointer = function(name, to) {
|
||||
// When the 'artifact' pointer is changed, we should change the base
|
||||
// of the data output node to the target type
|
||||
if (name === this.castOpts.ptr && (typeof to === 'string')) {
|
||||
this.client.startTransaction(`Setting output of ${this.name} to ${to}`);
|
||||
this.castOutputType(to);
|
||||
this.client.makePointer(this._node.id, name, to);
|
||||
this.client.completeTransaction();
|
||||
} else {
|
||||
DecoratorBase.prototype.savePointer.call(this, name, to);
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.getDisplayName = function() {
|
||||
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type',
|
||||
id = this._node.pointers[ptrName],
|
||||
name = this.nameFor[id] || this._node.name;
|
||||
return name;
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.updateDisplayName = function() {
|
||||
var newName = this.getDisplayName();
|
||||
if (this.name !== newName) {
|
||||
this.name = newName;
|
||||
this.nameWidth = null;
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.updateTargetName = function(id, name) {
|
||||
DecoratorBase.prototype.updateTargetName.apply(this, arguments);
|
||||
// Update name
|
||||
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type';
|
||||
if (this._node.pointers[ptrName] === id) {
|
||||
this._name = name;
|
||||
this.onResize();
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.expand = function() {
|
||||
this.updateDisplayName();
|
||||
DecoratorBase.prototype.expand.call(this);
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.condense = function() {
|
||||
this.updateDisplayName();
|
||||
DecoratorBase.prototype.condense.call(this);
|
||||
};
|
||||
|
||||
return ArtifactOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/DcOpDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
DcOpDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var DcOpDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'DcOpDecorator';
|
||||
|
||||
DcOpDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('DcOpDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(DcOpDecorator.prototype, __parent_proto__);
|
||||
DcOpDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
DcOpDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: DcOpDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return DcOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.dcop-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.dcop-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.dcop-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.dcop-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.dcop-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.dcop-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.dcop-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .dcop-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,79 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'decorators/OperationDecorator/EasyDAG/OperationDecorator.EasyDAGWidget',
|
||||
'css!./DcOpDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var DcOpDecorator,
|
||||
DECORATOR_ID = 'DcOpDecorator';
|
||||
|
||||
// DcOp nodes need to be able to...
|
||||
// - dynamically change their outputs (downcast)
|
||||
DcOpDecorator = function (options) {
|
||||
options.color = options.color || '#78909c';
|
||||
DecoratorBase.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(DcOpDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
DcOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
DcOpDecorator.prototype.getTargetFilterFnFor = function() {
|
||||
return id => {
|
||||
var node = this.client.getNode(id);
|
||||
return node.getId() !== node.getMetaTypeId(); // not meta node
|
||||
};
|
||||
};
|
||||
|
||||
DcOpDecorator.prototype.castOutputType = function(targetId) {
|
||||
var target = this.client.getNode(targetId),
|
||||
baseId = target.getBaseId(),
|
||||
outputId = this._node.outputs[0] && this._node.outputs[0].id,
|
||||
hash;
|
||||
|
||||
if (!outputId) {
|
||||
// create the outputId node
|
||||
outputId = this._createOutputNode(baseId);
|
||||
} else {
|
||||
this.client.makePointer(outputId, CONSTANTS.POINTER_BASE, baseId);
|
||||
}
|
||||
// Copy the data content to the output node
|
||||
hash = target.getAttribute('data');
|
||||
this.client.setAttributes(outputId, 'data', hash);
|
||||
};
|
||||
|
||||
DcOpDecorator.prototype._createOutputNode = function(baseId) {
|
||||
var n = this.client.getNode(this._node.id),
|
||||
outputCntrId;
|
||||
|
||||
outputCntrId = n.getChildrenIds().find(id => {
|
||||
var metaTypeId = this.client.getNode(id).getMetaTypeId(),
|
||||
metaType = this.client.getNode(metaTypeId);
|
||||
|
||||
if (!metaType) {
|
||||
this.logger.error(`Could not check the type of ${id}!`);
|
||||
return false;
|
||||
}
|
||||
return metaType.getAttribute('name') === 'Outputs';
|
||||
});
|
||||
|
||||
return this.client.createChild({
|
||||
baseId: baseId,
|
||||
parentId: outputCntrId
|
||||
});
|
||||
};
|
||||
|
||||
return DcOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.job-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.job-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.job-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.job-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.job-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.job-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.job-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .job-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,60 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'decorators/EllipseDecorator/EasyDAG/EllipseDecorator.EasyDAGWidget',
|
||||
'css!./JobDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
EllipseDecorator
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var JobDecorator,
|
||||
DECORATOR_ID = 'JobDecorator',
|
||||
COLORS = {
|
||||
pending: '#9e9e9e',
|
||||
running: '#fff59d',
|
||||
success: '#66bb6a',
|
||||
fail: '#e57373'
|
||||
};
|
||||
|
||||
// Job nodes need to be able to...
|
||||
// - show their ports
|
||||
// - highlight ports
|
||||
// - unhighlight ports
|
||||
// - report the location of specific ports
|
||||
JobDecorator = function (options) {
|
||||
options.skipAttributes = {
|
||||
name: true,
|
||||
status: true,
|
||||
execFiles: true,
|
||||
stdout: true,
|
||||
debug: true
|
||||
};
|
||||
EllipseDecorator.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(JobDecorator.prototype, EllipseDecorator.prototype);
|
||||
|
||||
JobDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
JobDecorator.prototype.getDisplayName = function() {
|
||||
return this._node.name;
|
||||
};
|
||||
|
||||
JobDecorator.prototype.setAttributes = function() {
|
||||
EllipseDecorator.prototype.setAttributes.call(this);
|
||||
var attrs = this._node.attributes,
|
||||
status = attrs.status && attrs.status.value;
|
||||
|
||||
// Update the color based on the 'status' attr
|
||||
this.color = COLORS[status] || COLORS.fail;
|
||||
};
|
||||
|
||||
return JobDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/JobDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
JobDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var JobDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'JobDecorator';
|
||||
|
||||
JobDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('JobDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(JobDecorator.prototype, __parent_proto__);
|
||||
JobDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
JobDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: JobDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return JobDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.op-int-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.op-int-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.op-int-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.op-int-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.op-int-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.op-int-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.op-int-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .op-int-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,90 @@
|
||||
/*globals define, $,_*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'decorators/EllipseDecorator/EasyDAG/EllipseDecorator.EasyDAGWidget',
|
||||
'css!./OpIntDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OpIntDecorator,
|
||||
DECORATOR_ID = 'OpIntDecorator';
|
||||
|
||||
// OpInt nodes need to be able to...
|
||||
// - show their ports
|
||||
// - highlight ports
|
||||
// - unhighlight ports
|
||||
// - report the location of specific ports
|
||||
OpIntDecorator = function (options) {
|
||||
this.color = this.color || '#78909c';
|
||||
DecoratorBase.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(OpIntDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
OpIntDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
OpIntDecorator.prototype.initialize = function() {
|
||||
if (this._node.baseName === 'Operation') {
|
||||
this.color = '#2196f3';
|
||||
} else {
|
||||
// On hover, show the type
|
||||
this.enableTooltip(this._node.baseName, 'dark');
|
||||
}
|
||||
DecoratorBase.prototype.initialize.call(this);
|
||||
this.$name.on('dblclick', this.editName.bind(this));
|
||||
};
|
||||
|
||||
OpIntDecorator.prototype.editName = function() {
|
||||
var html = this.$name[0][0],
|
||||
position = html.getBoundingClientRect(),
|
||||
|
||||
width = Math.max(position.right-position.left, 15),
|
||||
container = $('<div>'),
|
||||
parentHtml = $('body');
|
||||
|
||||
// foreignObject was not working so we are using a tmp container
|
||||
// instead
|
||||
container.css('top', position.top);
|
||||
container.css('left', position.left);
|
||||
container.css('position', 'absolute');
|
||||
container.css('width', width);
|
||||
container.attr('id', 'CONTAINER-TMP');
|
||||
|
||||
$(parentHtml).append(container);
|
||||
|
||||
container.editInPlace({
|
||||
enableEmpty: true,
|
||||
value: this.name,
|
||||
css: {
|
||||
'z-index': 10000,
|
||||
'id': 'asdf',
|
||||
'width': width,
|
||||
'xmlns': 'http://www.w3.org/1999/xhtml'
|
||||
},
|
||||
onChange: this.onNameChanged.bind(this),
|
||||
onFinish: function () {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
OpIntDecorator.prototype.onNameChanged = function(oldVal, newValue) {
|
||||
this.saveAttribute('name', newValue);
|
||||
};
|
||||
|
||||
OpIntDecorator.prototype.getDisplayName = function() {
|
||||
return this._node.name;
|
||||
};
|
||||
|
||||
// clicking on the name should allow the user to edit it in place
|
||||
// TODO
|
||||
|
||||
return OpIntDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/OpIntDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
OpIntDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OpIntDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'OpIntDecorator';
|
||||
|
||||
OpIntDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('OpIntDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(OpIntDecorator.prototype, __parent_proto__);
|
||||
OpIntDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
OpIntDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: OpIntDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return OpIntDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.op-int-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.op-int-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.op-int-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.op-int-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.op-int-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.op-int-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.op-int-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .op-int-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,39 @@
|
||||
/*globals define, $,_*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'decorators/OpIntDecorator/EasyDAG/OpIntDecorator.EasyDAGWidget',
|
||||
'css!./OpIntPtrDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OpIntPtrDecorator,
|
||||
DECORATOR_ID = 'OpIntPtrDecorator';
|
||||
|
||||
// OpInt nodes need to be able to...
|
||||
// - show their ports
|
||||
// - highlight ports
|
||||
// - unhighlight ports
|
||||
// - report the location of specific ports
|
||||
OpIntPtrDecorator = function (options) {
|
||||
this.color = '#80deea';
|
||||
DecoratorBase.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(OpIntPtrDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
OpIntPtrDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
OpIntPtrDecorator.prototype.onNameChanged = function(old, newValue) {
|
||||
return this.changePtrName(this.name, newValue);
|
||||
};
|
||||
|
||||
return OpIntPtrDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/OpIntPtrDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
OpIntPtrDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OpIntPtrDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'OpIntPtrDecorator';
|
||||
|
||||
OpIntPtrDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('OpIntPtrDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(OpIntPtrDecorator.prototype, __parent_proto__);
|
||||
OpIntPtrDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
OpIntPtrDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: OpIntPtrDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return OpIntPtrDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.operation-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.operation-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.operation-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.operation-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.operation-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.operation-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.operation-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .operation-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,176 @@
|
||||
/*globals define, _, Opentip*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'decorators/EllipseDecorator/EasyDAG/EllipseDecorator.EasyDAGWidget',
|
||||
'css!./OperationDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OperationDecorator,
|
||||
NAME_MARGIN = 25,
|
||||
DECORATOR_ID = 'OperationDecorator',
|
||||
PORT_TOOLTIP_OPTS = {
|
||||
tipJoint: 'left',
|
||||
removeElementsOnHide: true,
|
||||
style: 'dark'
|
||||
};
|
||||
|
||||
// Operation nodes need to be able to...
|
||||
// - show their ports
|
||||
// - highlight ports
|
||||
// - unhighlight ports
|
||||
// - report the location of specific ports
|
||||
OperationDecorator = function (options) {
|
||||
options.color = options.color || '#78909c';
|
||||
DecoratorBase.call(this, options);
|
||||
|
||||
this.id = this._node.id;
|
||||
this.$ports = this.$el.append('g')
|
||||
.attr('id', 'ports');
|
||||
this.$portTooltips = {};
|
||||
};
|
||||
|
||||
_.extend(OperationDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
OperationDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
OperationDecorator.prototype.PORT_COLOR = {
|
||||
OPEN: '#90caf9',
|
||||
OCCUPIED: '#e57373'
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.condense = function() {
|
||||
var path,
|
||||
width,
|
||||
rx;
|
||||
|
||||
width = Math.max(this.nameWidth + 2 * NAME_MARGIN, this.dense.width);
|
||||
rx = width/2;
|
||||
|
||||
path = [
|
||||
`M${-rx},0`,
|
||||
`l ${width} 0`,
|
||||
`l 0 ${this.dense.height}`,
|
||||
`l -${width} 0`,
|
||||
`l 0 -${this.dense.height}`
|
||||
].join(' ');
|
||||
|
||||
|
||||
this.$body
|
||||
.attr('d', path);
|
||||
|
||||
// Clear the attributes
|
||||
this.$attributes.remove();
|
||||
this.$attributes = this.$el.append('g')
|
||||
.attr('fill', '#222222');
|
||||
|
||||
this.height = this.dense.height;
|
||||
this.width = width;
|
||||
|
||||
this.$name.attr('y', this.height/2);
|
||||
|
||||
this.$el
|
||||
.attr('transform', `translate(${this.width/2}, 0)`);
|
||||
this.expanded = false;
|
||||
this.onResize();
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.showPorts = function(ids, areInputs) {
|
||||
var allPorts = areInputs ? this._node.inputs : this._node.outputs,
|
||||
ports = ids ? allPorts.filter(port => ids.indexOf(port.id) > -1) : allPorts,
|
||||
x = -this.width/2,
|
||||
dx = this.width/(ports.length+1),
|
||||
y = areInputs ? 0 : this.height; // (this.height/2);
|
||||
|
||||
ports.forEach(port => {
|
||||
x += dx;
|
||||
this.renderPort(port, x, y, areInputs);
|
||||
});
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.renderPort = function(port, x, y, isInput) {
|
||||
var color = this.PORT_COLOR.OPEN,
|
||||
portIcon = this.$ports.append('g'),
|
||||
tooltip;
|
||||
|
||||
// If the port is incoming and occupied, render it differently
|
||||
if (isInput && port.connection) {
|
||||
color = this.PORT_COLOR.OCCUPIED;
|
||||
}
|
||||
|
||||
portIcon.append('circle')
|
||||
.attr('cx', x)
|
||||
.attr('cy', y)
|
||||
.attr('r', 10)
|
||||
.attr('fill', color);
|
||||
|
||||
portIcon.append('text')
|
||||
.attr('x', x)
|
||||
.attr('y', y)
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dominant-baseline', 'middle')
|
||||
.attr('fill', 'black')
|
||||
.text(port.name[0]);
|
||||
|
||||
portIcon.on('click', this.onPortClick.bind(this, this.id, port.id, !isInput));
|
||||
|
||||
// Add tooltip with whole name
|
||||
if (this.$portTooltips[port.id]) {
|
||||
this.$portTooltips[port.id].hide();
|
||||
}
|
||||
tooltip = new Opentip(portIcon[0][0], PORT_TOOLTIP_OPTS);
|
||||
tooltip.setContent(port.name);
|
||||
portIcon.on('mouseenter', () => tooltip.show());
|
||||
portIcon.on('mouseout', () => tooltip.hide());
|
||||
this.$portTooltips[port.id] = tooltip;
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.hidePorts = function() {
|
||||
var visiblePortIds = Object.keys(this.$portTooltips);
|
||||
this.logger.info(`hiding ports for ${this.name} (${this.id})`);
|
||||
this.$ports.remove();
|
||||
this.$ports = this.$el.append('g')
|
||||
.attr('id', 'ports');
|
||||
|
||||
for (var i = visiblePortIds.length; i--;) {
|
||||
this.$portTooltips[visiblePortIds[i]].hide();
|
||||
}
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.getPortLocation = function(id, isInput) {
|
||||
// Report location of given port
|
||||
var ports = isInput ? this._node.inputs : this._node.outputs,
|
||||
i = ports.length-1,
|
||||
y;
|
||||
|
||||
while (i >= 0 && ports[i].id !== id) {
|
||||
i--;
|
||||
}
|
||||
if (i !== -1) {
|
||||
i += 1;
|
||||
y = (this.height/2);
|
||||
return {
|
||||
x: i * this.width/(ports.length+1),
|
||||
y: isInput ? y * -1 : y
|
||||
};
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.onPortClick = function() {
|
||||
// Overridden in the widget
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.getDisplayName = function() {
|
||||
return this._node.name;
|
||||
};
|
||||
|
||||
return OperationDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/OperationDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
OperationDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OperationDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'OperationDecorator';
|
||||
|
||||
OperationDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('OperationDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(OperationDecorator.prototype, __parent_proto__);
|
||||
OperationDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
OperationDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: OperationDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return OperationDecorator;
|
||||
});
|
||||
@@ -0,0 +1,213 @@
|
||||
/*globals define*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Mon May 23 2016 14:23:16 GMT-0500 (CDT).
|
||||
* A plugin that inherits from the PluginBase. To see source code documentation about available
|
||||
* properties and methods visit %host%/docs/source/PluginBase.html.
|
||||
*/
|
||||
|
||||
define([
|
||||
'q',
|
||||
'text!./metadata.json',
|
||||
'plugin/PluginBase'
|
||||
], function (
|
||||
Q,
|
||||
pluginMetadata,
|
||||
PluginBase
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
pluginMetadata = JSON.parse(pluginMetadata);
|
||||
|
||||
/**
|
||||
* Initializes a new instance of CreateExecution.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin CreateExecution.
|
||||
* @constructor
|
||||
*/
|
||||
var CreateExecution = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
|
||||
* This is also available at the instance at this.pluginMetadata.
|
||||
* @type {object}
|
||||
*/
|
||||
CreateExecution.metadata = pluginMetadata;
|
||||
|
||||
// Prototypical inheritance from PluginBase.
|
||||
CreateExecution.prototype = Object.create(PluginBase.prototype);
|
||||
CreateExecution.prototype.constructor = CreateExecution;
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
CreateExecution.prototype.main = function (callback) {
|
||||
// Verify that the node is a pipeline
|
||||
if (!this.core.isTypeOf(this.activeNode, this.META.Pipeline)) {
|
||||
return callback('Current node is not a Pipeline!', this.result);
|
||||
}
|
||||
|
||||
return this.createExecution(this.activeNode)
|
||||
.then(() => {
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.catch(err => callback(err, this.result));
|
||||
};
|
||||
|
||||
CreateExecution.prototype.getExecutionDir = function () {
|
||||
return this.core.loadChildren(this.rootNode)
|
||||
.then(children => {
|
||||
var execPath = this.core.getPath(this.META.Execution);
|
||||
|
||||
// Find a node in the root that can contain only executions
|
||||
return children.find(child => {
|
||||
var metarule = this.core.getChildrenMeta(child);
|
||||
return metarule && metarule[execPath];
|
||||
}) || this.rootNode; // default to rootNode
|
||||
});
|
||||
};
|
||||
|
||||
CreateExecution.prototype.createExecution = function (node) {
|
||||
var name = this.core.getAttribute(node, 'name');
|
||||
|
||||
// Given a pipeline, copy all the operations to a custom job
|
||||
// - Copy the operations
|
||||
// - Wrap the operations in "Job" boxes which contain running info
|
||||
// - eg,
|
||||
// - 'debug' the given run (download all execution files)
|
||||
// - 'console' show console output (future feature)
|
||||
// - Update the references
|
||||
var tgtNode,
|
||||
copies,
|
||||
opTuples, // [[op, index], [op, index], ...]
|
||||
dataMapping = {};
|
||||
|
||||
return this.getExecutionDir()
|
||||
.then(execDir => {
|
||||
tgtNode = this.core.createNode({
|
||||
base: this.META.Execution,
|
||||
parent: execDir
|
||||
});
|
||||
this.core.setAttribute(tgtNode, 'name', `${name} Execution`);
|
||||
return this.core.loadChildren(node);
|
||||
})
|
||||
.then(children => {
|
||||
if (!children.length) {
|
||||
this.logger.warn(`No children in pipeline. Will proceed anyway`);
|
||||
}
|
||||
|
||||
copies = children.length ? this.core.copyNodes(children, tgtNode) : [];
|
||||
opTuples = copies
|
||||
.map((copy, i) => [copy, i]) // zip w/ index
|
||||
.filter(pair => this.core.isTypeOf(pair[0], this.META.Operation));
|
||||
|
||||
// Create a mapping of old names to new names
|
||||
return Q.all(opTuples.map(pair =>
|
||||
// Add the input/output mappings to the dataMapping
|
||||
this.addDataToMap(children[pair[1]], pair[0], dataMapping)
|
||||
)
|
||||
);
|
||||
})
|
||||
.then(() => { // datamapping is set!
|
||||
this.updateReferences(copies, dataMapping);
|
||||
this.boxOperations(opTuples.map(o => o[0]), tgtNode);
|
||||
return this.save(`Created execution of ${name}`);
|
||||
})
|
||||
.then(() => tgtNode); // return tgtNode
|
||||
};
|
||||
|
||||
CreateExecution.prototype.getExecutionsDir = function () {
|
||||
return this.rootNode;
|
||||
};
|
||||
|
||||
CreateExecution.prototype.addDataToMap = function (srcOp, dstOp, map) {
|
||||
return Q.all(
|
||||
[srcOp, dstOp]
|
||||
.map(op => {
|
||||
// Get the inputs and outputs for both
|
||||
return this.core.loadChildren(op)
|
||||
.then(containers => {
|
||||
var names = containers.map(c => this.core.getAttribute(c, 'name')),
|
||||
inputs = containers
|
||||
.find((c, i) => names[i] === 'Inputs'),
|
||||
outputs = containers
|
||||
.find((c, i) => names[i] === 'Outputs');
|
||||
|
||||
return Q.all(
|
||||
[inputs, outputs].map(c => c ? this.core.loadChildren(c) : [])
|
||||
);
|
||||
});
|
||||
})
|
||||
)
|
||||
.then(ios => {
|
||||
var srcIO,
|
||||
dstIO;
|
||||
|
||||
srcIO = ios[0].map(c => this.sortIOByName(c));
|
||||
dstIO = ios[1].map(c => this.sortIOByName(c));
|
||||
|
||||
// match the nodes by same name!
|
||||
srcIO.forEach((srcContainer, c) => srcContainer.forEach((node, n) =>
|
||||
map[this.core.getPath(node)] = dstIO[c][n] // old id -> new node
|
||||
)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
CreateExecution.prototype.sortIOByName = function (container) {
|
||||
return container.sort((a, b) =>
|
||||
// sort by name
|
||||
this.core.getAttribute(a, 'name') < this.core.getAttribute(b, 'name') ? 1 : -1
|
||||
);
|
||||
};
|
||||
|
||||
// Wrap each Operation with a Job 'box'
|
||||
CreateExecution.prototype.boxOperations = function (operations, container) {
|
||||
operations.forEach(copy => {
|
||||
var name = this.core.getAttribute(copy, 'name'),
|
||||
job;
|
||||
|
||||
// Create job
|
||||
job = this.core.createNode({
|
||||
base: this.META.Job,
|
||||
parent: container
|
||||
});
|
||||
this.core.setAttribute(job, 'name', name);
|
||||
|
||||
// Move the given copy into the Job node
|
||||
this.core.moveNode(copy, job);
|
||||
});
|
||||
};
|
||||
|
||||
CreateExecution.prototype.updateReferences = function (nodes, map) {
|
||||
// For each new node, update the references (other than base)
|
||||
// to the correct nodeId
|
||||
nodes.forEach(copy => {
|
||||
this.core.getPointerNames(copy)
|
||||
.filter(name => name !== 'base')
|
||||
.forEach(name => {
|
||||
var tgt = this.core.getPointerPath(copy, name);
|
||||
if (map[tgt]) {
|
||||
this.logger.info(`Updating ptr ${name}`);
|
||||
this.core.setPointer(copy, name, map[tgt]);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return CreateExecution;
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "CreateExecution",
|
||||
"name": "CreateExecution",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"icon": {
|
||||
"class": "glyphicon glyphicon-cog",
|
||||
"src": ""
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"writeAccessRequired": false,
|
||||
"configStructure": []
|
||||
}
|
||||
@@ -9,12 +9,22 @@ define([
|
||||
'plugin/PluginConfig',
|
||||
'plugin/PluginBase',
|
||||
'deepforge/js-yaml.min',
|
||||
'text!deepforge/layers.yml',
|
||||
'common/util/guid',
|
||||
'js/RegistryKeys',
|
||||
'js/Constants',
|
||||
'js/Panels/MetaEditor/MetaEditorConstants',
|
||||
'underscore',
|
||||
'text!deepforge/layers.json',
|
||||
'text!./metadata.json'
|
||||
], function (
|
||||
PluginConfig,
|
||||
PluginBase,
|
||||
yaml,
|
||||
generateGuid,
|
||||
REGISTRY_KEYS,
|
||||
CONSTANTS,
|
||||
META_CONSTANTS,
|
||||
_,
|
||||
DEFAULT_LAYERS,
|
||||
metadata
|
||||
) {
|
||||
@@ -31,6 +41,8 @@ define([
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = CreateTorchMeta.metadata;
|
||||
this.metaSheets = {};
|
||||
this.sheetCounts = {};
|
||||
};
|
||||
|
||||
CreateTorchMeta.metadata = JSON.parse(metadata);
|
||||
@@ -51,15 +63,14 @@ define([
|
||||
CreateTorchMeta.prototype.main = function (callback) {
|
||||
// Use self to access core, project, result, logger etc from PluginBase.
|
||||
// These are all instantiated at this point.
|
||||
var self = this,
|
||||
nodeObject;
|
||||
var self = this;
|
||||
|
||||
if (!this.META.Language) {
|
||||
callback('"Language" container required to run plugin', this.result);
|
||||
}
|
||||
|
||||
// Extra layer names
|
||||
this.getYamlText((err, text) => {
|
||||
this.getJsonLayers((err, text) => {
|
||||
if (err) {
|
||||
return callback(err, this.result);
|
||||
}
|
||||
@@ -68,15 +79,25 @@ define([
|
||||
// - (Abstract) CategoryLayerTypes
|
||||
// - LayerName
|
||||
// - Attributes (if exists)
|
||||
var content,
|
||||
var content = {},
|
||||
categories,
|
||||
nodes = {};
|
||||
config = this.getCurrentConfig(),
|
||||
nodes = {},
|
||||
layers;
|
||||
|
||||
try {
|
||||
content = yaml.load(text);
|
||||
layers = JSON.parse(text)
|
||||
.filter(layer => layer.type !== 'Criterion');
|
||||
} catch (e) {
|
||||
return callback('YAML parse error: ' + e, this.result);
|
||||
return callback('JSON parse error: ' + e, this.result);
|
||||
}
|
||||
layers.forEach(layer => {
|
||||
if (!content[layer.type]) {
|
||||
content[layer.type] = [];
|
||||
}
|
||||
content[layer.type].push(layer);
|
||||
});
|
||||
|
||||
categories = Object.keys(content);
|
||||
// Create the base class, if needed
|
||||
if (!this.META.Layer) {
|
||||
@@ -85,23 +106,52 @@ define([
|
||||
|
||||
// Create the category nodes
|
||||
categories
|
||||
.forEach(name => nodes[name] = this.createMetaNode(name, this.META.Layer));
|
||||
.forEach(name => {
|
||||
// Create a tab for each
|
||||
this.metaSheets[name] = this.createMetaSheetTab(name);
|
||||
this.sheetCounts[name] = 0;
|
||||
nodes[name] = this.createMetaNode(name, this.META.Layer, name);
|
||||
});
|
||||
|
||||
// Make them abstract
|
||||
categories
|
||||
.forEach(name => this.core.setRegistry(nodes[name], 'isAbstract', true));
|
||||
|
||||
|
||||
if (config.removeOldLayers) {
|
||||
var isNewLayer = {},
|
||||
newLayers = layers.map(layer => layer.name),
|
||||
oldLayers,
|
||||
oldNames;
|
||||
|
||||
newLayers = newLayers.concat(categories); // add the category nodes
|
||||
newLayers.forEach(name => isNewLayer[name] = true);
|
||||
|
||||
// Set the newLayer nodes 'base' to 'Layer' so we don't accidentally
|
||||
// delete them
|
||||
newLayers
|
||||
.map(name => this.META[name])
|
||||
.filter(layer => !!layer)
|
||||
.forEach(layer => this.core.setPointer(layer, 'base', this.META.Layer));
|
||||
|
||||
oldLayers = Object.keys(this.META)
|
||||
.filter(name => name !== 'Layer')
|
||||
.map(name => this.META[name])
|
||||
.filter(node => this.isMetaTypeOf(node, this.META.Layer))
|
||||
.filter(node => !isNewLayer[this.core.getAttribute(node, 'name')]);
|
||||
|
||||
oldNames = oldLayers.map(l => this.core.getAttribute(l, 'name'));
|
||||
// Get the old layer names
|
||||
this.logger.debug(`Removing layers: ${oldNames.join(', ')}`);
|
||||
oldLayers.forEach(layer => this.core.deleteNode(layer));
|
||||
}
|
||||
|
||||
// Create the actual nodes
|
||||
categories.forEach(cat => {
|
||||
content[cat]
|
||||
.forEach(name => {
|
||||
var attrs = null;
|
||||
if (typeof name !== 'string') {
|
||||
attrs = name[Object.keys(name)[0]];
|
||||
name = Object.keys(name)[0];
|
||||
}
|
||||
nodes[name] = this.createMetaNode(name, nodes[cat], attrs);
|
||||
.forEach(layer => {
|
||||
var attrs = layer.params,
|
||||
name = layer.name;
|
||||
nodes[name] = this.createMetaNode(name, nodes[cat], cat, attrs);
|
||||
// Make the node non-abstract
|
||||
this.core.setRegistry(nodes[name], 'isAbstract', false);
|
||||
});
|
||||
@@ -116,11 +166,48 @@ define([
|
||||
callback(null, self.result);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getYamlText = function (callback) {
|
||||
CreateTorchMeta.prototype.removeFromMeta = function (nodeId) {
|
||||
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
|
||||
sheet;
|
||||
|
||||
// Remove from meta
|
||||
this.core.delMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, nodeId);
|
||||
|
||||
// Remove from the given meta sheet
|
||||
sheet = sheets.find(sheet => {
|
||||
var paths = this.core.getMemberPaths(this.rootNode, sheet.SetID);
|
||||
return paths.indexOf(nodeId) > -1;
|
||||
});
|
||||
|
||||
if (sheet) {
|
||||
this.core.delMember(this.rootNode, sheet.SetID, nodeId);
|
||||
}
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.createMetaSheetTab = function (name) {
|
||||
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
|
||||
id = META_CONSTANTS.META_ASPECT_SHEET_NAME_PREFIX + generateGuid(),
|
||||
sheet,
|
||||
desc = {
|
||||
SetID: id,
|
||||
order: sheets.length,
|
||||
title: name
|
||||
};
|
||||
|
||||
sheet = sheets.find(sheet => sheet.title === name);
|
||||
if (!sheet) {
|
||||
sheet = desc;
|
||||
this.logger.debug(`creating meta sheet "${name}"`);
|
||||
this.core.createSet(this.rootNode, sheet.SetID);
|
||||
sheets.push(sheet);
|
||||
this.core.setRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS, sheets);
|
||||
}
|
||||
return sheet.SetID;
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getJsonLayers = function (callback) {
|
||||
var config = this.getCurrentConfig();
|
||||
|
||||
if (config.layerNameHash) {
|
||||
@@ -136,41 +223,72 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.createMetaNode = function (name, base, attrs) {
|
||||
var node;
|
||||
CreateTorchMeta.prototype.createMetaNode = function (name, base, tabName, attrs) {
|
||||
var node = this.META[name],
|
||||
nodeId = node && this.core.getPath(node),
|
||||
tabId = this.metaSheets[tabName],
|
||||
position = this.getPositionFor(name, tabName);
|
||||
|
||||
if (this.META[name]) {
|
||||
this.logger.warn('"' + name + '" already exists. skipping...');
|
||||
return this.META[name];
|
||||
if (!tabId) {
|
||||
this.logger.error(`No meta sheet for ${tabName}`);
|
||||
}
|
||||
|
||||
// Create a node
|
||||
node = this.core.createNode({
|
||||
parent: this.META.Language,
|
||||
base: base
|
||||
});
|
||||
this.core.setAttribute(node, 'name', name);
|
||||
if (!node) {
|
||||
// Create a node
|
||||
node = this.core.createNode({
|
||||
parent: this.META.Language,
|
||||
base: base
|
||||
});
|
||||
this.core.setAttribute(node, 'name', name);
|
||||
|
||||
nodeId = this.core.getPath(node);
|
||||
} else {
|
||||
// Remove from meta
|
||||
this.removeFromMeta(nodeId);
|
||||
this.core.setPointer(node, 'base', base);
|
||||
}
|
||||
|
||||
// Add it to the meta sheet
|
||||
this.core.addMember(this.rootNode, 'MetaAspectSet', node);
|
||||
this.core.addMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, node);
|
||||
this.core.addMember(this.rootNode, tabId, node);
|
||||
|
||||
// Add it to a tab of the meta sheet
|
||||
var set = this.core.getSetNames(this.rootNode)
|
||||
.find(name => name !== 'MetaAspectSet');
|
||||
|
||||
this.core.addMember(this.rootNode, set, node);
|
||||
// TODO: Position the nodes on the META
|
||||
// TODO: Put each group of nodes on their own META sheet
|
||||
this.core.setMemberRegistry(
|
||||
this.rootNode,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME,
|
||||
nodeId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
position
|
||||
);
|
||||
this.core.setMemberRegistry(
|
||||
this.rootNode,
|
||||
tabId,
|
||||
nodeId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
position
|
||||
);
|
||||
|
||||
if (attrs) { // Add the attributes
|
||||
attrs.forEach((name, index) => {
|
||||
var desc = null;
|
||||
if (typeof name !== 'string') {
|
||||
desc = name[Object.keys(name)[0]];
|
||||
name = Object.keys(name)[0];
|
||||
// Remove attributes not in the given list
|
||||
var currentAttrs = this.core.getValidAttributeNames(node),
|
||||
rmAttrs;
|
||||
|
||||
rmAttrs = _.difference(currentAttrs, attrs) // old attribute names
|
||||
.filter(attr => attr !== 'name');
|
||||
|
||||
if (rmAttrs.length) {
|
||||
this.logger.debug(`Removing ${rmAttrs.join(', ')} from ${name}`);
|
||||
}
|
||||
rmAttrs.forEach(attr => {
|
||||
this.core.delAttributeMeta(node, attr);
|
||||
if (this.core.getOwnAttribute(node, attr) !== undefined) {
|
||||
this.core.delAttribute(node, attr);
|
||||
}
|
||||
desc = desc || {};
|
||||
});
|
||||
|
||||
attrs.forEach((name, index) => {
|
||||
var desc = {};
|
||||
desc.argindex = index;
|
||||
desc.default = '';
|
||||
this.addAttribute(name, node, desc);
|
||||
});
|
||||
}
|
||||
@@ -179,11 +297,38 @@ define([
|
||||
return node;
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getPositionFor = function(name, tabName) {
|
||||
var index = this.sheetCounts[tabName],
|
||||
dx = 140,
|
||||
dy = 100,
|
||||
MAX_WIDTH = 1200,
|
||||
x;
|
||||
|
||||
if (tabName === 'Convolution') {
|
||||
dx *= 1.3;
|
||||
dy *= 1.5;
|
||||
}
|
||||
|
||||
this.sheetCounts[tabName]++;
|
||||
if (index === 0) {
|
||||
return {
|
||||
x: MAX_WIDTH/2,
|
||||
y: 50
|
||||
};
|
||||
}
|
||||
|
||||
x = dx*index;
|
||||
return {
|
||||
x: x%MAX_WIDTH,
|
||||
y: Math.floor(x/MAX_WIDTH+1)*dy + 50
|
||||
};
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.addAttribute = function (name, node, def) {
|
||||
var initial,
|
||||
schema = {};
|
||||
|
||||
schema.type = def.type || 'integer';
|
||||
schema.type = def.type || 'string';
|
||||
if (schema.type === 'list') { // FIXME: add support for lists
|
||||
schema.type = 'string';
|
||||
}
|
||||
@@ -213,9 +358,7 @@ define([
|
||||
if (schema.type === 'boolean') {
|
||||
initial = initial !== null ? initial : false;
|
||||
}
|
||||
if (initial !== null) { // optional attribute - set default value
|
||||
this.core.setAttribute(node, name, initial);
|
||||
}
|
||||
this.core.setAttribute(node, name, initial);
|
||||
};
|
||||
|
||||
return CreateTorchMeta;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "CreateTorchMeta",
|
||||
"name": "Create Torch Meta",
|
||||
"name": "Update nn meta",
|
||||
"version": "0.1.0",
|
||||
"description": "Create metamodel from Torch yaml",
|
||||
"icon": {
|
||||
@@ -17,6 +17,14 @@
|
||||
"value": "",
|
||||
"valueType": "asset",
|
||||
"readOnly": false
|
||||
},
|
||||
{
|
||||
"name": "removeOldLayers",
|
||||
"displayName": "Delete old layers",
|
||||
"description": "Delete all layers not in the current description",
|
||||
"value": true,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,157 @@
|
||||
/* globals define*/
|
||||
// This is an 'executor' containing the implementations of all local operations
|
||||
// These are all primitives in DeepForge
|
||||
define([
|
||||
], function(
|
||||
) {
|
||||
'use strict';
|
||||
var LocalExecutor = function() {
|
||||
};
|
||||
|
||||
// Should these be in lua?
|
||||
LocalExecutor.prototype.ArtifactLoader = function(node) {
|
||||
// Get the hash from the output node
|
||||
var hash;
|
||||
return this.core.loadChildren(node)
|
||||
.then(cntrs => {
|
||||
// Get the output container and load it's children
|
||||
var output = cntrs
|
||||
.find(cntr => {
|
||||
var metaNode = this.core.getMetaType(cntr),
|
||||
metaName = this.core.getAttribute(metaNode, 'name');
|
||||
return metaName === 'Outputs';
|
||||
});
|
||||
return this.core.loadChildren(output);
|
||||
})
|
||||
.then(dataNodes => {
|
||||
hash = this.core.getAttribute(dataNodes[0], 'data');
|
||||
return this.getOutputs(node);
|
||||
})
|
||||
.then(outputTuples => {
|
||||
var outputs = outputTuples.map(tuple => tuple[2]),
|
||||
paths;
|
||||
|
||||
paths = outputs.map(output => this.core.getPath(output));
|
||||
// Get the 'data' hash and store it in the output data ports
|
||||
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
|
||||
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
|
||||
|
||||
this.onOperationComplete(node);
|
||||
});
|
||||
};
|
||||
|
||||
LocalExecutor.prototype.ArtifactFinder = function(node) {
|
||||
// Check the save dir for a node with the given name
|
||||
// that has the given type
|
||||
var hash,
|
||||
typeId = this.core.getPointerPath(node, 'type'),
|
||||
type,
|
||||
artifactName = this.core.getAttribute(node, 'artifactName');
|
||||
|
||||
return this.core.loadByPath(this.rootNode, typeId)
|
||||
.then(_type => {
|
||||
type = _type;
|
||||
return this._getSaveDir();
|
||||
})
|
||||
.then(saveDir => this.core.loadChildren(saveDir))
|
||||
.then(artifacts => {
|
||||
return artifacts.find(artifact =>
|
||||
this.core.getAttribute(artifact, 'name') === artifactName &&
|
||||
this.isMetaTypeOf(artifact, type));
|
||||
})
|
||||
.then(matchingArtifact => {
|
||||
hash = matchingArtifact && this.core.getAttribute(matchingArtifact, 'data');
|
||||
// If no hash, just
|
||||
if (!hash) {
|
||||
return this.onOperationComplete(node);
|
||||
} else {
|
||||
return this.getOutputs(node)
|
||||
.then(outputTuples => {
|
||||
var outputs = outputTuples.map(tuple => tuple[2]),
|
||||
paths;
|
||||
|
||||
paths = outputs.map(output => this.core.getPath(output));
|
||||
// Get the 'data' hash and store it in the output data ports
|
||||
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
|
||||
|
||||
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
|
||||
|
||||
this.onOperationComplete(node);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
LocalExecutor.prototype._getSaveDir = function () {
|
||||
return this.core.loadChildren(this.rootNode)
|
||||
.then(children => {
|
||||
var execPath = this.core.getPath(this.META.Data),
|
||||
containers,
|
||||
saveDir;
|
||||
|
||||
// Find a node in the root that can contain only executions
|
||||
containers = children.filter(child => {
|
||||
var metarule = this.core.getChildrenMeta(child);
|
||||
return metarule && metarule[execPath];
|
||||
});
|
||||
|
||||
if (containers.length > 1) {
|
||||
saveDir = containers.find(c =>
|
||||
this.core.getAttribute(c, 'name').toLowerCase().indexOf('artifacts') > -1
|
||||
) || containers[0];
|
||||
}
|
||||
|
||||
return saveDir || this.rootNode; // default to rootNode
|
||||
});
|
||||
};
|
||||
|
||||
LocalExecutor.prototype.Save = function(node) {
|
||||
var nodeId = this.core.getPath(node),
|
||||
parentNode;
|
||||
|
||||
// Get the input node
|
||||
this.logger.info('Calling save operation!');
|
||||
return this._getSaveDir()
|
||||
.then(_saveDir => {
|
||||
parentNode = _saveDir;
|
||||
return this.getInputs(node);
|
||||
})
|
||||
.then(inputs => {
|
||||
var ids = inputs.map(i => this.core.getPath(i[2])),
|
||||
dataNodes;
|
||||
|
||||
dataNodes = Object.keys(this.nodes)
|
||||
.map(id => this.nodes[id])
|
||||
.filter(node => this.isMetaTypeOf(node, this.META.Transporter))
|
||||
.filter(node =>
|
||||
ids.indexOf(this.core.getPointerPath(node, 'dst')) > -1
|
||||
)
|
||||
.map(node => this.core.getPointerPath(node, 'src'))
|
||||
.map(id => this.nodes[id]);
|
||||
|
||||
// get the input node
|
||||
if (dataNodes.length === 0) {
|
||||
this.logger.error(`Could not find data to save! ${nodeId}`);
|
||||
} else {
|
||||
var newNodes = this.core.copyNodes(dataNodes, parentNode),
|
||||
newName = this.core.getOwnAttribute(node, 'saveName');
|
||||
if (newName) {
|
||||
newNodes.forEach(node =>
|
||||
this.core.setAttribute(node, 'name', newName)
|
||||
);
|
||||
}
|
||||
}
|
||||
var hashes = dataNodes.map(n => this.core.getAttribute(n, 'data'));
|
||||
this.logger.info(`saving hashes: ${hashes.map(h => `"${h}"`)}`);
|
||||
this.onOperationComplete(node);
|
||||
});
|
||||
|
||||
// Overwrite existing node w/ this name?
|
||||
// TODO
|
||||
};
|
||||
|
||||
LocalExecutor.TYPES = Object.keys(LocalExecutor.prototype)
|
||||
.filter(name => name.indexOf('_') !== 0);
|
||||
|
||||
return LocalExecutor;
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
require 'paths'
|
||||
local dir = paths.concat('inputs', '<%= name %>')
|
||||
<%= code %>
|
||||
@@ -1,12 +0,0 @@
|
||||
-- run the <%= name %> and serialize the results
|
||||
<%= outputs.map(p => p[0])[0] %> = require './main'
|
||||
print('<%= name %> operation complete!')
|
||||
|
||||
-- serialize by type
|
||||
outputs = require './outputs'
|
||||
<% outputs.forEach(pair => {
|
||||
var name = pair[0],
|
||||
type = pair[1];
|
||||
%>
|
||||
outputs.<%= type %>('<%= name %>', <%= name %>)
|
||||
<% }); %>
|
||||
@@ -1,12 +0,0 @@
|
||||
-- input data
|
||||
<% inputs.forEach(function(pair) { var input = pair[0]%>
|
||||
<%= input %> = require './inputs/<%= input %>'
|
||||
<% }); %>
|
||||
|
||||
-- load references
|
||||
<% pointers.forEach(function(pointer) { %><%= pointer %> = require './pointers/<%= pointer %>'
|
||||
<% }); %>
|
||||
attributes = require './attributes'
|
||||
|
||||
-- main operation code for <%= name %>
|
||||
<%= code %>
|
||||
@@ -17,14 +17,6 @@
|
||||
"value": false,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
},
|
||||
{
|
||||
"name": "reset",
|
||||
"displayName": "Reset",
|
||||
"description": "Clear existing results",
|
||||
"value": false,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
require 'paths'
|
||||
|
||||
local path = 'inputs/<%= name %>/<%= filename %>'
|
||||
local abs_path = paths.concat('inputs', '<%= name %>', '<%= filename %>')
|
||||
|
||||
<%= code %>
|
||||
@@ -0,0 +1,13 @@
|
||||
-- run the <%= name %> and serialize the results
|
||||
print('\n############### Running "<%= name %>" Operation ############### ')
|
||||
results = require './main'
|
||||
print('############### "<%= name %>" Operation Complete! ###############')
|
||||
|
||||
-- serialize by type
|
||||
outputs = require './outputs'
|
||||
<% outputs.forEach(pair => {
|
||||
var name = pair[0],
|
||||
type = pair[1];
|
||||
%>
|
||||
outputs.<%= type %>('<%= name %>', results.<%= name %>)
|
||||
<% }); %>
|
||||
+3
@@ -1,3 +1,4 @@
|
||||
/*globals define*/
|
||||
define([
|
||||
'text!./entry.ejs',
|
||||
'text!./main.ejs',
|
||||
@@ -10,7 +11,9 @@ define([
|
||||
DESERIALIZE
|
||||
) {
|
||||
|
||||
var BASH = 'th init.lua 2>&1';
|
||||
return {
|
||||
BASH,
|
||||
ENTRY,
|
||||
MAIN,
|
||||
SERIALIZE,
|
||||
@@ -0,0 +1,12 @@
|
||||
-- load custom layers
|
||||
require './custom-layers'
|
||||
|
||||
-- input data<% inputs.forEach(function(pair) { var input = pair[0], isNil = pair[1];%>
|
||||
<%= isNil ? 'local ' : ''%><%= input %> = <% if (isNil) { %>nil<% } else { %>require './inputs/<%= input %>'<%}}); %>
|
||||
|
||||
-- load references<% pointers.forEach(function(pair) { var pointer = pair[0], isNil = pair[1];%>
|
||||
<%= isNil ? 'local ' : ''%><%= pointer %> = <% if (isNil) { %>nil<% } else { %>require './pointers/<%= pointer %>'<%}}); %>
|
||||
attributes = require './attributes'
|
||||
|
||||
-- main operation code for <%= name %>
|
||||
<%= code %>
|
||||
+3
-4
@@ -1,15 +1,14 @@
|
||||
-- Serialization functions for:<%= types.map(function(type) {return type[0];}).join('\n-- ') %>
|
||||
-- Serialization functions for: <%= types.map(function(type) {return type[0];}).join('\n-- ') %>
|
||||
require 'paths'
|
||||
|
||||
local serializer = {}
|
||||
|
||||
<% types.forEach(function(pair) {
|
||||
var type = pair[0],
|
||||
fn = pair[1];
|
||||
%>
|
||||
function serializer.<%= type %> (name, data)
|
||||
local dir = paths.concat('outputs', name)
|
||||
os.execute('mkdir ' .. dir)
|
||||
local path = 'outputs/' .. name
|
||||
local abs_path = paths.concat('outputs', name)
|
||||
<%= fn.replace('\n', '\n ') %>
|
||||
end
|
||||
<% }); %>
|
||||
@@ -29,6 +29,7 @@ define([
|
||||
* @classdesc This class represents the plugin GenerateArchitecture.
|
||||
* @constructor
|
||||
*/
|
||||
var INDEX = '__index__';
|
||||
var GenerateArchitecture = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
@@ -42,57 +43,166 @@ define([
|
||||
GenerateArchitecture.prototype.constructor = GenerateArchitecture;
|
||||
|
||||
GenerateArchitecture.prototype.main = function () {
|
||||
this.addCustomLayersToMeta();
|
||||
this.LayerDict = createLayerDict(this.core, this.META);
|
||||
this.uniqueId = 2;
|
||||
this._oldTemplateSettings = _.templateSettings;
|
||||
return PluginBase.prototype.main.apply(this, arguments);
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.addCustomLayersToMeta = function () {
|
||||
var metaDict = this.core.getAllMetaNodes(this.rootNode);
|
||||
|
||||
Object.keys(metaDict).map(id => metaDict[id])
|
||||
// Get all custom layers
|
||||
.filter(node => this.core.isTypeOf(node, this.META.Layer))
|
||||
// Add them to the meta
|
||||
.forEach(node => this.META[this.core.getAttribute(node, 'name')] = node);
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createOutputFiles = function (tree) {
|
||||
var layers = tree[Constants.CHILDREN],
|
||||
//initialLayers,
|
||||
result = {},
|
||||
template,
|
||||
snippet,
|
||||
code,
|
||||
args;
|
||||
code = 'require \'nn\'\n';
|
||||
|
||||
code = [
|
||||
'require \'nn\'',
|
||||
'',
|
||||
'local net = nn.Sequential()'
|
||||
].join('\n');
|
||||
//initialLayers = layers.filter(layer => layer[Constants.PREV].length === 0);
|
||||
// Add an index to each layer
|
||||
layers.forEach((l, index) => l[INDEX] = index);
|
||||
|
||||
// Start with sequential (just one input)
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
if (layers[i][Constants.NEXT].length > 1) {
|
||||
// no support for
|
||||
console.error('No support for parallel layers... yet');
|
||||
break;
|
||||
} else {
|
||||
// args
|
||||
args = this.createArgString(layers[i]);
|
||||
template = _.template('net:add(nn.{{= name }}' + args + ')');
|
||||
snippet = template(layers[i]);
|
||||
code += '\n' + snippet;
|
||||
}
|
||||
// Define custom layers
|
||||
if (this.getCurrentConfig().standalone) {
|
||||
code += this.genLayerDefinitions(layers);
|
||||
}
|
||||
|
||||
code += '\n\nreturn net';
|
||||
code += this.genArchCode(layers);
|
||||
|
||||
result[tree.name + '.lua'] = code;
|
||||
_.templateSettings = this._oldTemplateSettings; // FIXME: Fix this in SimpleNodes
|
||||
return result;
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createArgString = function (layer) {
|
||||
return '(' + this.LayerDict[layer.name].map(arg => {
|
||||
var value = layer[arg.name];
|
||||
// Infer if value is unset and infer.dimensionality is set
|
||||
if (!value && arg.infer === 'dimensionality') {
|
||||
value = dimensionality(layer[Constants.PREV][0]);
|
||||
}
|
||||
return value;
|
||||
}).join(', ') + ')';
|
||||
GenerateArchitecture.prototype.genArchCode = function (layers) {
|
||||
return [
|
||||
this.createSequential(layers[0], 'net').code,
|
||||
'\nreturn net'
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createSequential = function (layer, name) {
|
||||
var next = layer[Constants.NEXT][0],
|
||||
args,
|
||||
template,
|
||||
snippet,
|
||||
snippets,
|
||||
code = `\nlocal ${name} = nn.Sequential()`,
|
||||
|
||||
group,
|
||||
i,
|
||||
result;
|
||||
|
||||
while (layer) {
|
||||
// if there is only one successor, just add the given layer
|
||||
if (layer[Constants.PREV].length > 1) { // sequential layers are over
|
||||
next = layer; // the given layer will be added by the caller
|
||||
break;
|
||||
} else { // add the given layer
|
||||
args = this.createArgString(layer);
|
||||
template = _.template(name + ':add(nn.{{= name }}' + args + ')');
|
||||
snippet = template(layer);
|
||||
code += '\n' + snippet;
|
||||
|
||||
}
|
||||
|
||||
while (layer && layer[Constants.NEXT].length > 1) { // concat/parallel
|
||||
// if there is a fork, recurse and add a concat layer
|
||||
|
||||
this.logger.debug(`detected fork of size ${layer[Constants.NEXT].length}`);
|
||||
snippets = layer[Constants.NEXT].map(nlayer =>
|
||||
this.createSequential(nlayer, 'net_'+(this.uniqueId++)));
|
||||
code += '\n' + snippets.map(snippet => snippet.code).join('\n');
|
||||
|
||||
// Make sure all snippets end at the same concat node
|
||||
|
||||
// Until all snippets end at the same concat node
|
||||
snippets.sort((a, b) => a.endIndex < b.endIndex ? -1 : 1);
|
||||
group = [];
|
||||
while (snippets.length > 0) {
|
||||
// Add snippets to the group
|
||||
i = 0;
|
||||
while (i < snippets.length &&
|
||||
snippets[0].endIndex === snippets[i].endIndex) {
|
||||
|
||||
group.push(snippets[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Add concat layer
|
||||
layer = group[0].next;
|
||||
if (layer) {
|
||||
args = this.createArgString(layer);
|
||||
code += `\n\nlocal concat_${layer[INDEX]} = nn.Concat${args}\n` +
|
||||
group.map(snippet =>
|
||||
`concat_${layer[INDEX]}:add(${snippet.name})`)
|
||||
.join('\n') + `\n\n${name}:add(concat_${layer[INDEX]})`;
|
||||
|
||||
next = layer[Constants.NEXT][0];
|
||||
} else {
|
||||
next = null; // no next layers
|
||||
}
|
||||
|
||||
// Remove the updated snippets
|
||||
this.logger.debug('removing ' + i + ' snippet(s)');
|
||||
snippets.splice(0, i);
|
||||
|
||||
// merge the elements in the group
|
||||
if (snippets.length) { // prepare next iteration
|
||||
result = this.createSequential(next, 'net_'+(this.uniqueId++));
|
||||
code += result.code;
|
||||
group = [result];
|
||||
this.logger.debug('updating group ('+ snippets.length+ ' left)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer = next;
|
||||
next = layer && layer[Constants.NEXT][0];
|
||||
}
|
||||
|
||||
return {
|
||||
code: code,
|
||||
name: name,
|
||||
endIndex: next ? next[INDEX] : Infinity,
|
||||
next: next
|
||||
};
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createArgString = function (layer) {
|
||||
return '(' + this.LayerDict[layer.name]
|
||||
.map(arg => layer[arg.name])
|
||||
.filter(GenerateArchitecture.isSet)
|
||||
.join(', ') + ')';
|
||||
};
|
||||
|
||||
GenerateArchitecture.isSet = function (value) {
|
||||
return !(value === undefined || value === null || value === '');
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.genLayerDefinitions = function(layers) {
|
||||
var code = '',
|
||||
customLayerId = this.core.getPath(this.META.CustomLayer),
|
||||
customLayers = layers.filter(layer => { // Get the custom layers
|
||||
var node = this.META[layer.name];
|
||||
return this.core.getMixinPaths(node).indexOf(customLayerId) !== -1;
|
||||
});
|
||||
|
||||
if (customLayers.length) {
|
||||
code += '\n-------------- Custom Layer Definitions --------------\n\n';
|
||||
code += customLayers.map(layer => layer.code).join('\n');
|
||||
code += '\n\n-------------- Network --------------\n';
|
||||
}
|
||||
|
||||
return code;
|
||||
};
|
||||
return GenerateArchitecture;
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* globals define */
|
||||
define([
|
||||
'SimpleNodes/Constants',
|
||||
'deepforge/lua'
|
||||
|
||||
@@ -9,5 +9,14 @@
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"configStructure": []
|
||||
"configStructure": [
|
||||
{
|
||||
"name": "standalone",
|
||||
"displayName": "Standalone",
|
||||
"description": "Prepend custom layer definitions",
|
||||
"value": false,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*globals define, _*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Sat Jun 04 2016 18:01:54 GMT-0500 (CDT).
|
||||
* A plugin that inherits from the PluginBase. To see source code documentation about available
|
||||
* properties and methods visit %host%/docs/source/PluginBase.html.
|
||||
*/
|
||||
|
||||
define([
|
||||
'text!./metadata.json',
|
||||
'plugin/PluginBase',
|
||||
'deepforge/plugin/PtrCodeGen',
|
||||
'q'
|
||||
], function (
|
||||
pluginMetadata,
|
||||
PluginBase,
|
||||
PtrCodeGen,
|
||||
Q
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
pluginMetadata = JSON.parse(pluginMetadata);
|
||||
var HEADER_LENGTH = 60;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of GenerateExecFile.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin GenerateExecFile.
|
||||
* @constructor
|
||||
*/
|
||||
var GenerateExecFile = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
|
||||
this._srcIdFor = {}; // input path -> output data node path
|
||||
|
||||
this._nameFor = {}; // input path -> opname
|
||||
this._dataNameFor = {};
|
||||
this._opNames = {};
|
||||
|
||||
// topo sort stuff
|
||||
this._nextOps = {};
|
||||
this._incomingCnts = {};
|
||||
|
||||
this._operations = {};
|
||||
this.activeNodeId = null;
|
||||
this.activeNodeDepth = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
|
||||
* This is also available at the instance at this.pluginMetadata.
|
||||
* @type {object}
|
||||
*/
|
||||
GenerateExecFile.metadata = pluginMetadata;
|
||||
|
||||
// Prototypical inheritance from PluginBase.
|
||||
GenerateExecFile.prototype = Object.create(PluginBase.prototype);
|
||||
GenerateExecFile.prototype.constructor = GenerateExecFile;
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
GenerateExecFile.prototype.main = function (callback) {
|
||||
// Get all the children and call generate exec file
|
||||
this.activeNodeId = this.core.getPath(this.activeNode);
|
||||
this.activeNodeDepth = this.activeNodeId.split('/').length + 1;
|
||||
|
||||
if (this.isMetaTypeOf(this.activeNode, this.META.Execution)) {
|
||||
this.activeNodeDepth++;
|
||||
}
|
||||
|
||||
return this.core.loadChildren(this.activeNode)
|
||||
.then(nodes => this.createExecFile(nodes))
|
||||
.then(code => this.blobClient.putFile('init.lua', code))
|
||||
.then(hash => {
|
||||
this.result.addArtifact(hash);
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.fail(err => callback(err));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.createExecFile = function (children) {
|
||||
// Convert opNodes' jobs to the nested operations
|
||||
var opNodes,
|
||||
nodes;
|
||||
|
||||
return this.unpackJobs(children)
|
||||
.then(_nodes => {
|
||||
nodes = _nodes;
|
||||
opNodes = nodes
|
||||
.filter(node => this.isMetaTypeOf(node, this.META.Operation));
|
||||
return Q.all(nodes.map(node => this.registerNameAndData(node)));
|
||||
})
|
||||
.then(() => Q.all(opNodes.map(node => this.createOperation(node))))
|
||||
.then(operations => {
|
||||
var nextIds = opNodes.map(n => this.core.getPath(n))
|
||||
.filter(id => !this._incomingCnts[id]);
|
||||
|
||||
operations.forEach(op => this._operations[op.id] = op);
|
||||
|
||||
// Toposort and concat!
|
||||
return this.combineOpNodes(nextIds);
|
||||
})
|
||||
.fail(err => this.logger.error(err));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.unpackJobs = function (nodes) {
|
||||
return Q.all(
|
||||
nodes.map(node => {
|
||||
if (!this.isMetaTypeOf(node, this.META.Job)) {
|
||||
return node;
|
||||
}
|
||||
return this.core.loadChildren(node)
|
||||
.then(children =>
|
||||
children.find(c => this.isMetaTypeOf(c, this.META.Operation))
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.combineOpNodes = function (opIds) {
|
||||
var nextIds = [],
|
||||
dstIds,
|
||||
code,
|
||||
id;
|
||||
|
||||
// Combine all nodes with incoming cnts of 0
|
||||
code = opIds.map(id => this._operations[id].code).join('\n');
|
||||
|
||||
// Decrement all next ops
|
||||
dstIds = opIds.map(id => this._nextOps[id])
|
||||
.reduce((l1, l2) => l1.concat(l2), []);
|
||||
for (var i = dstIds.length; i--;) {
|
||||
id = dstIds[i];
|
||||
if (--this._incomingCnts[id] === 0) {
|
||||
nextIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
// append
|
||||
return [
|
||||
code,
|
||||
nextIds.length ? this.combineOpNodes(nextIds) : ''
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.registerNameAndData = function (node) {
|
||||
var name = this.core.getAttribute(node, 'name'),
|
||||
id = this.core.getPath(node),
|
||||
basename = name,
|
||||
i = 2;
|
||||
|
||||
if (this.isMetaTypeOf(node, this.META.Operation)) {
|
||||
|
||||
// Get a unique operation name
|
||||
while (this._opNames[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
// register the unique name
|
||||
this._opNames[name] = true;
|
||||
this._nameFor[id] = name;
|
||||
|
||||
// For operations, register all output data node names by path
|
||||
return this.core.loadChildren(node)
|
||||
.then(cntrs => {
|
||||
var cntr = cntrs.find(n => this.isMetaTypeOf(n, this.META.Outputs));
|
||||
return this.core.loadChildren(cntr);
|
||||
})
|
||||
.then(outputs => {
|
||||
outputs.forEach(output => {
|
||||
var dataId = this.core.getPath(output);
|
||||
|
||||
name = this.core.getAttribute(output, 'name');
|
||||
this._dataNameFor[dataId] = name;
|
||||
});
|
||||
});
|
||||
|
||||
// For each input data node, register the associated output id
|
||||
} else if (this.isMetaTypeOf(node, this.META.Transporter)) {
|
||||
var outputData = this.core.getPointerPath(node, 'src'),
|
||||
inputData = this.core.getPointerPath(node, 'dst'),
|
||||
srcOpId = this.getOpIdFor(outputData),
|
||||
dstOpId = this.getOpIdFor(inputData);
|
||||
|
||||
this._srcIdFor[inputData] = outputData;
|
||||
|
||||
// Store the next operation ids for the op id
|
||||
if (!this._nextOps[srcOpId]) {
|
||||
this._nextOps[srcOpId] = [];
|
||||
}
|
||||
this._nextOps[srcOpId].push(dstOpId);
|
||||
|
||||
// Increment the incoming counts for each dst op
|
||||
this._incomingCnts[dstOpId] = this._incomingCnts[dstOpId] || 0;
|
||||
this._incomingCnts[dstOpId]++;
|
||||
}
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.getOpIdFor = function (dataId) {
|
||||
var ids = dataId.split('/'),
|
||||
depth = ids.length;
|
||||
|
||||
ids.splice(this.activeNodeDepth - depth);
|
||||
return ids.join('/');
|
||||
};
|
||||
|
||||
// For each operation...
|
||||
// - unpack the inputs from prev ops
|
||||
// - add the attributes table (if used)
|
||||
// - check for '\<attributes\>' in code
|
||||
// - add the references
|
||||
// - generate the code
|
||||
// - replace the `return <thing>` w/ `<ref-name> = <thing>`
|
||||
GenerateExecFile.prototype.createOperation = function (node) {
|
||||
var id = this.core.getPath(node),
|
||||
operation = {};
|
||||
|
||||
operation.name = this._nameFor[id];
|
||||
operation.id = id;
|
||||
operation.code = this.core.getAttribute(node, 'code');
|
||||
|
||||
// Update the 'code' attribute
|
||||
// Change the last return statement to assign the results to a table
|
||||
operation.code = this.assignResultToVar(operation.code,
|
||||
`${operation.name}_results`);
|
||||
|
||||
// Get all the input names (and sources)
|
||||
return this.core.loadChildren(node)
|
||||
.then(containers => {
|
||||
var inputs;
|
||||
|
||||
inputs = containers
|
||||
.find(cntr => this.isMetaTypeOf(cntr, this.META.Inputs));
|
||||
|
||||
this.logger.info(`${name} has ${containers.length} cntrs`);
|
||||
return this.core.loadChildren(inputs);
|
||||
})
|
||||
.then(data => {
|
||||
// Get the input names and sources
|
||||
var inputNames = data.map(d => this.core.getAttribute(d, 'name')),
|
||||
ids = data.map(d => this.core.getPath(d)),
|
||||
srcIds = ids.map(id => this._srcIdFor[id]);
|
||||
|
||||
operation.inputs = inputNames.map((name, i) => {
|
||||
var id = srcIds[i],
|
||||
srcDataName = this._dataNameFor[id],
|
||||
srcOpId = this.getOpIdFor(id),
|
||||
srcOpName = this._nameFor[srcOpId];
|
||||
|
||||
return `local ${name} = ${srcOpName}_results.${srcDataName}`;
|
||||
});
|
||||
|
||||
return operation;
|
||||
|
||||
})
|
||||
.then(operation => {
|
||||
|
||||
// For each reference, run the plugin and retrieve the generated code
|
||||
operation.refNames = this.core.getPointerNames(node)
|
||||
.filter(name => name !== 'base');
|
||||
|
||||
var refs = operation.refNames
|
||||
.map(ref => [ref, this.core.getPointerPath(node, ref)]);
|
||||
|
||||
return Q.all(
|
||||
refs.map(pair => this.genPtrSnippet.apply(this, pair))
|
||||
);
|
||||
})
|
||||
.then(codeFiles => {
|
||||
operation.refs = codeFiles;
|
||||
this.genOperationCode(operation);
|
||||
return operation;
|
||||
});
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.genPtrSnippet = function (ptrName, pId) {
|
||||
return this.getPtrCodeHash(pId)
|
||||
.then(hash => this.blobClient.getObjectAsString(hash))
|
||||
.then(code => this.createHeader(`creating ${ptrName}`, 40) + '\n' +
|
||||
this.assignResultToVar(code, ptrName));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.createHeader = function (title, length) {
|
||||
var len;
|
||||
title = ` ${title} `;
|
||||
length = length || HEADER_LENGTH;
|
||||
|
||||
len = Math.max(
|
||||
Math.floor((length - title.length)/2),
|
||||
2
|
||||
);
|
||||
|
||||
return [
|
||||
'',
|
||||
title,
|
||||
''
|
||||
].join(new Array(len+1).join('-')) + '\n';
|
||||
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.genOperationCode = function (operation) {
|
||||
var header = this.createHeader(`"${operation.name}" Operation`),
|
||||
codeParts = [];
|
||||
|
||||
codeParts.push(header);
|
||||
|
||||
if (operation.inputs.length) {
|
||||
codeParts.push(operation.inputs.join('\n'));
|
||||
}
|
||||
|
||||
if (operation.refs.length) {
|
||||
codeParts.push(operation.refs.join('\n'));
|
||||
}
|
||||
|
||||
codeParts.push(operation.code);
|
||||
codeParts.push('');
|
||||
operation.code = codeParts.join('\n');
|
||||
return operation;
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.assignResultToVar = function (code, name) {
|
||||
var i = code.lastIndexOf('return');
|
||||
return code.substring(0, i) +
|
||||
code.substring(i)
|
||||
.replace('return', `local ${name} = `);
|
||||
};
|
||||
|
||||
_.extend(GenerateExecFile.prototype, PtrCodeGen.prototype);
|
||||
|
||||
return GenerateExecFile;
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "GenerateExecFile",
|
||||
"name": "Generate Execution File",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"icon": {
|
||||
"class": "glyphicon glyphicon-cog",
|
||||
"src": ""
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"writeAccessRequired": false,
|
||||
"configStructure": []
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*globals define*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Tue Jun 07 2016 11:25:09 GMT-0500 (CDT).
|
||||
* A plugin that inherits from the PluginBase. To see source code documentation about available
|
||||
* properties and methods visit %host%/docs/source/PluginBase.html.
|
||||
*/
|
||||
|
||||
define([
|
||||
'text!./metadata.json',
|
||||
'plugin/PluginBase',
|
||||
'q'
|
||||
], function (
|
||||
pluginMetadata,
|
||||
PluginBase,
|
||||
Q
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
pluginMetadata = JSON.parse(pluginMetadata);
|
||||
|
||||
/**
|
||||
* Initializes a new instance of ImportArtifact.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin ImportArtifact.
|
||||
* @constructor
|
||||
*/
|
||||
var ImportArtifact = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
|
||||
* This is also available at the instance at this.pluginMetadata.
|
||||
* @type {object}
|
||||
*/
|
||||
ImportArtifact.metadata = pluginMetadata;
|
||||
|
||||
// Prototypical inheritance from PluginBase.
|
||||
ImportArtifact.prototype = Object.create(PluginBase.prototype);
|
||||
ImportArtifact.prototype.constructor = ImportArtifact;
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
ImportArtifact.prototype.main = function (callback) {
|
||||
var self = this,
|
||||
config = this.getCurrentConfig(),
|
||||
hash = config.dataHash,
|
||||
baseName = config.dataTypeId,
|
||||
name,
|
||||
baseType,
|
||||
dataNode,
|
||||
|
||||
metaDict,
|
||||
metanodes;
|
||||
|
||||
// Create node of type "typeId" in the activeNode and set the hash, name
|
||||
metaDict = this.core.getAllMetaNodes(this.activeNode);
|
||||
metanodes = Object.keys(metaDict).map(id => metaDict[id]);
|
||||
baseType = metanodes.find(node =>
|
||||
this.core.getAttribute(node, 'name') === baseName
|
||||
);
|
||||
|
||||
if (!baseType) {
|
||||
callback(`Could not find data type "${baseName}"`, this.result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the base node
|
||||
dataNode = this.core.createNode({
|
||||
base: baseType,
|
||||
parent: this.activeNode
|
||||
});
|
||||
|
||||
this.core.setAttribute(dataNode, 'data', hash);
|
||||
baseName = this.core.getAttribute(baseType, 'name');
|
||||
|
||||
var getName;
|
||||
if (config.name) {
|
||||
getName = Q().then(() => config.name);
|
||||
} else {
|
||||
getName = this.blobClient.getMetadata(hash)
|
||||
.then(md => {
|
||||
name = baseName[0].toLowerCase() + baseName.substring(1);
|
||||
if (md) {
|
||||
name = md.name.replace(/\.[^\.]*?$/, '');
|
||||
}
|
||||
return name;
|
||||
});
|
||||
}
|
||||
|
||||
getName.then(name => this.core.setAttribute(dataNode, 'name', name))
|
||||
.then(() => this.save(`Uploaded "${name}" data`))
|
||||
.then(function () {
|
||||
self.result.setSuccess(true);
|
||||
callback(null, self.result);
|
||||
})
|
||||
.fail(function (err) {
|
||||
callback(err, self.result);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return ImportArtifact;
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"id": "ImportArtifact",
|
||||
"name": "ImportArtifact",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"icon": {
|
||||
"class": "glyphicon glyphicon-cog",
|
||||
"src": ""
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"writeAccessRequired": true,
|
||||
"configStructure": [
|
||||
{
|
||||
"name": "name",
|
||||
"displayName": "Data name",
|
||||
"description": "Optional name for artifact",
|
||||
"value": "",
|
||||
"valueType": "string",
|
||||
"readOnly": false
|
||||
},
|
||||
{
|
||||
"name": "dataHash",
|
||||
"displayName": "Data to upload",
|
||||
"description": "",
|
||||
"value": "",
|
||||
"valueType": "asset",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
/* globals define */
|
||||
// This is the searcher for the mock library
|
||||
define([
|
||||
'deepforge/layer-args',
|
||||
@@ -10,10 +11,10 @@ define([
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var nop = function() {};
|
||||
var createSearcher = function(plugin) {
|
||||
var core = plugin.core,
|
||||
META = plugin.META,
|
||||
logger = plugin.logger.fork('nn'),
|
||||
parent = plugin.tgtNode,
|
||||
LayerDict = createLayerDict(core, META);
|
||||
|
||||
@@ -41,8 +42,7 @@ define([
|
||||
};
|
||||
|
||||
Layer.prototype._node = function() {
|
||||
var attrs = this._attrs,
|
||||
name,
|
||||
var name,
|
||||
node,
|
||||
value;
|
||||
|
||||
@@ -83,11 +83,11 @@ define([
|
||||
this._outputs = [];
|
||||
};
|
||||
|
||||
Container.prototype.add = function(self, tlayer) {
|
||||
console.error('Add is not overridden!');
|
||||
Container.prototype.add = function() {
|
||||
logger.error('Add is not overridden!');
|
||||
};
|
||||
|
||||
var Sequential = function(attrs, args) {
|
||||
var Sequential = function(/*attrs, args*/) {
|
||||
Container.call(this);
|
||||
};
|
||||
|
||||
@@ -95,8 +95,7 @@ define([
|
||||
|
||||
Sequential.prototype.add = function(self, tlayer) {
|
||||
var layer = tlayer.get('_node'),
|
||||
nodes = layer._inputs,
|
||||
conn;
|
||||
nodes = layer._inputs;
|
||||
|
||||
// If this._inputs is empty, add the layer to the inputs list
|
||||
if (this._inputs.length === 0) { // first node
|
||||
@@ -146,15 +145,12 @@ define([
|
||||
var CreateLayer = function(type) {
|
||||
var res = luajs.newContext()._G,
|
||||
attrs = [].slice.call(arguments, 1),
|
||||
proto,
|
||||
node;
|
||||
|
||||
if (LAYERS[type]) {
|
||||
node = new LAYERS[type](LayerDict[type] || [], attrs);
|
||||
proto = LAYERS[type].prototype;
|
||||
} else { // Call generic Layer with type name
|
||||
node = new Layer(type, LayerDict[type] || [], attrs);
|
||||
proto = Layer.prototype;
|
||||
}
|
||||
|
||||
res.set('_node', node);
|
||||
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -5,28 +5,88 @@
|
||||
"panel": "panels/AutoViz/AutoVizPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "EasyDAG",
|
||||
"title": "EasyDAG",
|
||||
"panel": "panels/EasyDAG/EasyDAGPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "ArchEditor",
|
||||
"title": "ArchEditor",
|
||||
"panel": "panels/ArchEditor/ArchEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "TextEditor",
|
||||
"title": "TextEditor",
|
||||
"panel": "panels/TextEditor/TextEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "OperationEditor",
|
||||
"title": "OperationEditor",
|
||||
"panel": "panels/OperationEditor/OperationEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "PipelineEditor",
|
||||
"title": "PipelineEditor",
|
||||
"panel": "panels/PipelineEditor/PipelineEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "ExecutionView",
|
||||
"title": "ExecutionView",
|
||||
"panel": "panels/ExecutionView/ExecutionViewPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "RootViz",
|
||||
"title": "RootViz",
|
||||
"panel": "panels/RootViz/RootVizPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "TilingViz",
|
||||
"title": "TilingViz",
|
||||
"panel": "panels/TilingViz/TilingVizPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "OperationCodeEditor",
|
||||
"title": "OperationCodeEditor",
|
||||
"panel": "panels/OperationCodeEditor/OperationCodeEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "OperationInterfaceEditor",
|
||||
"title": "OperationInterfaceEditor",
|
||||
"panel": "panels/OperationInterfaceEditor/OperationInterfaceEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "DataTypeEditor",
|
||||
"title": "DataTypeEditor",
|
||||
"panel": "panels/DataTypeEditor/DataTypeEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "SerializeEditor",
|
||||
"title": "SerializeEditor",
|
||||
"panel": "panels/SerializeEditor/SerializeEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "DeserializeEditor",
|
||||
"title": "DeserializeEditor",
|
||||
"panel": "panels/DeserializeEditor/DeserializeEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "Footer",
|
||||
"title": "Footer",
|
||||
"panel": "panels/Footer/FooterPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "LogViewer",
|
||||
"title": "LogViewer",
|
||||
"panel": "panels/LogViewer/LogViewerPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "LayerEditor",
|
||||
"title": "LayerEditor",
|
||||
"panel": "panels/LayerEditor/LayerEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Tue May 17 2016 11:25:46 GMT-0400 (EDT).
|
||||
@@ -7,23 +7,42 @@
|
||||
define([
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'js/NodePropertyNames',
|
||||
'js/Utils/ComponentSettings',
|
||||
'underscore'
|
||||
], function (
|
||||
EasyDAGControl,
|
||||
nodePropertyNames,
|
||||
ComponentSettings,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ArchEditorControl;
|
||||
var ArchEditorControl,
|
||||
DEFAULT_CONFIG = {
|
||||
DefaultColor: '#ffb74d',
|
||||
LayerColors: {
|
||||
Containers: '#ffb74d',
|
||||
Convolution: '#2196f3',
|
||||
Simple: '#ff9100',
|
||||
Transfer: '#80deea',
|
||||
Misc: '#ce93d8'
|
||||
}
|
||||
};
|
||||
|
||||
ArchEditorControl = function (options) {
|
||||
EasyDAGControl.call(this, options);
|
||||
this._config = DEFAULT_CONFIG;
|
||||
ComponentSettings.resolveWithWebGMEGlobal(this._config, this.getComponentId());
|
||||
};
|
||||
|
||||
_.extend(ArchEditorControl.prototype, EasyDAGControl.prototype);
|
||||
|
||||
ArchEditorControl.prototype.TERRITORY_RULE = {children: 1};
|
||||
ArchEditorControl.prototype.getComponentId = function() {
|
||||
return 'ArchEditor';
|
||||
};
|
||||
|
||||
ArchEditorControl.prototype._getObjectDescriptor = function(id) {
|
||||
var desc = EasyDAGControl.prototype._getObjectDescriptor.call(this, id);
|
||||
|
||||
@@ -42,32 +61,41 @@ define([
|
||||
}
|
||||
|
||||
// Add layer type (base class's base class)
|
||||
desc.layerType = null;
|
||||
if (desc.baseName) {
|
||||
var node = this._client.getNode(id),
|
||||
base = this._client.getNode(node.getMetaTypeId()),
|
||||
layerType = this._client.getNode(base.getBaseId());
|
||||
|
||||
if (layerType) {
|
||||
desc.layerType = layerType.getAttribute(nodePropertyNames.Attributes.name);
|
||||
}
|
||||
}
|
||||
desc.layerType = null;
|
||||
if (desc.baseName) {
|
||||
var node = this._client.getNode(id),
|
||||
base = this._client.getNode(node.getMetaTypeId()),
|
||||
layerType = this._client.getNode(base.getBaseId()),
|
||||
color;
|
||||
|
||||
desc.baseName = base.getAttribute(nodePropertyNames.Attributes.name);
|
||||
if (layerType) {
|
||||
desc.layerType = layerType.getAttribute(nodePropertyNames.Attributes.name);
|
||||
|
||||
color = this._config.LayerColors[desc.layerType];
|
||||
if (!color) {
|
||||
this._logger.warn(`No color found for ${desc.layerType}`);
|
||||
color = this._config.DefaultColor;
|
||||
}
|
||||
desc.color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
ArchEditorControl.prototype._getValidInitialNodes = function() {
|
||||
return this._client.getChildrenMeta(this._currentNodeId).items
|
||||
// For now, anything is possible!
|
||||
// FIXME
|
||||
.map(info => this._getAllDescendentIds(info.id))
|
||||
.reduce((prev, curr) => prev.concat(curr))
|
||||
// Filter all abstract nodes
|
||||
.filter(nodeId => {
|
||||
return !this._client.getNode(nodeId).isAbstract();
|
||||
})
|
||||
.map(id => this._getObjectDescriptor(id))
|
||||
.filter(obj => !obj.isConnection && obj.name !== 'Connection');
|
||||
// For now, anything is possible!
|
||||
// FIXME
|
||||
.map(info => this._getAllDescendentIds(info.id))
|
||||
.reduce((prev, curr) => prev.concat(curr))
|
||||
// Filter all abstract nodes
|
||||
.filter(nodeId => {
|
||||
return !this._client.getNode(nodeId).isAbstract();
|
||||
})
|
||||
.map(id => this._getObjectDescriptor(id))
|
||||
.filter(obj => !obj.isConnection && obj.name !== 'Connection');
|
||||
};
|
||||
|
||||
return ArchEditorControl;
|
||||
|
||||
@@ -29,6 +29,7 @@ define([
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
@@ -55,6 +56,7 @@ define([
|
||||
this.control = new ArchEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'panels/TilingViz/TilingVizPanel',
|
||||
'panels/SerializeEditor/SerializeEditorPanel',
|
||||
'panels/DeserializeEditor/DeserializeEditorPanel',
|
||||
'underscore'
|
||||
], function (
|
||||
TilingViz,
|
||||
SerializeEditor,
|
||||
DeserializeEditor,
|
||||
_
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var DataTypeEditorPanel;
|
||||
|
||||
DataTypeEditorPanel = function (layoutManager, params) {
|
||||
TilingViz.call(this, layoutManager, params);
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(DataTypeEditorPanel.prototype, TilingViz.prototype);
|
||||
|
||||
DataTypeEditorPanel.prototype.getPanels = function () {
|
||||
return [SerializeEditor, DeserializeEditor];
|
||||
};
|
||||
|
||||
return DataTypeEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl',
|
||||
'underscore'
|
||||
], function (
|
||||
TextEditorControl,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var DeserializeEditorControl;
|
||||
|
||||
DeserializeEditorControl = function (options) {
|
||||
options.attributeName = 'deserialize';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(
|
||||
DeserializeEditorControl.prototype,
|
||||
TextEditorControl.prototype
|
||||
);
|
||||
|
||||
// input/output updates are actually activeNode updates
|
||||
DeserializeEditorControl.prototype._onUpdate = function (id) {
|
||||
if (id === this._currentNodeId) {
|
||||
TextEditorControl.prototype._onUpdate.call(this, this._currentNodeId);
|
||||
}
|
||||
};
|
||||
|
||||
return DeserializeEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed Jun 01 2016 14:45:18 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/DeserializeEditor/DeserializeEditorWidget',
|
||||
'./DeserializeEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
DeserializeEditorWidget,
|
||||
DeserializeEditorControl) {
|
||||
'use strict';
|
||||
|
||||
var DeserializeEditorPanel;
|
||||
|
||||
DeserializeEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'DeserializeEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(DeserializeEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(DeserializeEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
DeserializeEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new DeserializeEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new DeserializeEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
DeserializeEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
DeserializeEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
DeserializeEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
DeserializeEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
DeserializeEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return DeserializeEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Tue May 24 2016 10:15:19 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'deepforge/viz/PipelineControl',
|
||||
'underscore'
|
||||
], function (
|
||||
EasyDAGControl,
|
||||
PipelineControl,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ExecutionViewControl;
|
||||
|
||||
ExecutionViewControl = function (options) {
|
||||
EasyDAGControl.call(this, options);
|
||||
this.addedNodes = {};
|
||||
};
|
||||
|
||||
_.extend(
|
||||
ExecutionViewControl.prototype,
|
||||
EasyDAGControl.prototype,
|
||||
PipelineControl.prototype
|
||||
);
|
||||
|
||||
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
|
||||
ExecutionViewControl.prototype.TERRITORY_RULE = {children: 4};
|
||||
ExecutionViewControl.prototype.DEFAULT_DECORATOR = 'JobDecorator';
|
||||
|
||||
ExecutionViewControl.prototype._onLoad = function(id) {
|
||||
var desc = this._getObjectDescriptor(id);
|
||||
if (desc.parentId === this._currentNodeId) {
|
||||
this.addedNodes[id] = true;
|
||||
EasyDAGControl.prototype._onLoad.call(this, id);
|
||||
}
|
||||
};
|
||||
|
||||
ExecutionViewControl.prototype._onUnload = function(id) {
|
||||
if (this.addedNodes[id] === true) {
|
||||
EasyDAGControl.prototype._onUnload.call(this, id);
|
||||
delete this.addedNodes[id];
|
||||
}
|
||||
};
|
||||
|
||||
ExecutionViewControl.prototype._onUpdate = function(id) {
|
||||
if (this.addedNodes[id] === true) {
|
||||
EasyDAGControl.prototype._onUpdate.call(this, id);
|
||||
}
|
||||
};
|
||||
|
||||
// Add the connection detection
|
||||
return ExecutionViewControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Tue May 24 2016 10:15:19 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/ExecutionView/ExecutionViewWidget',
|
||||
'./ExecutionViewControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
ExecutionViewWidget,
|
||||
ExecutionViewControl) {
|
||||
'use strict';
|
||||
|
||||
var ExecutionViewPanel;
|
||||
|
||||
ExecutionViewPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'ExecutionViewPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(ExecutionViewPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(ExecutionViewPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
ExecutionViewPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new ExecutionViewWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new ExecutionViewControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
ExecutionViewPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
ExecutionViewPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
ExecutionViewPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
ExecutionViewPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
ExecutionViewPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return ExecutionViewPanel;
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
/*globals define, _, WebGMEGlobal, $ */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* @author rkereskenyi / https://github.com/rkereskenyi
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBase',
|
||||
'js/Widgets/NetworkStatus/NetworkStatusWidget',
|
||||
'js/Widgets/BranchStatus/BranchStatusWidget',
|
||||
'js/Widgets/BranchSelector/BranchSelectorWidget',
|
||||
'js/Widgets/KeyboardManager/KeyboardManagerWidget',
|
||||
'js/Widgets/Notification/NotificationWidget'
|
||||
], function (PanelBase,
|
||||
NetworkStatusWidget,
|
||||
BranchStatusWidget,
|
||||
BranchSelectorWidget,
|
||||
KeyboardManagerWidget,
|
||||
NotificationWidget) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var FooterPanel,
|
||||
__parent__ = PanelBase;
|
||||
|
||||
FooterPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBase.OPTIONS.LOGGER_INSTANCE_NAME] = 'FooterPanel';
|
||||
|
||||
//call parent's constructor
|
||||
__parent__.apply(this, [options]);
|
||||
|
||||
this._client = params.client;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('FooterPanel ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(FooterPanel.prototype, __parent__.prototype);
|
||||
|
||||
FooterPanel.prototype._initialize = function () {
|
||||
//main container
|
||||
var navBar = $('<div/>', {class: 'navbar navbar-inverse navbar-fixed-bottom'}),
|
||||
navBarInner = $('<div/>', {class: 'navbar-inner'}),
|
||||
separator = $('<div class="spacer pull-right"></div>'),
|
||||
widgetPlaceHolder = $('<div class="pull-right"></div>'),
|
||||
keyBoardManagerEl,
|
||||
networkStatusEl,
|
||||
branchStatusEl,
|
||||
notificationEl;
|
||||
|
||||
navBar.append(navBarInner);
|
||||
this.$el.append(navBar);
|
||||
|
||||
//padding from screen right edge
|
||||
navBarInner.append(separator.clone());
|
||||
|
||||
//keyboard enable/disbale widget (NOTE: only on non touch device)
|
||||
if (WebGMEGlobal.SUPPORTS_TOUCH !== true) {
|
||||
keyBoardManagerEl = widgetPlaceHolder.clone();
|
||||
new KeyboardManagerWidget(keyBoardManagerEl);
|
||||
navBarInner.append(keyBoardManagerEl).append(separator.clone());
|
||||
}
|
||||
|
||||
networkStatusEl = widgetPlaceHolder.clone();
|
||||
new NetworkStatusWidget(networkStatusEl, this._client);
|
||||
navBarInner.append(networkStatusEl).append(separator.clone());
|
||||
|
||||
notificationEl = widgetPlaceHolder.clone();
|
||||
new NotificationWidget(notificationEl, this._client);
|
||||
navBarInner.append(notificationEl).append(separator.clone());
|
||||
|
||||
branchStatusEl = widgetPlaceHolder.clone();
|
||||
new BranchStatusWidget(branchStatusEl, this._client);
|
||||
navBarInner.append(branchStatusEl).append(separator.clone());
|
||||
};
|
||||
|
||||
return FooterPanel;
|
||||
});
|
||||
@@ -1,35 +1,105 @@
|
||||
/*globals WebGMEGlobal*/
|
||||
/*globals define, Materialize, WebGMEGlobal*/
|
||||
// These are actions defined for specific meta types. They are evaluated from
|
||||
// the context of the ForgeActionButton
|
||||
define([], function() {
|
||||
var ROOT_ID = '',
|
||||
CREATE_MODEL_TXT = 'Create new model';
|
||||
define([
|
||||
'js/RegistryKeys'
|
||||
], function(
|
||||
REGISTRY_KEYS
|
||||
) {
|
||||
var instances = [
|
||||
'Architecture',
|
||||
'Pipeline'
|
||||
],
|
||||
metaNodes = [
|
||||
'Operation',
|
||||
'Data'
|
||||
],
|
||||
create = {};
|
||||
|
||||
var createNewArchitecture = function(type) {
|
||||
return createNew.call(this, 'Architecture');
|
||||
};
|
||||
var createNew = function(type, metasheetName) {
|
||||
var newId,
|
||||
baseId,
|
||||
msg = `Created new ${type + (metasheetName ? ' prototype' : '')}`;
|
||||
|
||||
var createNewPipeline = function(type) {
|
||||
return createNew.call(this, 'Pipeline');
|
||||
};
|
||||
|
||||
var createNew = function(type) {
|
||||
// Create CNN node in the current dir
|
||||
// Get CNN node type
|
||||
var parentId = this._currentNodeId,
|
||||
baseId = this.client.getAllMetaNodes()
|
||||
baseId = this.client.getAllMetaNodes()
|
||||
.find(node => node.getAttribute('name') === type)
|
||||
.getId();
|
||||
|
||||
this.client.createChild({parentId, baseId});
|
||||
this.client.startTransaction(msg);
|
||||
newId = this.createNamedNode(baseId, !!metasheetName);
|
||||
|
||||
if (metasheetName) {
|
||||
this.addToMetaSheet(newId, metasheetName);
|
||||
}
|
||||
|
||||
this.client.completeTransaction();
|
||||
|
||||
WebGMEGlobal.State.registerActiveObject(newId);
|
||||
return newId;
|
||||
};
|
||||
|
||||
|
||||
instances.forEach(type => {
|
||||
create[type] = function() {
|
||||
return createNew.call(this, type);
|
||||
};
|
||||
});
|
||||
|
||||
metaNodes.forEach(type => {
|
||||
create[type] = function() {
|
||||
return createNew.call(this, type, type);
|
||||
};
|
||||
});
|
||||
|
||||
var createLayer = function() {
|
||||
// Prompt the base type
|
||||
this.promptLayerType().then(selected => {
|
||||
var baseId = selected.node.id,
|
||||
typeName = this.client.getNode(baseId).getAttribute('name'),
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
msg = `Created new custom ${typeName} layer`,
|
||||
newId,
|
||||
customLayerId,
|
||||
name;
|
||||
|
||||
for (var i = metanodes.length; i--;) {
|
||||
name = metanodes[i].getAttribute('name');
|
||||
if (name === 'CustomLayer') {
|
||||
customLayerId = metanodes[i].getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.client.startTransaction(msg);
|
||||
|
||||
newId = this.createNamedNode(baseId, true);
|
||||
this.addToMetaSheet(newId, 'CustomLayers');
|
||||
this.client.addMixin(newId, customLayerId);
|
||||
this.client.setRegistry(newId, REGISTRY_KEYS.IS_ABSTRACT, false);
|
||||
|
||||
this.client.completeTransaction();
|
||||
|
||||
WebGMEGlobal.State.registerActiveObject(newId);
|
||||
});
|
||||
};
|
||||
////////////// Downloading files //////////////
|
||||
var downloadAttrs = [
|
||||
'data',
|
||||
'execFiles'
|
||||
],
|
||||
download = {};
|
||||
|
||||
downloadAttrs.forEach(attr => {
|
||||
download[attr] = function() {
|
||||
return downloadButton.call(this, attr);
|
||||
};
|
||||
});
|
||||
|
||||
// Add download model button
|
||||
var downloadButton = function() {
|
||||
var downloadButton = function(attr) {
|
||||
var id = this._currentNodeId,
|
||||
node = this.client.getNode(id),
|
||||
hash = node.getAttribute('data'),
|
||||
url;
|
||||
hash = node.getAttribute(attr);
|
||||
|
||||
if (hash) {
|
||||
return '/rest/blob/download/' + hash;
|
||||
@@ -37,27 +107,136 @@ define([], function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
var UPLOAD_PLUGIN = 'ImportArtifact',
|
||||
DATA_TYPE_CONFIG = {
|
||||
name: 'dataTypeId',
|
||||
displayName: 'Data Type Id',
|
||||
valueType: 'string',
|
||||
valueItems: []
|
||||
};
|
||||
var uploadArtifact = function() {
|
||||
// Get the data types
|
||||
var dataBase,
|
||||
dataBaseId,
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
dataTypes = []; // TODO
|
||||
|
||||
dataBase = metanodes.find(n => n.getAttribute('name') === 'Data');
|
||||
|
||||
if (!dataBase) {
|
||||
this.logger.error('Could not find the base Data node!');
|
||||
return;
|
||||
}
|
||||
|
||||
dataBaseId = dataBase.getId();
|
||||
dataTypes = metanodes.filter(n => this.client.isTypeOf(n.getId(), dataBaseId))
|
||||
.map(node => node.getAttribute('name'));
|
||||
|
||||
this.logger.info(`Found ${dataTypes.length} data types`);
|
||||
|
||||
// Add the target type to the pluginMetadata... hacky :/
|
||||
// FIXME: this should create it's own plugin dialog which allows
|
||||
// users to select the data type
|
||||
var metadata = WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN],
|
||||
config = metadata.configStructure
|
||||
.find(opt => opt.name === DATA_TYPE_CONFIG.name);
|
||||
|
||||
if (!config) {
|
||||
config = DATA_TYPE_CONFIG;
|
||||
WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN].configStructure.push(config);
|
||||
}
|
||||
|
||||
config.valueItems = dataTypes;
|
||||
config.value = dataTypes[0];
|
||||
|
||||
WebGMEGlobal.InterpreterManager.configureAndRun(metadata, (result) => {
|
||||
if (!result) {
|
||||
Materialize.toast('Artifact upload failed!', 2000);
|
||||
return;
|
||||
}
|
||||
this.logger.info('Finished uploading ' + UPLOAD_PLUGIN);
|
||||
Materialize.toast('Artifact upload complete!', 2000);
|
||||
});
|
||||
};
|
||||
|
||||
var returnToLastPipeline = () =>
|
||||
WebGMEGlobal.State.registerActiveObject(window.DeepForge.lastPipeline);
|
||||
return {
|
||||
// Meta nodes
|
||||
MyPipelines_META: [
|
||||
{
|
||||
name: 'Create new pipeline',
|
||||
icon: 'queue',
|
||||
action: create.Pipeline
|
||||
}
|
||||
],
|
||||
MyArchitectures_META: [
|
||||
{
|
||||
name: 'Create new architecture',
|
||||
icon: 'queue',
|
||||
action: create.Architecture
|
||||
}
|
||||
],
|
||||
MyDataTypes_META: [
|
||||
{
|
||||
name: 'Create new data type',
|
||||
icon: 'queue',
|
||||
action: create.Data
|
||||
}
|
||||
],
|
||||
MyLayers_META: [
|
||||
{
|
||||
name: 'Create new layer',
|
||||
icon: 'queue',
|
||||
action: createLayer
|
||||
}
|
||||
],
|
||||
MyOperations_META: [
|
||||
{
|
||||
name: 'Create new operation',
|
||||
icon: 'queue',
|
||||
action: create.Operation
|
||||
}
|
||||
],
|
||||
MyArtifacts_META: [
|
||||
{
|
||||
name: 'Upload artifact',
|
||||
icon: 'swap_vert',
|
||||
action: uploadArtifact
|
||||
}
|
||||
],
|
||||
Operation_META: [
|
||||
{
|
||||
name: 'Return to Pipeline',
|
||||
icon: 'input',
|
||||
filter: () => window.DeepForge && window.DeepForge.lastPipeline,
|
||||
action: returnToLastPipeline
|
||||
}
|
||||
],
|
||||
|
||||
// Instances
|
||||
Data: [
|
||||
{
|
||||
name: 'Download',
|
||||
icon: 'play_for_work',
|
||||
href: downloadButton // function to create href url
|
||||
href: download.data // function to create href url
|
||||
}
|
||||
],
|
||||
|
||||
Pipelines: [
|
||||
Job: [
|
||||
{
|
||||
name: 'Create new pipeline',
|
||||
icon: 'queue',
|
||||
action: createNewPipeline
|
||||
name: 'Download Execution Files',
|
||||
icon: 'play_for_work',
|
||||
href: download.execFiles
|
||||
}
|
||||
],
|
||||
Architectures: [
|
||||
Pipeline: [
|
||||
{
|
||||
name: 'Create new architecture',
|
||||
name: 'Create new node',
|
||||
icon: 'queue',
|
||||
action: createNewArchitecture
|
||||
priority: 2,
|
||||
action: function() {
|
||||
this.onCreateInitialNode();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*globals define, _ */
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'panel/FloatingActionButton/FloatingActionButton',
|
||||
'deepforge/viz/PipelineControl',
|
||||
'./Actions',
|
||||
'widgets/EasyDAG/AddNodeDialog',
|
||||
'js/RegistryKeys',
|
||||
'js/Panels/MetaEditor/MetaEditorConstants',
|
||||
'q',
|
||||
'text!./PluginConfig.json'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
PluginButton,
|
||||
PipelineControl,
|
||||
ACTIONS,
|
||||
AddNodeDialog,
|
||||
REGISTRY_KEYS,
|
||||
META_CONSTANTS,
|
||||
Q,
|
||||
PluginConfig
|
||||
) {
|
||||
'use strict';
|
||||
@@ -17,27 +27,47 @@ define([
|
||||
var ForgeActionButton= function (layoutManager, params) {
|
||||
PluginButton.call(this, layoutManager, params);
|
||||
this._pluginConfig = JSON.parse(PluginConfig);
|
||||
this._client = this.client;
|
||||
this._actions = [];
|
||||
|
||||
WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT,
|
||||
this.addActionsForObject, this);
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
// inherit from PanelBaseWithHeader
|
||||
_.extend(ForgeActionButton.prototype, PluginButton.prototype);
|
||||
_.extend(
|
||||
ForgeActionButton.prototype,
|
||||
PluginButton.prototype,
|
||||
PipelineControl.prototype
|
||||
);
|
||||
|
||||
ForgeActionButton.prototype.addActionsForObject = function(models, nodeId) {
|
||||
var baseName,
|
||||
node = this.client.getNode(nodeId),
|
||||
ForgeActionButton.prototype.findActionsFor = function(nodeId) {
|
||||
var node = this.client.getNode(nodeId),
|
||||
base = this.client.getNode(node.getMetaTypeId()),
|
||||
base,
|
||||
isMeta = base && base.getId() === node.getId(),
|
||||
suffix = isMeta ? '_META' : '',
|
||||
actions,
|
||||
i;
|
||||
basename;
|
||||
|
||||
// Get node baseName and look up actions
|
||||
baseName = base ? base.getAttribute('name') : 'ROOT';
|
||||
while (base && !(actions && actions.length)) {
|
||||
basename = base.getAttribute('name') + suffix;
|
||||
base = this.client.getNode(base.getBaseId());
|
||||
actions = ACTIONS[basename];
|
||||
if (actions) {
|
||||
actions = actions.filter(action => !action.filter || action.filter());
|
||||
}
|
||||
}
|
||||
|
||||
return actions || [];
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.onNodeLoad = function(nodeId) {
|
||||
PluginButton.prototype.onNodeLoad.call(this, nodeId);
|
||||
this.addActionsForObject(nodeId);
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.addActionsForObject = function(nodeId) {
|
||||
var actions = this.findActionsFor(nodeId),
|
||||
i;
|
||||
|
||||
// Remove old actions
|
||||
for (i = this._actions.length; i--;) {
|
||||
@@ -45,7 +75,6 @@ define([
|
||||
}
|
||||
|
||||
// Get node name and look up actions
|
||||
actions = ACTIONS[baseName] || [];
|
||||
for (i = actions.length; i--;) {
|
||||
this.buttons[actions[i].name] = actions[i];
|
||||
}
|
||||
@@ -54,5 +83,121 @@ define([
|
||||
this.update();
|
||||
};
|
||||
|
||||
// Helper functions
|
||||
ForgeActionButton.prototype.addToMetaSheet = function(nodeId, metasheetName) {
|
||||
var root = this.client.getNode(CONSTANTS.PROJECT_ROOT_ID),
|
||||
metatabs = root.getRegistry(REGISTRY_KEYS.META_SHEETS),
|
||||
metatab = metatabs.find(tab => tab.title === metasheetName) || metatabs[0],
|
||||
metatabId = metatab.SetID;
|
||||
|
||||
// Add to the general meta
|
||||
this.client.addMember(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME
|
||||
);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
|
||||
// Add to the specific sheet
|
||||
this.client.addMember(CONSTANTS.PROJECT_ROOT_ID, nodeId, metatabId);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
metatabId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.createNamedNode = function(baseId, isMeta) {
|
||||
var parentId = this._currentNodeId,
|
||||
newId = this.client.createChild({parentId, baseId}),
|
||||
basename = 'New' + this.client.getNode(baseId).getAttribute('name'),
|
||||
newName = this.getUniqueName(parentId, basename);
|
||||
|
||||
// If instance, make the first char lowercase
|
||||
if (!isMeta) {
|
||||
newName = newName.substring(0, 1).toLowerCase() + newName.substring(1);
|
||||
}
|
||||
this.client.setAttributes(newId, 'name', newName);
|
||||
return newId;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.getUniqueName = function(parentId, basename) {
|
||||
var pNode = this.client.getNode(parentId),
|
||||
children = pNode.getChildrenIds().map(id => this.client.getNode(id)),
|
||||
name = basename,
|
||||
exists = {},
|
||||
i = 2;
|
||||
|
||||
children.forEach(child => exists[child.getAttribute('name')] = true);
|
||||
|
||||
while (exists[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.getLayerTypeDesc = function(node) {
|
||||
var decManager = this.client.decoratorManager,
|
||||
desc = {};
|
||||
|
||||
desc.id = node.getId();
|
||||
desc.name = node.getAttribute('name');
|
||||
desc.baseName = desc.name;
|
||||
desc.attributes = {};
|
||||
desc.pointers = {};
|
||||
|
||||
// Get the decorator
|
||||
desc.Decorator = decManager.getDecoratorForWidget('EllipseDecorator', 'EasyDAG');
|
||||
|
||||
// Set the color
|
||||
desc.color = '#9e9e9e';
|
||||
return desc;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.promptLayerType = function() {
|
||||
// Prompt for the new custom layer's base type
|
||||
var deferred = Q.defer(),
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
baseLayerId = metanodes.find(n => n.getAttribute('name') === 'Layer').getId(),
|
||||
layerType,
|
||||
types;
|
||||
|
||||
// PoA:
|
||||
// - Get the layer type ids
|
||||
// - Create the descriptors
|
||||
// - Get the color for the given types
|
||||
// - Move colors to a constants dir?
|
||||
|
||||
// Get the layer type ids
|
||||
layerType = metanodes
|
||||
.filter(node => node.getBaseId() === baseLayerId);
|
||||
|
||||
// - Create the descriptors
|
||||
types = layerType.map(node => {
|
||||
return {
|
||||
node: this.getLayerTypeDesc(node)
|
||||
};
|
||||
});
|
||||
|
||||
AddNodeDialog.prompt(types, deferred.resolve);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return ForgeActionButton;
|
||||
});
|
||||
|
||||
@@ -10,5 +10,9 @@
|
||||
"ImportTorch": {
|
||||
"icon": "import_export",
|
||||
"priority": -1
|
||||
},
|
||||
"GenerateExecFile": {
|
||||
"icon": "play_for_work",
|
||||
"priority": -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl'
|
||||
], function (
|
||||
TextEditorControl
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var NO_CODE_MESSAGE = '-- <%= name %> is not an editable layer!',
|
||||
LayerEditorControl;
|
||||
|
||||
LayerEditorControl = function (options) {
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(LayerEditorControl.prototype, TextEditorControl.prototype);
|
||||
|
||||
LayerEditorControl.prototype.loadMetaNodes = function () {
|
||||
return this._client.getAllMetaNodes();
|
||||
};
|
||||
|
||||
// This next function retrieves the relevant node information for the widget
|
||||
LayerEditorControl.prototype._getObjectDescriptor = function (nodeId) {
|
||||
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, nodeId),
|
||||
node = this._client.getNode(nodeId),
|
||||
hasCode = node.getValidAttributeNames().indexOf('code') > -1,
|
||||
template;
|
||||
|
||||
// Get own attribute, if set. Otherwise, set the text to the parent's populated
|
||||
// template
|
||||
this.loadMetaNodes();
|
||||
if (hasCode) { // is a custom layer
|
||||
if (!node.getOwnAttribute('code')) {
|
||||
// Retrieve the template from the mixin
|
||||
template = node.getMixinPaths()
|
||||
.map(id => this._client.getNode(id).getAttribute('code'))
|
||||
.find(code => !!code) || NO_CODE_MESSAGE;
|
||||
}
|
||||
} else {
|
||||
template = NO_CODE_MESSAGE;
|
||||
}
|
||||
|
||||
if (template) {
|
||||
desc.text = _.template(template)(desc);
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
LayerEditorControl.prototype.saveTextFor = function (id, text) {
|
||||
var r = /:__init\((.*)\)/,
|
||||
match = text.match(r),
|
||||
textMatch = match && match[1],
|
||||
node = this._client.getNode(id),
|
||||
currentAttrs = node.getValidAttributeNames(),
|
||||
attributes = [],
|
||||
msg = `Updating layer definition for ${node.getAttribute('name')}`;
|
||||
|
||||
// Parse the attributes and update the node!
|
||||
if (textMatch) {
|
||||
attributes = textMatch.split(',')
|
||||
.map(arg => arg.replace(/\s+/g, '')) // trim white space
|
||||
.filter(arg => !!arg); // no empty strings!
|
||||
} else { // inheriting __init
|
||||
attributes = this.getInheritedAttrs(text);
|
||||
}
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
|
||||
TextEditorControl.prototype.saveTextFor.call(this, id, text);
|
||||
|
||||
// Remove old attributes
|
||||
_.difference(currentAttrs, attributes)
|
||||
.forEach(attr => this._client.removeAttributeSchema(id, attr));
|
||||
|
||||
attributes.forEach((attr, i) =>
|
||||
this._client.setAttributeSchema(id, attr, {type: 'string', argindex: i}));
|
||||
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
LayerEditorControl.prototype.getInheritedAttrs = function (code) {
|
||||
// Get the base class
|
||||
var r = /torch.class\((.*)\)/,
|
||||
match = code.match(r),
|
||||
baseType,
|
||||
metanode,
|
||||
textMatch = match && match[1];
|
||||
|
||||
if (textMatch) {
|
||||
baseType = textMatch.split(',')[1]
|
||||
.replace(/^\s*['"]nn\./, '')
|
||||
.replace(/['"]\s*$/, '');
|
||||
|
||||
this._logger.debug(`inheriting the attributes from ${baseType}`);
|
||||
|
||||
// Get the meta node and valid attribute names
|
||||
metanode = this._client.getAllMetaNodes()
|
||||
.find(node => node.getAttribute('name') === baseType);
|
||||
|
||||
if (metanode) {
|
||||
return metanode.getValidAttributeNames()
|
||||
.filter(attr => attr !== 'name');
|
||||
} else {
|
||||
// Check if the type is known by torch
|
||||
this._logger.warn(`Unknown base type ${baseType}. Assuming attributes are []`);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
return LayerEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/TextEditor/TextEditorWidget',
|
||||
'./LayerEditorControl'
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
LayerEditorControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var LayerEditorPanel;
|
||||
|
||||
LayerEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LayerEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(LayerEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(LayerEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
LayerEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new TextEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new LayerEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
LayerEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
LayerEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return LayerEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
// This is a read-only view of the 'stdout' attribute for a Job node
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl'
|
||||
], function (
|
||||
TextEditorControl
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var LogViewerControl;
|
||||
|
||||
LogViewerControl = function (options) {
|
||||
options.attributeName = 'stdout';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(LogViewerControl.prototype, TextEditorControl.prototype);
|
||||
|
||||
LogViewerControl.prototype._onUpdate = function (id) {
|
||||
if (id === this._currentNodeId) {
|
||||
TextEditorControl.prototype._onUpdate.call(this, id);
|
||||
}
|
||||
};
|
||||
|
||||
return LogViewerControl;
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed Jun 15 2016 14:06:10 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/LogViewer/LogViewerWidget',
|
||||
'./LogViewerControl'
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
LogViewerWidget,
|
||||
LogViewerControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var LogViewerPanel;
|
||||
|
||||
LogViewerPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LogViewerPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(LogViewerPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(LogViewerPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
LogViewerPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new LogViewerWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new LogViewerControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
LogViewerPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
LogViewerPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return LogViewerPanel;
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 12:00:46 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl',
|
||||
'deepforge/viz/OperationControl',
|
||||
'underscore'
|
||||
], function (
|
||||
TextEditorControl,
|
||||
OperationControl,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OperationCodeEditorControl;
|
||||
|
||||
OperationCodeEditorControl = function (options) {
|
||||
options.attributeName = 'code';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(
|
||||
OperationCodeEditorControl.prototype,
|
||||
OperationControl.prototype,
|
||||
TextEditorControl.prototype
|
||||
);
|
||||
|
||||
// Override ObjectDescriptor
|
||||
OperationCodeEditorControl.prototype.TERRITORY_RULE = {children: 3};
|
||||
OperationCodeEditorControl.prototype._getObjectDescriptor = function (id) {
|
||||
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, id),
|
||||
node = this._client.getNode(id);
|
||||
|
||||
// Add the inputs, outputs, references, and attributes
|
||||
desc.inputs = this.getOperationInputs(node).map(id => this.formatIO(id));
|
||||
desc.outputs = this.getOperationOutputs(node).map(id => this.formatIO(id));
|
||||
desc.references = node.getPointerNames().filter(name => name !== 'base');
|
||||
return desc;
|
||||
};
|
||||
|
||||
// This will be changed when the input/output reps are updated (soon)
|
||||
OperationCodeEditorControl.prototype.formatIO = function (id) {
|
||||
// parse arguments are in the form 'arg: Type1, arg2: Type2'
|
||||
// and return [[arg1, Type1], [arg2, Type2]]
|
||||
var node = this._client.getNode(id),
|
||||
mNode = this._client.getNode(node.getMetaTypeId());
|
||||
|
||||
return [node, mNode].map(n => n.getAttribute('name'));
|
||||
};
|
||||
|
||||
// input/output updates are actually activeNode updates
|
||||
OperationCodeEditorControl.prototype._onUpdate = function (id) {
|
||||
if (id === this._currentNodeId || this.hasMetaName(id, 'Data')) {
|
||||
TextEditorControl.prototype._onUpdate.call(this, this._currentNodeId);
|
||||
}
|
||||
};
|
||||
|
||||
return OperationCodeEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,102 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 12:00:46 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/OperationCodeEditor/OperationCodeEditorWidget',
|
||||
'./OperationCodeEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
OperationCodeEditorWidget,
|
||||
OperationCodeEditorControl) {
|
||||
'use strict';
|
||||
|
||||
var OperationCodeEditorPanel;
|
||||
|
||||
OperationCodeEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'OperationCodeEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(OperationCodeEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(OperationCodeEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
OperationCodeEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new OperationCodeEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new OperationCodeEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
OperationCodeEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
OperationCodeEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
OperationCodeEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationCodeEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationCodeEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return OperationCodeEditorPanel;
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 12:00:46 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl',
|
||||
'underscore'
|
||||
], function (
|
||||
TextEditorControl,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var OperationEditorControl;
|
||||
|
||||
OperationEditorControl = function (options) {
|
||||
options.attributeName = 'code';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(OperationEditorControl.prototype, TextEditorControl.prototype);
|
||||
|
||||
// Override ObjectDescriptor
|
||||
OperationEditorControl.prototype._getObjectDescriptor = function (id) {
|
||||
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, id),
|
||||
node = this._client.getNode(id);
|
||||
// Add the inputs, outputs, references, and attributes
|
||||
desc.inputs = this._parseArgs(node.getAttribute('inputs'));
|
||||
desc.outputs = this._parseArgs(node.getAttribute('outputs'));
|
||||
desc.references = node.getPointerNames().filter(name => name !== 'base');
|
||||
return desc;
|
||||
};
|
||||
|
||||
// This will be changed when the input/output reps are updated (soon)
|
||||
OperationEditorControl.prototype._parseArgs = function (args) {
|
||||
// parse arguments are in the form 'arg: Type1, arg2: Type2'
|
||||
// and return [[arg1, Type1], [arg2, Type2]]
|
||||
return args ? args.split(',')
|
||||
.map(pair => pair.split(':').map(w => w.replace(/\s+/g, ''))) : [];
|
||||
|
||||
};
|
||||
|
||||
return OperationEditorControl;
|
||||
});
|
||||
@@ -1,98 +1,30 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*globals define, */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 12:00:46 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/OperationEditor/OperationEditorWidget',
|
||||
'./OperationEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
OperationEditorWidget,
|
||||
OperationEditorControl) {
|
||||
define([
|
||||
'panels/TilingViz/TilingVizPanel',
|
||||
'panels/OperationCodeEditor/OperationCodeEditorPanel',
|
||||
'panels/OperationInterfaceEditor/OperationInterfaceEditorPanel',
|
||||
'underscore'
|
||||
], function (
|
||||
TilingViz,
|
||||
CodeEditor,
|
||||
InterfaceEditor,
|
||||
_
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var OperationEditorPanel;
|
||||
|
||||
OperationEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'OperationEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
TilingViz.call(this, layoutManager, params);
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(OperationEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(OperationEditorPanel.prototype, IActivePanel.prototype);
|
||||
//inherit from TilingViz
|
||||
_.extend(OperationEditorPanel.prototype, TilingViz.prototype);
|
||||
|
||||
OperationEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new OperationEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new OperationEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
OperationEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
OperationEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
OperationEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
OperationEditorPanel.prototype.getPanels = function () {
|
||||
return [CodeEditor, InterfaceEditor];
|
||||
};
|
||||
|
||||
return OperationEditorPanel;
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/*globals define*/
|
||||
define([
|
||||
], function(
|
||||
) {
|
||||
'use strict';
|
||||
var OperationInterfaceEditorEvents = function() {
|
||||
this._widget.allDataTypeIds = this.allDataTypeIds.bind(this);
|
||||
this._widget.allValidReferences = this.allValidReferences.bind(this);
|
||||
this._widget.addRefTo = this.addRefTo.bind(this);
|
||||
this._widget.changePtrName = this.changePtrName.bind(this);
|
||||
this._widget.removePtr = this.removePtr.bind(this);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.allValidReferences = function() {
|
||||
// Get all meta nodes that...
|
||||
// - are not data, pipeline or operation (or fco!)
|
||||
// - have a plugin defined?
|
||||
// Currently you can't reference operations or pipelines.
|
||||
var notTypes = ['Data', 'Operation', 'Pipeline'];
|
||||
return this._client.getAllMetaNodes()
|
||||
.filter(node => {
|
||||
var plugins = node.getRegistry('validPlugins');
|
||||
// Convention is enforced; if the plugin generates lua artifacts,
|
||||
// it should be called `Generate`.. (something)
|
||||
return plugins && plugins.indexOf('Generate') !== -1;
|
||||
})
|
||||
.filter(node => notTypes.reduce((valid, name) =>
|
||||
valid && !this.hasMetaName(node.getId(), name), true))
|
||||
.filter(node => node.getAttribute('name') !== 'FCO')
|
||||
.map(node => {
|
||||
return {
|
||||
node: this._getObjectDescriptor(node.getId())
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.allDataTypeIds = function() {
|
||||
return this.allDataTypes().map(node => node.getId());
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.allDataTypes = function() {
|
||||
return this._client.getAllMetaNodes()
|
||||
.filter(node => this.hasMetaName(node.getId(), 'Data'));
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype._getValidSuccessorNodes = function(nodeId) {
|
||||
// Return all data types in the meta
|
||||
if (nodeId !== this._currentNodeId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.allDataTypeIds().map(id => {
|
||||
return {
|
||||
node: this._getObjectDescriptor(id)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype._getDataName = function(cntrId, typeId) {
|
||||
var otherIds = this._client.getNode(cntrId).getChildrenIds(),
|
||||
otherNames = otherIds.map(id => this._client.getNode(id).getAttribute('name')),
|
||||
baseName = this._client.getNode(typeId).getAttribute('name').toLowerCase(),
|
||||
name = baseName,
|
||||
i = 1;
|
||||
|
||||
while (otherNames.indexOf(name) !== -1) {
|
||||
i++;
|
||||
name = baseName + '_' + i;
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.getRefName = function(node, basename) {
|
||||
// Get a dict of all invalid ptr names for the given node
|
||||
var invalid = {},
|
||||
name,
|
||||
i = 2;
|
||||
|
||||
name = basename;
|
||||
node.getSetNames().concat(node.getPointerNames())
|
||||
.forEach(ptr => invalid[ptr] = true);
|
||||
|
||||
while (invalid[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.addRefTo = function(targetId) {
|
||||
// Create a reference from the current node to the given type
|
||||
var opNode = this._client.getNode(this._currentNodeId),
|
||||
target = this._client.getNode(targetId),
|
||||
desiredName = target.getAttribute('name').toLowerCase(),
|
||||
ptrName = this.getRefName(opNode, desiredName),
|
||||
msg = `Adding ref "${ptrName}" to operation "${opNode.getAttribute('name')}"`;
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
this._client.setPointerMeta(this._currentNodeId, ptrName, {
|
||||
min: 1,
|
||||
max: 1,
|
||||
items: [
|
||||
{
|
||||
id: targetId,
|
||||
max: 1
|
||||
}
|
||||
]
|
||||
});
|
||||
this._client.makePointer(this._currentNodeId, ptrName, null);
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.changePtrName = function(from, to) {
|
||||
var opNode = this._client.getNode(this._currentNodeId),
|
||||
name = opNode.getAttribute('name'),
|
||||
msg = `Renaming ref from "${from}" to "${to}" for ${name}`,
|
||||
meta = this._client.getPointerMeta(this._currentNodeId, from),
|
||||
ptrName;
|
||||
|
||||
ptrName = this.getRefName(opNode, to);
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
|
||||
// Currently, this will not update children already using old name...
|
||||
this._client.deleteMetaPointer(this._currentNodeId, from);
|
||||
this._client.delPointer(this._currentNodeId, from);
|
||||
this._client.setPointerMeta(this._currentNodeId, ptrName, meta);
|
||||
this._client.makePointer(this._currentNodeId, ptrName, null);
|
||||
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype.removePtr = function(name) {
|
||||
var opName = this._client.getNode(this._currentNodeId).getAttribute('name'),
|
||||
msg = `Removing ref "${name}" from "${opName}" operation`;
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
// Currently, this will not update children already using old name...
|
||||
this._client.deleteMetaPointer(this._currentNodeId, name);
|
||||
this._client.delPointer(this._currentNodeId, name);
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorEvents.prototype._createConnectedNode = function(typeId, isInput) {
|
||||
var node = this._client.getNode(this._currentNodeId),
|
||||
name = node.getAttribute('name'),
|
||||
cntrs = node.getChildrenIds(),
|
||||
cntrType = isInput ? 'Inputs' : 'Outputs',
|
||||
cntrId = cntrs.find(id => this.hasMetaName(id, cntrType)),
|
||||
dataName = this._getDataName(cntrId, typeId),
|
||||
msg;
|
||||
|
||||
msg = `Adding ${isInput ? 'input' : 'output'} "${dataName}" to ${name} interface`;
|
||||
this._client.startTransaction(msg);
|
||||
var id = this._client.createChild({
|
||||
parentId: cntrId,
|
||||
baseId: typeId
|
||||
});
|
||||
|
||||
// Set the name of the new input
|
||||
this._client.setAttributes(id, 'name', dataName);
|
||||
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
return OperationInterfaceEditorEvents;
|
||||
});
|
||||
@@ -0,0 +1,286 @@
|
||||
/*globals define, */
|
||||
/*jshint browser: true*/
|
||||
// OpInterface visualizes the interface of the given operation and allows the
|
||||
// user to edit the meta definition of the given operation. That is, it will
|
||||
// show the operation's input data nodes as incoming connections; outputs as
|
||||
// outgoing connections and the defined attributes/ptrs in the expanded view
|
||||
// of the node.
|
||||
|
||||
define([
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'js/Constants',
|
||||
'deepforge/viz/OperationControl',
|
||||
'./OperationInterfaceEditorControl.EventHandlers',
|
||||
'underscore'
|
||||
], function (
|
||||
EasyDAGControl,
|
||||
CONSTANTS,
|
||||
OperationControl,
|
||||
OperationInterfaceEditorControlEvents,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var CONN_ID = 0,
|
||||
OperationInterfaceEditorControl;
|
||||
|
||||
OperationInterfaceEditorControl = function (options) {
|
||||
EasyDAGControl.call(this, options);
|
||||
OperationInterfaceEditorControlEvents.call(this);
|
||||
this._connections = {};
|
||||
this._pointers = {};
|
||||
};
|
||||
|
||||
_.extend(
|
||||
OperationInterfaceEditorControl.prototype,
|
||||
EasyDAGControl.prototype,
|
||||
OperationControl.prototype,
|
||||
OperationInterfaceEditorControlEvents.prototype
|
||||
);
|
||||
|
||||
OperationInterfaceEditorControl.prototype.TERRITORY_RULE = {children: 3};
|
||||
OperationInterfaceEditorControl.prototype.DEFAULT_DECORATOR = 'OpIntDecorator';
|
||||
OperationInterfaceEditorControl.prototype.selectedObjectChanged = function (nodeId) {
|
||||
this._logger.debug('activeObject nodeId \'' + nodeId + '\'');
|
||||
|
||||
// Remove current territory patterns
|
||||
if (this._currentNodeId) {
|
||||
this._client.removeUI(this._territoryId);
|
||||
}
|
||||
|
||||
this._currentNodeId = nodeId;
|
||||
this._currentNodeParentId = undefined;
|
||||
|
||||
if (typeof this._currentNodeId === 'string') {
|
||||
var node = this._client.getNode(nodeId),
|
||||
name = node.getAttribute('name'),
|
||||
parentId = node.getParentId();
|
||||
|
||||
this._widget.setTitle(name.toUpperCase());
|
||||
|
||||
if (typeof parentId === 'string') {
|
||||
this.$btnModelHierarchyUp.show();
|
||||
} else {
|
||||
this.$btnModelHierarchyUp.hide();
|
||||
}
|
||||
|
||||
this._currentNodeParentId = parentId;
|
||||
|
||||
// Put new node's info into territory rules
|
||||
this.updateTerritory();
|
||||
}
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype._eventCallback = function (events) {
|
||||
var event;
|
||||
|
||||
// Remove any events about the current node
|
||||
this._logger.debug('_eventCallback \'' + i + '\' items');
|
||||
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
event = events[i];
|
||||
switch (event.etype) {
|
||||
case CONSTANTS.TERRITORY_EVENT_LOAD:
|
||||
this._onLoad(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UPDATE:
|
||||
this._onUpdate(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UNLOAD:
|
||||
this._onUnload(event.eid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.debug('_eventCallback \'' + events.length + '\' items - DONE');
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.updateTerritory = function() {
|
||||
var nodeId = this._currentNodeId;
|
||||
|
||||
// activeNode rules
|
||||
this._territories = {};
|
||||
|
||||
this._territoryId = this._client.addUI(this, events => {
|
||||
this._eventCallback(events);
|
||||
});
|
||||
|
||||
this._territories[nodeId] = {children: 0}; // Territory "rule"
|
||||
this._client.updateTerritory(this._territoryId, this._territories);
|
||||
this._logger.debug(`OpIntEditor current territory id is ${this._territoryId}`);
|
||||
|
||||
this._territories[nodeId] = this.TERRITORY_RULE;
|
||||
|
||||
// Add the operation definitions to the territory
|
||||
var metanodes = this._client.getAllMetaNodes(),
|
||||
operation = metanodes.find(n => n.getAttribute('name') === 'Data');
|
||||
|
||||
// Get all the meta nodes that are instances of Data
|
||||
metanodes.map(n => n.getId())
|
||||
.filter(nId => this._client.isTypeOf(nId, operation.getId()))
|
||||
// Add a rule for them
|
||||
.forEach(opId => this._territories[opId] = {children: 0});
|
||||
|
||||
this._client.updateTerritory(this._territoryId, this._territories);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype._getObjectDescriptor = function(gmeId) {
|
||||
var desc = EasyDAGControl.prototype._getObjectDescriptor.call(this, gmeId);
|
||||
// Check if it is...
|
||||
// - input data
|
||||
// - output data
|
||||
// - operation node
|
||||
if (desc.id !== this._currentNodeId && this.containedInCurrent(gmeId)) {
|
||||
var cntrType = this._client.getNode(desc.parentId).getMetaTypeId();
|
||||
var cntr = this._client.getNode(cntrType).getAttribute('name');
|
||||
|
||||
desc.container = cntr.toLowerCase();
|
||||
desc.attributes = {};
|
||||
} else if (desc.id === this._currentNodeId) {
|
||||
delete desc.attributes.code;
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype._onUnload = function(gmeId) {
|
||||
EasyDAGControl.prototype._onUnload.call(this, gmeId);
|
||||
var conn = this._connections[gmeId];
|
||||
if (conn) {
|
||||
this._widget.removeNode(conn.id);
|
||||
}
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype._onLoad = function(gmeId) {
|
||||
var desc;
|
||||
if (this._currentNodeId === gmeId) {
|
||||
desc = this._getObjectDescriptor(gmeId);
|
||||
this._widget.addNode(desc);
|
||||
|
||||
// Create nodes for the valid pointers
|
||||
this.updatePtrs();
|
||||
|
||||
} else if (this.hasMetaName(gmeId, 'Data') && this.containedInCurrent(gmeId)) {
|
||||
desc = this._getObjectDescriptor(gmeId);
|
||||
this._widget.addNode(desc);
|
||||
this.createConnection(desc);
|
||||
}
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype._onUpdate = function(gmeId) {
|
||||
if (gmeId === this._currentNodeId) {
|
||||
EasyDAGControl.prototype._onUpdate.call(this, gmeId);
|
||||
|
||||
// Update the valid pointers
|
||||
this.updatePtrs();
|
||||
|
||||
} else if (this.containedInCurrent(gmeId) && this.hasMetaName(gmeId, 'Data')) {
|
||||
EasyDAGControl.prototype._onUpdate.call(this, gmeId);
|
||||
}
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.loadMeta = function() {
|
||||
// Load the metamodel. This is kinda a hack to make sure
|
||||
// the meta nodes are accessible with `this._client.getNode`
|
||||
return this._client.getAllMetaNodes();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.getPtrDescriptor = function(name) {
|
||||
var targetId = this._client.getPointerMeta(this._currentNodeId, name)
|
||||
.items[0].id,
|
||||
target = this._client.getNode(targetId),
|
||||
decManager = this._client.decoratorManager,
|
||||
Decorator = decManager.getDecoratorForWidget('OpIntPtrDecorator', 'EasyDAG');
|
||||
|
||||
return {
|
||||
id: 'ptr_'+name,
|
||||
isPointer: true,
|
||||
baseName: target.getAttribute('name'),
|
||||
Decorator: Decorator,
|
||||
attributes: {},
|
||||
name: name,
|
||||
parentId: this._currentNodeId
|
||||
};
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.updatePtrs = function() {
|
||||
// Update the pointer nodes for the current node
|
||||
var node = this._client.getNode(this._currentNodeId),
|
||||
rmPtrs,
|
||||
updatePtrs = [],
|
||||
newPtrs,
|
||||
newPtrDict = {},
|
||||
ptr;
|
||||
|
||||
// Get the pointers that should exist [name, target]
|
||||
this.loadMeta();
|
||||
newPtrs = node.getPointerNames()
|
||||
.filter(name => name !== CONSTANTS.POINTER_BASE)
|
||||
.map(name => this.getPtrDescriptor(name));
|
||||
|
||||
// Compare them to the existing...
|
||||
for (var i = newPtrs.length; i--;) {
|
||||
ptr = newPtrs[i];
|
||||
if (this._pointers[ptr.id]) { // Check for update
|
||||
updatePtrs.push(ptr);
|
||||
newPtrs.splice(i, 1);
|
||||
newPtrDict[ptr.id] = ptr;
|
||||
delete this._pointers[ptr.id];
|
||||
}
|
||||
}
|
||||
|
||||
rmPtrs = Object.keys(this._pointers);
|
||||
|
||||
// Remove ones that should no longer exist
|
||||
rmPtrs.forEach(id => this.rmPtr(id));
|
||||
|
||||
// Add ones that should
|
||||
this._pointers = newPtrDict;
|
||||
newPtrs.forEach(desc => this.addPtr(desc));
|
||||
updatePtrs.forEach(desc => this.updatePtr(desc));
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.addPtr = function(desc) {
|
||||
this._widget.addNode(desc);
|
||||
this._pointers[desc.id] = desc;
|
||||
this.createConnection(desc);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.updatePtr = function(desc) {
|
||||
this._widget.updateNode(desc);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.rmPtr = function(id) {
|
||||
// Remove the pointer's node
|
||||
this._widget.removeNode(id);
|
||||
// and connection
|
||||
var conn = this._connections[id];
|
||||
this._widget.removeNode(conn.id);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.containedInCurrent = function(id) {
|
||||
return id.indexOf(this._currentNodeId) === 0;
|
||||
};
|
||||
|
||||
OperationInterfaceEditorControl.prototype.createConnection = function(desc) {
|
||||
var conn = {};
|
||||
conn.id = `CONN_${++CONN_ID}`;
|
||||
|
||||
if (desc.container === 'outputs') {
|
||||
conn.src = this._currentNodeId;
|
||||
conn.dst = desc.id;
|
||||
} else {
|
||||
conn.src = desc.id;
|
||||
conn.dst = this._currentNodeId;
|
||||
}
|
||||
// Create a connection either to or from desc & the currentNode
|
||||
this._widget.addConnection(conn);
|
||||
this._connections[desc.id] = conn;
|
||||
|
||||
return conn;
|
||||
};
|
||||
|
||||
return OperationInterfaceEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Tue May 31 2016 09:16:24 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/OperationInterfaceEditor/OperationInterfaceEditorWidget',
|
||||
'./OperationInterfaceEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
OperationInterfaceEditorWidget,
|
||||
OperationInterfaceEditorControl) {
|
||||
'use strict';
|
||||
|
||||
var OperationInterfaceEditorPanel;
|
||||
|
||||
OperationInterfaceEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'OperationInterfaceEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(OperationInterfaceEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(OperationInterfaceEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
OperationInterfaceEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new OperationInterfaceEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new OperationInterfaceEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
widget: this.widget,
|
||||
embedded: this._embedded
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
OperationInterfaceEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
OperationInterfaceEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
OperationInterfaceEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
OperationInterfaceEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return OperationInterfaceEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,470 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'deepforge/viz/PipelineControl',
|
||||
'common/core/coreQ',
|
||||
'common/storage/constants',
|
||||
'q',
|
||||
'underscore'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
EasyDAGControl,
|
||||
PipelineControl,
|
||||
Core,
|
||||
STORAGE_CONSTANTS,
|
||||
Q,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var PipelineEditorControl,
|
||||
CONN = {
|
||||
SRC: 'src',
|
||||
DST: 'dst'
|
||||
},
|
||||
DECORATORS = {
|
||||
ArtifactLoader: 'ArtifactOpDecorator',
|
||||
ArtifactFinder: 'ArtifactOpDecorator'
|
||||
},
|
||||
WIDGET_NAME = 'EasyDAG';
|
||||
|
||||
PipelineEditorControl = function (options) {
|
||||
EasyDAGControl.call(this, options);
|
||||
this.addedIds = {};
|
||||
};
|
||||
|
||||
_.extend(
|
||||
PipelineEditorControl.prototype,
|
||||
EasyDAGControl.prototype,
|
||||
PipelineControl.prototype
|
||||
);
|
||||
|
||||
PipelineEditorControl.prototype._getValidInitialNodes =
|
||||
PipelineControl.prototype.getValidInitialNodes;
|
||||
|
||||
PipelineEditorControl.prototype.TERRITORY_RULE = {children: 3};
|
||||
PipelineEditorControl.prototype.selectedObjectChanged = function (nodeId) {
|
||||
this._logger.debug('activeObject nodeId \'' + nodeId + '\'');
|
||||
|
||||
// Remove current territory patterns
|
||||
if (this._currentNodeId) {
|
||||
this._client.removeUI(this._territoryId);
|
||||
}
|
||||
|
||||
this._currentNodeId = nodeId;
|
||||
this._currentNodeParentId = undefined;
|
||||
|
||||
if (typeof this._currentNodeId === 'string') {
|
||||
var desc = this._getObjectDescriptor(nodeId);
|
||||
this._widget.setTitle(desc.name.toUpperCase());
|
||||
|
||||
if (typeof desc.parentId === 'string') {
|
||||
this.$btnModelHierarchyUp.show();
|
||||
} else {
|
||||
this.$btnModelHierarchyUp.hide();
|
||||
}
|
||||
|
||||
this._currentNodeParentId = desc.parentId;
|
||||
|
||||
// Put new node's info into territory rules
|
||||
this.updateTerritory();
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.updateTerritory = function() {
|
||||
var nodeId = this._currentNodeId;
|
||||
|
||||
// activeNode rules
|
||||
this._territories = {};
|
||||
|
||||
this._territoryId = this._client.addUI(this, events => {
|
||||
this._eventCallback(events);
|
||||
});
|
||||
this._logger.debug(`PipelineEditor territory id is ${this._territoryId}`);
|
||||
|
||||
this._territories[nodeId] = {children: 0}; // Territory "rule"
|
||||
this._client.updateTerritory(this._territoryId, this._territories);
|
||||
|
||||
this._territories[nodeId] = this.TERRITORY_RULE;
|
||||
|
||||
// Add the operation definitions to the territory
|
||||
var metanodes = this._client.getAllMetaNodes(),
|
||||
operation = metanodes.find(n => n.getAttribute('name') === 'Operation');
|
||||
|
||||
// Get all the meta nodes that are instances of Operations
|
||||
metanodes.map(n => n.getId())
|
||||
.filter(nId => this._client.isTypeOf(nId, operation.getId()))
|
||||
// Add a rule for them
|
||||
.forEach(opId => this._territories[opId] = this.TERRITORY_RULE);
|
||||
|
||||
// Add arch/artifact dir to the territory
|
||||
// loading more than necessary.... can restrict it in the future
|
||||
// if perf is a problem
|
||||
this._territories[CONSTANTS.PROJECT_ROOT_ID] = {children: 2};
|
||||
|
||||
this._client.updateTerritory(this._territoryId, this._territories);
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._initWidgetEventHandlers = function () {
|
||||
EasyDAGControl.prototype._initWidgetEventHandlers.call(this);
|
||||
this._widget.getExistingPortMatches = this.getExistingPortMatches.bind(this);
|
||||
this._widget.createConnection = this.createConnection.bind(this);
|
||||
this._widget.removeConnection = this.removeConnection.bind(this);
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.isContainedInActive = function (gmeId) {
|
||||
// Check if the given id is contained in the active node
|
||||
return gmeId.indexOf(this._currentNodeId) === 0;
|
||||
};
|
||||
|
||||
////////////////////// Node Load/Update/Unload Overrides //////////////////////
|
||||
// Filter out the child nodes (bc of the larger territory)
|
||||
PipelineEditorControl.prototype._onLoad = function (gmeId) {
|
||||
var desc = this._getObjectDescriptor(gmeId);
|
||||
if (desc.parentId === this._currentNodeId) {
|
||||
this.addedIds[desc.id] = true;
|
||||
return EasyDAGControl.prototype._onLoad.call(this, gmeId);
|
||||
} else if (desc.parentId !== null &&
|
||||
this.isContainedInActive(desc.parentId) && desc.isDataPort) {
|
||||
// port added!
|
||||
this.addedIds[desc.id] = true;
|
||||
this._widget.addPort(desc);
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._onUnload = function (gmeId) {
|
||||
// Check if it has been added
|
||||
if(this.addedIds[gmeId]) {
|
||||
delete this.addedIds[gmeId];
|
||||
return EasyDAGControl.prototype._onUnload.call(this, gmeId);
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._onUpdate = function (gmeId) {
|
||||
var desc = this._getObjectDescriptor(gmeId);
|
||||
if (desc.isDataPort && this.isContainedInActive(desc.parentId)) { // port added!
|
||||
this._widget.updatePort(desc);
|
||||
} else if (desc.isConnection) {
|
||||
this._widget.updateConnection(desc);
|
||||
} else if (desc.parentId === this._currentNodeId) {
|
||||
this._widget.updateNode(desc);
|
||||
} // Ignore any other updates - ie, Inputs/Outputs containers
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getNodeDecorator = function (nodeObj) {
|
||||
var decoratorManager = this._client.decoratorManager,
|
||||
decorator,
|
||||
decoratorClass;
|
||||
|
||||
var base = this._client.getNode(nodeObj.getMetaTypeId()),
|
||||
baseName = base && base.getAttribute('name');
|
||||
|
||||
decorator = DECORATORS[baseName] || this.DEFAULT_DECORATOR;
|
||||
decoratorClass = decoratorManager.getDecoratorForWidget(decorator, WIDGET_NAME);
|
||||
return decoratorClass;
|
||||
};
|
||||
|
||||
// Override the getSuccessors method to look up successors by operations
|
||||
// with input nodes of the selected node's output type (prioritize the
|
||||
// valid nodes that are using an unused output type, if one exists, ow
|
||||
// prioritize based on current outgoing connections count).
|
||||
// TODO
|
||||
|
||||
PipelineEditorControl.prototype.hasValidOutputs = function (inputId, outputs) {
|
||||
return this.getValidOutputs(inputId, outputs);
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.getValidOutputs = function (inputId, outputs) {
|
||||
// Valid input if one of the isTypeOf(<output>, inputId)
|
||||
// for at least one output
|
||||
var inputType = this._client.getNode(inputId).getMetaTypeId();
|
||||
return outputs.filter(type => this._client.isTypeOf(type, inputType)).length;
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getValidSuccessorNodes = function (nodeId) {
|
||||
// Get all valid children
|
||||
var node = this._client.getNode(nodeId),
|
||||
children,
|
||||
outputs;
|
||||
|
||||
children = this._getAllValidChildren(node.getParentId())
|
||||
.map(id => this._client.getNode(id));
|
||||
|
||||
// Get all valid data output types of 'nodeId'
|
||||
outputs = this.getOperationOutputs(node)
|
||||
.map(id => this._client.getNode(id).getMetaTypeId());
|
||||
|
||||
// For all valid children, return all that have at least one
|
||||
// (unoccupied) input that is a superclass (or same class) as
|
||||
// one of the outputs
|
||||
return children
|
||||
.filter(node => this.getOperationInputs(node)
|
||||
.filter(id => this.hasValidOutputs(id, outputs)).length)
|
||||
.map(node => {
|
||||
return {
|
||||
node: this._getObjectDescriptor(node.getId())
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.removeConnection = function (id) {
|
||||
var conn = this._client.getNode(id),
|
||||
names,
|
||||
msg;
|
||||
|
||||
names = ['src', 'dst'] // srcPort, srcOp, dstPort, dstOp
|
||||
.map(type => conn.getPointer(type).to)
|
||||
.map(portId => [portId, this.getSiblingContaining(portId)])
|
||||
.reduce((l1, l2) => l1.concat(l2))
|
||||
.map(id => this._client.getNode(id));
|
||||
|
||||
msg = `Disconnecting ${names[0]} of ${names[1]} from ${names[2]} of ${names[3]}`;
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
this._client.delMoreNodes([id]);
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.getExistingPortMatches = function (portId, isOutput) {
|
||||
// Get the children nodeIds
|
||||
var srcOpId = this.getSiblingContaining(portId),
|
||||
childrenIds,
|
||||
skipIds, // Either ancestors or predecessors -> no cycles allowed!
|
||||
skipType = isOutput ? 'Predecessors' : 'Successors',
|
||||
method = 'get' + skipType,
|
||||
matches;
|
||||
|
||||
childrenIds = this._client.getNode(this._currentNodeId).getChildrenIds();
|
||||
|
||||
// Remove either ancestors or descendents
|
||||
skipIds = this[method](childrenIds.map(id => this._client.getNode(id)), srcOpId);
|
||||
childrenIds = _.difference(childrenIds, skipIds);
|
||||
|
||||
matches = this._getPortMatchFor(portId, childrenIds, isOutput);
|
||||
|
||||
// Get the port matches in the children
|
||||
return matches.map(tuple => {
|
||||
return {
|
||||
nodeId: tuple[0],
|
||||
portIds: tuple[1]
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getPortMatchFor = function (portId, opIds, isOutput) {
|
||||
//opIds = opIds || this._getAllValidChildren(node.getParentId());
|
||||
var opNodes = opIds.map(id => this._client.getNode(id)),
|
||||
portType = this._client.getNode(portId).getMetaTypeId(),
|
||||
getNodes = node => {
|
||||
var searchType = isOutput ? 'Inputs' : 'Outputs',
|
||||
searchFn = 'getOperation' + searchType,
|
||||
dstPorts = this[searchFn](node);
|
||||
|
||||
return [
|
||||
node.getId(),
|
||||
dstPorts.filter(id => {
|
||||
var typeId = this._client.getNode(id).getMetaTypeId();
|
||||
return isOutput ?
|
||||
this._client.isTypeOf(portType, typeId) :
|
||||
this._client.isTypeOf(typeId, portType);
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
return opNodes
|
||||
.map(getNodes) // Get all valid src/dst ports
|
||||
.filter(tuple => tuple[1].length);
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.createConnection = function (srcId, dstId) {
|
||||
var connId,
|
||||
names,
|
||||
msg;
|
||||
|
||||
names = [srcId, dstId] // srcPort, srcOp, dstPort, dstOp
|
||||
.map(id => [id, this.getSiblingContaining(srcId)])
|
||||
.reduce((l1, l2) => l1.concat(l2))
|
||||
.map(id => this._client.getNode(id));
|
||||
|
||||
msg = `Connecting ${names[0]} of ${names[1]} to ${names[2]} of ${names[4]}`;
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
|
||||
connId = this._client.createChild({
|
||||
parentId: this._currentNodeId,
|
||||
baseId: this.getConnectionId()
|
||||
});
|
||||
this._client.makePointer(connId, CONN.SRC, srcId);
|
||||
this._client.makePointer(connId, CONN.DST, dstId);
|
||||
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getPortPairs = function (outputs, inputs) {
|
||||
// Given a set of outputs and (potential) inputs, return valid pairs
|
||||
// <outputId, inputId> where `outputId` is the id of an outgoing port
|
||||
// in the src operation and `inputId` is the id of an incoming port in
|
||||
// the dst operation
|
||||
var result = [],
|
||||
ipairs = inputs.map(id => [id, this._client.getNode(id).getMetaTypeId()]),
|
||||
oType;
|
||||
|
||||
// For each output, get all possible (valid) input destinations
|
||||
outputs.forEach(outputId => {
|
||||
oType = this._client.getNode(outputId).getMetaTypeId();
|
||||
result = result.concat(ipairs.filter(pair =>
|
||||
// output type should be valid input type
|
||||
this._client.isTypeOf(oType, pair[1])
|
||||
)
|
||||
.map(pair => [outputId, pair[0]]) // Get the input data id
|
||||
);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype.getConnectionId = function () {
|
||||
return this._client.getAllMetaNodes()
|
||||
.find(node => node.getAttribute('name') === 'Transporter')
|
||||
.getId();
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._createConnectedNode = function (nodeId, typeId) {
|
||||
// Create a node of type "typeId" after "nodeId"
|
||||
// Figure out which ports need to be connected
|
||||
var parentId = this._currentNodeId,
|
||||
outputs = this.getOperationOutputs(this._client.getNode(nodeId)),
|
||||
inputs = this.getOperationInputs(this._client.getNode(typeId)),
|
||||
pairs = this._getPortPairs(outputs, inputs),
|
||||
srcOpName = this._client.getNode(nodeId).getAttribute('name');
|
||||
|
||||
this._logger.info(`Valid ports for ${nodeId} -> ${typeId} are ${pairs}`);
|
||||
|
||||
// If none, => error!
|
||||
// For now, I am assuming that they used '_getValidSuccessorNodes' to
|
||||
// get the pairs. ie, it is valid.
|
||||
// TODO
|
||||
|
||||
if (pairs.length === 1) { // If one, continue
|
||||
var pair = pairs[0],
|
||||
srcPortId = pair[0],
|
||||
srcPort,
|
||||
dstPortBaseId = pair[1],
|
||||
dstPortBase,
|
||||
rootGuid = this._client.getActiveRootHash(),
|
||||
branchName = this._client.getActiveBranchName(),
|
||||
startCommit = this._client.getActiveCommitHash(),
|
||||
connTypeId = this.getConnectionId(),
|
||||
project = this._client.getProjectObject(),
|
||||
conn,
|
||||
connBase,
|
||||
parentNode,
|
||||
commitMsg,
|
||||
root;
|
||||
|
||||
// This next portion uses the core bc it requires async loading and batching
|
||||
// into a single commit
|
||||
var core = new Core(project, {
|
||||
globConf: WebGMEGlobal.gmeConfig,
|
||||
logger: this._logger.fork('core')
|
||||
});
|
||||
// Load the first node/commit...
|
||||
core.loadRoot(rootGuid)
|
||||
.then(_root => {
|
||||
root = _root;
|
||||
return Q.all(
|
||||
[parentId, typeId, connTypeId, dstPortBaseId, srcPortId].map(id => core.loadByPath(root, id))
|
||||
);
|
||||
})
|
||||
.then(nodes => {
|
||||
// Create the given dst operation
|
||||
var opBase = nodes[1],
|
||||
dstOp;
|
||||
|
||||
parentNode = nodes[0];
|
||||
connBase = nodes[2];
|
||||
dstPortBase = nodes[3];
|
||||
srcPort = nodes[4];
|
||||
// Create the given dst operation
|
||||
dstOp = core.createNode({
|
||||
parent: parentNode,
|
||||
base: opBase
|
||||
});
|
||||
commitMsg = `Adding ${core.getAttribute(dstOp, 'name')} after ${srcOpName}`;
|
||||
return core.loadChildren(dstOp);
|
||||
})
|
||||
.then(containers => {
|
||||
var inputContainer;
|
||||
|
||||
// Get the operation inputs (can't use the earlier fn - different node types)
|
||||
inputContainer = containers
|
||||
.find(cntr => core.isInstanceOf(cntr, 'Inputs'));
|
||||
|
||||
return core.loadChildren(inputContainer);
|
||||
})
|
||||
.then(inputDataPorts => {
|
||||
// Get the matching input node
|
||||
var dstPort = inputDataPorts.find(port => core.isTypeOf(port, dstPortBase));
|
||||
// Create the connection
|
||||
conn = core.createNode({
|
||||
parent: parentNode,
|
||||
base: connBase
|
||||
});
|
||||
|
||||
// Connect srcPortId and the node from above
|
||||
core.setPointer(conn, 'src', srcPort);
|
||||
core.setPointer(conn, 'dst', dstPort);
|
||||
var persisted = core.persist(root);
|
||||
return project.makeCommit(
|
||||
branchName,
|
||||
[ startCommit ],
|
||||
persisted.rootHash,
|
||||
persisted.objects,
|
||||
commitMsg
|
||||
);
|
||||
})
|
||||
.then(result => {
|
||||
if (result.status === STORAGE_CONSTANTS.SYNCED) {
|
||||
// Throw out the changes... warn the user?
|
||||
this._logger.info('SYNCED!');
|
||||
} else {
|
||||
// Throw out the changes... warn the user?
|
||||
this._logger.warn(`Could not create operation after ${srcOpName}`);
|
||||
}
|
||||
})
|
||||
.fail(err => this._logger.error(`Could not create operation after ${srcOpName}: ${err}`));
|
||||
|
||||
} else if (pairs.length > 1) {
|
||||
// Else, prompt!
|
||||
// TODO
|
||||
this._logger.error('multiple port combinations... This is currently unsupported');
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getTargetDirs = function (typeIds) {
|
||||
// Find the directories containing these types
|
||||
return this._client.getNode(CONSTANTS.PROJECT_ROOT_ID).getChildrenIds()
|
||||
// No referencing data meta types
|
||||
.filter(id => {
|
||||
var cMeta = this._client.getChildrenMeta(id),
|
||||
validChildIds;
|
||||
|
||||
if (!cMeta) {
|
||||
return false;
|
||||
}
|
||||
|
||||
validChildIds = cMeta.items.map(item => item.id);
|
||||
for (var i = typeIds.length; i--;) {
|
||||
if (validChildIds.indexOf(typeIds[i]) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
return PipelineEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Thu May 19 2016 14:04:47 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/PipelineEditor/PipelineEditorWidget',
|
||||
'./PipelineEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
PipelineEditorWidget,
|
||||
PipelineEditorControl) {
|
||||
'use strict';
|
||||
|
||||
var PipelineEditorPanel;
|
||||
|
||||
PipelineEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'PipelineEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(PipelineEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(PipelineEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
PipelineEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new PipelineEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new PipelineEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
PipelineEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
PipelineEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
PipelineEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
PipelineEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
PipelineEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return PipelineEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,242 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 0.1.0 from webgme on Wed Dec 23 2015 11:31:06 GMT-0600 (CST).
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'js/Utils/GMEConcepts',
|
||||
'js/NodePropertyNames'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
GMEConcepts,
|
||||
nodePropertyNames
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var RootVizControl;
|
||||
|
||||
RootVizControl = function (options) {
|
||||
|
||||
this._logger = options.logger.fork('Control');
|
||||
|
||||
this._client = options.client;
|
||||
this._embedded = options.embedded;
|
||||
|
||||
// Initialize core collections and variables
|
||||
this._widget = options.widget;
|
||||
|
||||
this._currentNodeId = null;
|
||||
this._currentNodeParentId = undefined;
|
||||
|
||||
this._initWidgetEventHandlers();
|
||||
|
||||
this._logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
RootVizControl.prototype._initWidgetEventHandlers = function () {
|
||||
this._widget.onNodeClick = function (id) {
|
||||
// Change the current active object
|
||||
WebGMEGlobal.State.registerActiveObject(id);
|
||||
};
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
|
||||
// One major concept here is with managing the territory. The territory
|
||||
// defines the parts of the project that the visualizer is interested in
|
||||
// (this allows the browser to then only load those relevant parts).
|
||||
RootVizControl.prototype.selectedObjectChanged = function (nodeId) {
|
||||
var desc = this._getObjectDescriptor(nodeId),
|
||||
self = this;
|
||||
|
||||
self._logger.debug('activeObject nodeId \'' + nodeId + '\'');
|
||||
|
||||
// Remove current territory patterns
|
||||
if (self._currentNodeId) {
|
||||
self._client.removeUI(self._territoryId);
|
||||
}
|
||||
|
||||
self._currentNodeId = nodeId;
|
||||
self._currentNodeParentId = undefined;
|
||||
|
||||
if (self._currentNodeId || self._currentNodeId === CONSTANTS.PROJECT_ROOT_ID) {
|
||||
// Put new node's info into territory rules
|
||||
self._selfPatterns = {};
|
||||
self._selfPatterns[nodeId] = {children: 0}; // Territory "rule"
|
||||
|
||||
if (desc.parentId || desc.parentId === CONSTANTS.PROJECT_ROOT_ID) {
|
||||
self.$btnModelHierarchyUp.show();
|
||||
} else {
|
||||
self.$btnModelHierarchyUp.hide();
|
||||
}
|
||||
|
||||
self._currentNodeParentId = desc.parentId;
|
||||
|
||||
self._territoryId = self._client.addUI(self, function (events) {
|
||||
self._eventCallback(events);
|
||||
});
|
||||
self._logger.debug(`RootViz territory id is ${this._territoryId}`);
|
||||
|
||||
// Update the territory
|
||||
self._client.updateTerritory(self._territoryId, self._selfPatterns);
|
||||
|
||||
self._selfPatterns[nodeId] = {children: 1};
|
||||
self._client.updateTerritory(self._territoryId, self._selfPatterns);
|
||||
}
|
||||
};
|
||||
|
||||
// This next function retrieves the relevant node information for the widget
|
||||
RootVizControl.prototype._getObjectDescriptor = function (nodeId) {
|
||||
var nodeObj = this._client.getNode(nodeId),
|
||||
objDescriptor;
|
||||
|
||||
if (nodeObj) {
|
||||
objDescriptor = {
|
||||
'id': undefined,
|
||||
'name': undefined,
|
||||
'childrenIds': undefined,
|
||||
'parentId': undefined,
|
||||
'isConnection': false
|
||||
};
|
||||
|
||||
objDescriptor.id = nodeObj.getId();
|
||||
objDescriptor.name = nodeObj.getAttribute(nodePropertyNames.Attributes.name);
|
||||
objDescriptor.childrenIds = nodeObj.getChildrenIds();
|
||||
objDescriptor.childrenNum = objDescriptor.childrenIds.length;
|
||||
objDescriptor.parentId = nodeObj.getParentId();
|
||||
objDescriptor.isConnection = GMEConcepts.isConnection(nodeId); // GMEConcepts can be helpful
|
||||
}
|
||||
|
||||
return objDescriptor;
|
||||
};
|
||||
|
||||
/* * * * * * * * Node Event Handling * * * * * * * */
|
||||
RootVizControl.prototype._eventCallback = function (events) {
|
||||
var i = events ? events.length : 0,
|
||||
event;
|
||||
|
||||
this._logger.debug('_eventCallback \'' + i + '\' items');
|
||||
|
||||
while (i--) {
|
||||
event = events[i];
|
||||
switch (event.etype) {
|
||||
case CONSTANTS.TERRITORY_EVENT_LOAD:
|
||||
this._onLoad(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UPDATE:
|
||||
this._onUpdate(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UNLOAD:
|
||||
this._onUnload(event.eid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.debug('_eventCallback \'' + events.length + '\' items - DONE');
|
||||
};
|
||||
|
||||
RootVizControl.prototype._onLoad = function (gmeId) {
|
||||
var description = this._getObjectDescriptor(gmeId);
|
||||
this._widget.addNode(description);
|
||||
};
|
||||
|
||||
RootVizControl.prototype._onUpdate = function (gmeId) {
|
||||
var description = this._getObjectDescriptor(gmeId);
|
||||
this._widget.updateNode(description);
|
||||
};
|
||||
|
||||
RootVizControl.prototype._onUnload = function (gmeId) {
|
||||
this._widget.removeNode(gmeId);
|
||||
};
|
||||
|
||||
RootVizControl.prototype._stateActiveObjectChanged = function (model, activeObjectId) {
|
||||
this.selectedObjectChanged(activeObjectId);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
RootVizControl.prototype.destroy = function () {
|
||||
this._detachClientEventListeners();
|
||||
this._removeToolbarItems();
|
||||
};
|
||||
|
||||
RootVizControl.prototype._attachClientEventListeners = function () {
|
||||
if (!this._embedded) {
|
||||
this._detachClientEventListeners();
|
||||
WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged, this);
|
||||
}
|
||||
};
|
||||
|
||||
RootVizControl.prototype._detachClientEventListeners = function () {
|
||||
if (!this._embedded) {
|
||||
WebGMEGlobal.State.off('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged);
|
||||
}
|
||||
};
|
||||
|
||||
RootVizControl.prototype.onActivate = function () {
|
||||
this._attachClientEventListeners();
|
||||
this._displayToolbarItems();
|
||||
};
|
||||
|
||||
RootVizControl.prototype.onDeactivate = function () {
|
||||
this._detachClientEventListeners();
|
||||
this._hideToolbarItems();
|
||||
};
|
||||
|
||||
/* * * * * * * * * * Updating the toolbar * * * * * * * * * */
|
||||
RootVizControl.prototype._displayToolbarItems = function () {
|
||||
|
||||
if (this._toolbarInitialized === true) {
|
||||
for (var i = this._toolbarItems.length; i--;) {
|
||||
this._toolbarItems[i].show();
|
||||
}
|
||||
} else {
|
||||
this._initializeToolbar();
|
||||
}
|
||||
};
|
||||
|
||||
RootVizControl.prototype._hideToolbarItems = function () {
|
||||
|
||||
if (this._toolbarInitialized === true) {
|
||||
for (var i = this._toolbarItems.length; i--;) {
|
||||
this._toolbarItems[i].hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RootVizControl.prototype._removeToolbarItems = function () {
|
||||
|
||||
if (this._toolbarInitialized === true) {
|
||||
for (var i = this._toolbarItems.length; i--;) {
|
||||
this._toolbarItems[i].destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RootVizControl.prototype._initializeToolbar = function () {
|
||||
var self = this,
|
||||
toolBar = WebGMEGlobal.Toolbar;
|
||||
|
||||
this._toolbarItems = [];
|
||||
|
||||
this._toolbarItems.push(toolBar.addSeparator());
|
||||
|
||||
/************** Go to hierarchical parent button ****************/
|
||||
this.$btnModelHierarchyUp = toolBar.addButton({
|
||||
title: 'Go to parent',
|
||||
icon: 'glyphicon glyphicon-circle-arrow-up',
|
||||
clickFn: function (/*data*/) {
|
||||
WebGMEGlobal.State.registerActiveObject(self._currentNodeParentId);
|
||||
}
|
||||
});
|
||||
this._toolbarItems.push(this.$btnModelHierarchyUp);
|
||||
this.$btnModelHierarchyUp.hide();
|
||||
|
||||
this._toolbarInitialized = true;
|
||||
};
|
||||
|
||||
return RootVizControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 0.1.0 from webgme on Wed Dec 23 2015 11:31:06 GMT-0600 (CST).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/RootViz/RootVizWidget',
|
||||
'./RootVizControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
RootVizWidget,
|
||||
RootVizControl) {
|
||||
'use strict';
|
||||
|
||||
var RootVizPanel;
|
||||
|
||||
RootVizPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'RootVizPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(RootVizPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(RootVizPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
RootVizPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new RootVizWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new RootVizControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
RootVizPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
RootVizPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
RootVizPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
RootVizPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
RootVizPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return RootVizPanel;
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/*globals define */
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl',
|
||||
'underscore'
|
||||
], function (
|
||||
TextEditorControl,
|
||||
_
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var SerializeEditorControl;
|
||||
|
||||
SerializeEditorControl = function (options) {
|
||||
options.attributeName = 'serialize';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(
|
||||
SerializeEditorControl.prototype,
|
||||
TextEditorControl.prototype
|
||||
);
|
||||
|
||||
// input/output updates are actually activeNode updates
|
||||
SerializeEditorControl.prototype._onUpdate = function (id) {
|
||||
if (id === this._currentNodeId) {
|
||||
TextEditorControl.prototype._onUpdate.call(this, this._currentNodeId);
|
||||
}
|
||||
};
|
||||
|
||||
return SerializeEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed Jun 01 2016 14:44:21 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/SerializeEditor/SerializeEditorWidget',
|
||||
'./SerializeEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
SerializeEditorWidget,
|
||||
SerializeEditorControl) {
|
||||
'use strict';
|
||||
|
||||
var SerializeEditorPanel;
|
||||
|
||||
SerializeEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'SerializeEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(SerializeEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(SerializeEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
SerializeEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new SerializeEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new SerializeEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
SerializeEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
SerializeEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
SerializeEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
SerializeEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
SerializeEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return SerializeEditorPanel;
|
||||
});
|
||||
@@ -27,8 +27,11 @@ define([
|
||||
// Initialize core collections and variables
|
||||
this._widget = options.widget;
|
||||
this.ATTRIBUTE_NAME = options.attributeName || 'code'; // TODO: load from config
|
||||
|
||||
this._currentNodeId = null;
|
||||
this._currentNodeParentId = undefined;
|
||||
this._currentNodeHasAttr = false;
|
||||
this._embedded = options.embedded;
|
||||
|
||||
this._initWidgetEventHandlers();
|
||||
|
||||
@@ -36,19 +39,23 @@ define([
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._initWidgetEventHandlers = function () {
|
||||
// TODO: Add a way to navigate out of the current widget...
|
||||
this._widget.saveTextFor = (id, text) => {
|
||||
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
|
||||
if (this._currentNodeHasAttr) {
|
||||
this.saveTextFor(id, text);
|
||||
} else {
|
||||
this._logger.warn(`Cannot save attribute ${this.ATTRIBUTE_NAME} ` +
|
||||
`for ${id} - node doesn't have the given attribute!`);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
|
||||
// One major concept here is with managing the territory. The territory
|
||||
// defines the parts of the project that the visualizer is interested in
|
||||
// (this allows the browser to then only load those relevant parts).
|
||||
TextEditorControl.prototype.saveTextFor = function (id, text) {
|
||||
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
|
||||
};
|
||||
|
||||
TextEditorControl.prototype.TERRITORY_RULE = {children: 0};
|
||||
TextEditorControl.prototype.selectedObjectChanged = function (nodeId) {
|
||||
var desc = this._getObjectDescriptor(nodeId),
|
||||
self = this;
|
||||
var self = this;
|
||||
|
||||
self._logger.debug('activeObject nodeId \'' + nodeId + '\'');
|
||||
|
||||
@@ -59,34 +66,38 @@ define([
|
||||
|
||||
self._currentNodeId = nodeId;
|
||||
self._currentNodeParentId = undefined;
|
||||
self._currentNodeHasAttr = self._client.getNode(self._currentNodeId).getValidAttributeNames().indexOf(self.ATTRIBUTE_NAME) > -1;
|
||||
|
||||
if (typeof self._currentNodeId === 'string') {
|
||||
var parentId = this._getParentId(nodeId);
|
||||
// Put new node's info into territory rules
|
||||
self._selfPatterns = {};
|
||||
self._selfPatterns[nodeId] = {children: 0}; // Territory "rule"
|
||||
|
||||
//self._widget.setTitle(desc.name.toUpperCase());
|
||||
|
||||
if (typeof desc.parentId === 'string') {
|
||||
if (typeof parentId === 'string') {
|
||||
self.$btnModelHierarchyUp.show();
|
||||
} else {
|
||||
self.$btnModelHierarchyUp.hide();
|
||||
}
|
||||
|
||||
self._currentNodeParentId = desc.parentId;
|
||||
self._currentNodeParentId = parentId;
|
||||
|
||||
self._territoryId = self._client.addUI(self, function (events) {
|
||||
self._eventCallback(events);
|
||||
});
|
||||
self._logger.debug(`TextEditor territory id is ${this._territoryId}`);
|
||||
|
||||
// Update the territory
|
||||
self._client.updateTerritory(self._territoryId, self._selfPatterns);
|
||||
|
||||
self._selfPatterns[nodeId] = {children: 1};
|
||||
self._selfPatterns[nodeId] = this.TERRITORY_RULE;
|
||||
self._client.updateTerritory(self._territoryId, self._selfPatterns);
|
||||
}
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._getParentId = function (nodeId) {
|
||||
var node = this._client.getNode(nodeId);
|
||||
return node ? node.getParentId() : null;
|
||||
};
|
||||
|
||||
// This next function retrieves the relevant node information for the widget
|
||||
TextEditorControl.prototype._getObjectDescriptor = function (nodeId) {
|
||||
var nodeObj = this._client.getNode(nodeId),
|
||||
@@ -96,8 +107,8 @@ define([
|
||||
desc = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
parentId: undefined,
|
||||
text: ''
|
||||
parentId: undefined,
|
||||
text: ''
|
||||
};
|
||||
|
||||
desc.id = nodeObj.getId();
|
||||
@@ -119,17 +130,18 @@ define([
|
||||
while (i--) {
|
||||
event = events[i];
|
||||
switch (event.etype) {
|
||||
case CONSTANTS.TERRITORY_EVENT_LOAD:
|
||||
this._onLoad(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UPDATE:
|
||||
this._onUpdate(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UNLOAD:
|
||||
this._onUnload(event.eid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
case CONSTANTS.TERRITORY_EVENT_LOAD:
|
||||
this._onLoad(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UPDATE:
|
||||
this._onUpdate(event.eid);
|
||||
break;
|
||||
case CONSTANTS.TERRITORY_EVENT_UNLOAD:
|
||||
this._onUnload(event.eid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +149,10 @@ define([
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._onLoad = function (gmeId) {
|
||||
var description = this._getObjectDescriptor(gmeId);
|
||||
this._widget.addNode(description);
|
||||
if (this._currentNodeId === gmeId) { // Only load the text for the current node
|
||||
var description = this._getObjectDescriptor(gmeId);
|
||||
this._widget.addNode(description);
|
||||
}
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._onUpdate = function (gmeId) {
|
||||
@@ -165,12 +179,16 @@ define([
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._attachClientEventListeners = function () {
|
||||
this._detachClientEventListeners();
|
||||
WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged, this);
|
||||
if (!this._embedded) {
|
||||
this._detachClientEventListeners();
|
||||
WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged, this);
|
||||
}
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._detachClientEventListeners = function () {
|
||||
WebGMEGlobal.State.off('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged);
|
||||
if (!this._embedded) {
|
||||
WebGMEGlobal.State.off('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged);
|
||||
}
|
||||
};
|
||||
|
||||
TextEditorControl.prototype.onActivate = function () {
|
||||
@@ -186,6 +204,7 @@ define([
|
||||
|
||||
TextEditorControl.prototype.onDeactivate = function () {
|
||||
this._detachClientEventListeners();
|
||||
// TODO: Destroy the ace instance!
|
||||
this._hideToolbarItems();
|
||||
};
|
||||
|
||||
@@ -240,15 +259,6 @@ define([
|
||||
|
||||
/************** Checkbox example *******************/
|
||||
|
||||
this.$cbShowConnection = toolBar.addCheckBox({
|
||||
title: 'toggle checkbox',
|
||||
icon: 'gme icon-gme_diagonal-arrow',
|
||||
checkChangedFn: function (data, checked) {
|
||||
self._logger.debug('Checkbox has been clicked!');
|
||||
}
|
||||
});
|
||||
this._toolbarItems.push(this.$cbShowConnection);
|
||||
|
||||
this._toolbarInitialized = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 08:58:20 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/TextEditor/TextEditorWidget',
|
||||
'./TextEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
TextEditorControl) {
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
TextEditorControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var TextEditorPanel;
|
||||
@@ -26,6 +29,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
@@ -52,6 +56,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
|
||||
this.control = new TextEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
@@ -63,7 +68,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
|
||||
TextEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
this.widget.setReadOnly(isReadOnly);
|
||||
};
|
||||
|
||||
TextEditorPanel.prototype.onResize = function (width, height) {
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário