Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin CreateCircuitFromAnnotations #170

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 8 additions & 61 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"jszip": "^3.6.0",
"lodash-amd": "^4.17.15",
"webgme-bindings": "github:webgme/bindings",
"webgme-json-importer": "^1.2.0"
"webgme-json-importer": "github:deepforge-dev/webgme-json-importer"
},
"description": "First, install the electric-circuits following: - [NodeJS](https://nodejs.org/en/) (v4.x.x recommended) - [MongoDB](https://www.mongodb.com/)",
"main": "app.js",
Expand Down
95 changes: 95 additions & 0 deletions src/common/AnnotationWJIToCircuitTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* globals define */
function factory(guid) {
class AnnotationWJIToCircuitTransformer {
transform(annotationsWJI) {
this._transformIntersections(annotationsWJI);
this._addPortToJunctions(annotationsWJI);
this._reassignJunctionEdges(annotationsWJI);
}

_transformIntersections(annotations) {
// Nodes
const intersections = annotations.children.filter(this._isIntersection);
intersections.forEach(intersection => {
intersection.id ? intersection.id = intersection.id.replace('Intersection', 'Junction'): null;
intersection.pointers.base = '@meta:Junction';
});

// Edges/Wires
const wires = annotations.children.filter(this._isWire);
wires.forEach(wire => {
wire.id ? wire.id = wire.id.replace('Intersection', 'Junction'): null;
wire.pointers.src = wire.pointers.src.replace('Intersection', 'Junction');
wire.pointers.dst = wire.pointers.dst.replace('Intersection', 'Junction');
});
}

_addPortToJunctions(annotations) {
const junctions = annotations.children.filter(this._isJunction);
junctions.forEach(junction => {
junction.children = this._getPortsWJI(
['p1', 'p2', 'p3', 'p4']
);
});
}

_reassignJunctionEdges(annotations) {
const junctions = Object.fromEntries(annotations.children.filter(this._isJunction).map(j => [j.id, j]));
const wires = annotations.children.filter(this._isWire);

const isAJunctionId = id => !!junctions[id];

const getRandomChild = node => {
const index = Math.floor(Math.random() * node.children.length);
return node.children[index];
};

wires.forEach(wire => {
if (isAJunctionId(wire.pointers.src)) {
wire.pointers.src = `@id:${getRandomChild(junctions[wire.pointers.src]).alias}`;
}

if (isAJunctionId(wire.pointers.dst)) {
wire.pointers.dst = `@id:${getRandomChild(junctions[wire.pointers.dst]).alias}`;
}
});
}

_isIntersection(node) {
return node.pointers.base === '@meta:Intersection';
}

_isJunction(node) {
return node.pointers.base === '@meta:Junction';
}

_isWire(node) {
return node.pointers.base === '@meta:Wire';
}

_getPortsWJI(portNames) {
return portNames.map(name => {
const id = `${guid()}`;
const attributes = {name};
const pointers = {base: "@meta:Pin"};
return {
alias: id,
id: `@name:${name}`,
attributes,
pointers
};
});
}
}

return AnnotationWJIToCircuitTransformer;
}


if (typeof define !== 'undefined') {
define(['common/util/guid'], (guid) => factory(guid));
} else {
module.exports = factory();
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*globals define*/
/*eslint-env node, browser*/

/**
* Generated by PluginGenerator 2.20.5 from webgme on Thu Apr 07 2022 13:59:26 GMT-0500 (Central Daylight Time).
* A plugin that inherits from the PluginBase. To see source code documentation about available
* properties and methods visit %host%/docs/source/PluginBase.html.
*/

define([
'plugin/PluginConfig',
'text!./metadata.json',
'plugin/PluginBase',
'electric-circuits/AnnotationWJIToCircuitTransformer',
'webgme-json-importer/JSONImporter',
], function (
PluginConfig,
pluginMetadata,
PluginBase,
AnnotationWJIToCircuitTransformer,
JSONImporter,) {
'use strict';

pluginMetadata = JSON.parse(pluginMetadata);

class CreateCircuitFromAnnotations extends PluginBase {
constructor(props) {
super(props);
this.pluginMetadata = pluginMetadata;
}

async main() {
const annotationWJI = await this.blobClient.getObjectAsJSON(this.getCurrentConfig().annotations);
const circuitWJITransformer = new AnnotationWJIToCircuitTransformer();
circuitWJITransformer.transform(annotationWJI);
const importer = new JSONImporter(this.core, this.rootNode);
await importer.import(this.activeNode, annotationWJI);
await this.save('Model updated to new state.');
this.result.setSuccess(true);
}
}



return CreateCircuitFromAnnotations;
});
21 changes: 21 additions & 0 deletions src/plugins/CreateCircuitFromAnnotations/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"id": "CreateCircuitFromAnnotations",
"name": "CreateCircuitFromAnnotations",
"version": "0.1.0",
"description": "",
"icon": {
"class": "glyphicon glyphicon-cog",
"src": ""
},
"disableServerSideExecution": false,
"disableBrowserSideExecution": false,
"dependencies": [],
"writeAccessRequired": false,
"configStructure": [{
"name": "annotations",
"displayName": "Input Annotations",
"description": "The input annotation JSON file in the webgme-json-import (WJI) format",
"valueType": "asset",
"readOnly": false
}]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*eslint-env node, mocha*/
/**
* Generated by PluginGenerator 2.20.5 from webgme on Thu Apr 07 2022 13:59:26 GMT-0500 (Central Daylight Time).
*/

describe('CreateCircuitFromAnnotations', function () {
var testFixture = require('../../globals'),
gmeConfig = testFixture.getGmeConfig(),
expect = testFixture.expect,
logger = testFixture.logger.fork('CreateCircuitFromAnnotations'),
PluginCliManager = testFixture.WebGME.PluginCliManager,
projectName = 'testProject',
pluginName = 'CreateCircuitFromAnnotations',
project,
gmeAuth,
storage,
commitHash;

before(function (done) {
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
return storage.openDatabase();
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
gmeConfig: gmeConfig
};

return testFixture.importProject(storage, importParam);
})
.then(function (importResult) {
project = importResult.project;
commitHash = importResult.commitHash;
return project.createBranch('test', commitHash);
})
.nodeify(done);
});

after(function (done) {
storage.closeDatabase()
.then(function () {
return gmeAuth.unload();
})
.nodeify(done);
});

it('should run plugin and update the branch', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/1',
};

manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
try {
expect(err).to.equal(null);
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
} catch (e) {
done(e);
return;
}

project.getBranchHash('test')
.then(function (branchHash) {
expect(branchHash).to.not.equal(commitHash);
})
.nodeify(done);
});
});
});
Loading