private void computeForceDirectedLayoutThreaded(int simulationSteps, float stepSize) { status = Status.Working; Debug.Log("Starting forcedirected graph layout construction."); //Attract Strength multi float c1 = 10.0f; //"Spring" length for maximal dependency strength float c3 = 1.0f; //Repulsion float c4 = 5.0f; //Attract-To-Center float c5 = 0.005f; //Friction float c6 = 0.105f; //TimeStep float t = stepSize; Dictionary <GraphVertex, VertexPositionData> simulationData = new Dictionary <GraphVertex, VertexPositionData>(); #region init start values foreach (GraphVertex vert in graph.Vertices) { float rr = 20f; Vector2 startPos = new Vector2((float)RNG.NextDouble() * rr, (float)RNG.NextDouble() * rr); VertexPositionData vpd = new VertexPositionData(startPos, startPos); simulationData.Add(vert, vpd); } #endregion int stepCounter = 0; while (stepCounter < simulationSteps) { foreach (GraphVertex thisVert in graph.Vertices) { // total force affecting "thisVert" Vector2 netForce = Vector2.zero; #region Attraction IEnumerable <GraphEdge> outEdges; graph.TryGetOutEdges(thisVert, out outEdges); List <GraphEdge> edgeList = outEdges.ToList(); Vector2 springForce = Vector2.zero; foreach (GraphEdge importEdge in edgeList) { GraphVertex otherVert = importEdge.Target; Vector2 direction = simulationData[otherVert].position - simulationData[thisVert].position; float springEquilibriumLength = (thisVert.getIsland().getRadius() + otherVert.getIsland().getRadius()) + c3 * (project.getMaxImportCount() / importEdge.getWeight()); springForce += c1 * direction.normalized * Mathf.Log((direction.magnitude / springEquilibriumLength)); } IEnumerable <GraphEdge> inEdges; graph.TryGetInEdges(thisVert, out inEdges); edgeList = inEdges.ToList(); /* * foreach (GraphEdge exportEdge in edgeList) * { * GraphVertex otherVert = exportEdge.Source; * Vector2 direction = simulationData[otherVert].position - simulationData[thisVert].position; * * float springEquilibriumLength = (thisVert.getIsland().getRadius() + otherVert.getIsland().getRadius()) + c3 / exportEdge.getWeight(); * * springForce += c1 * direction.normalized * Mathf.Log((direction.magnitude / springEquilibriumLength)); * } */ netForce += springForce; #endregion #region Repulsion foreach (GraphVertex otherVert in graph.Vertices) { if (otherVert == thisVert || (edgeList.Find(x => (x.Source == otherVert) || (x.Target == otherVert))) != null) { continue; } Vector2 direction = simulationData[thisVert].position - simulationData[otherVert].position; float distanceToBounds = direction.magnitude - (thisVert.getIsland().getRadius() + otherVert.getIsland().getRadius()); if (distanceToBounds < 0.0f) { Vector2 constrainedPosition = simulationData[thisVert].position - direction.normalized * distanceToBounds; simulationData[thisVert] = new VertexPositionData(constrainedPosition, constrainedPosition); distanceToBounds = 0f; } netForce += (direction.normalized * c4) / (Mathf.Pow(distanceToBounds + 0.1f, 2f)); } #endregion #region Attract-to-Center netForce -= simulationData[thisVert].position * c5; #endregion #region position computation through Verlet-Integration Vector2 currentVelocity = (simulationData[thisVert].position - simulationData[thisVert].oldPosition) / t; Vector2 resistance = currentVelocity * t * c6; Vector2 newPosition = 2.0f * simulationData[thisVert].position - simulationData[thisVert].oldPosition + t * t * netForce; newPosition -= resistance; Vector2 oldPosition = simulationData[thisVert].position; VertexPositionData vpd = new VertexPositionData(newPosition, oldPosition); simulationData[thisVert] = vpd; #endregion stepCounter++; } } #region assign computed positions to graph vertices foreach (GraphVertex vert in graph.Vertices) { VertexPositionData vpd = simulationData[vert]; Vector3 pos = new Vector3(vpd.position.x, 0, vpd.position.y); vert.setPosition(pos); } #endregion status = Status.Finished; Debug.Log("Forcedirected Graph layout is computed!"); cb(); }
private void ConstructProject() { #region OsgiProject status = Status.Working; Debug.Log("Starting OSGi-Project construction!"); JSONObject tmp = jsonObj.GetField("name"); Assert.IsNotNull(tmp, "Projectname could not be found!"); currentProject = new OsgiProject(tmp.str); #endregion #region Bundle,Fragments,Compilation Units tmp = jsonObj.GetField("bundles"); Assert.IsNotNull(tmp, "Project does not contain any Bundles!"); List <JSONObject> jsonBundleList = tmp.list; List <JSONObject> jsonPackageList = jsonObj.GetField("packages").list; long maxLOC = 0; foreach (JSONObject jsonBundle in jsonBundleList) { string name = jsonBundle.GetField("name").str; string symbName = jsonBundle.GetField("symbolicName").str; Bundle currentBundle = new Bundle(name, symbName, currentProject); //Create Fragments tmp = jsonBundle.GetField("packageFragments"); if (tmp != null) { List <JSONObject> fragList = tmp.list; foreach (JSONObject frag in fragList) { JSONObject jsonPkg = frag.GetField("package"); int pkgIdx = resolvePackageReferenceIdx(jsonPkg); string fragName = jsonPackageList[pkgIdx].GetField("qualifiedName").str; Package currentFragment = new Package(currentBundle, fragName); //Create Compilation Units if (frag.GetField("compilationUnits") != null) { List <JSONObject> jsonCompUnits = frag.GetField("compilationUnits").list; foreach (JSONObject jsonCU in jsonCompUnits) { JSONObject tlt = jsonCU.GetField("topLevelType"); string tempStr = tlt.GetField("eClass").str; tempStr = tempStr.Replace(redundantString_A, ""); type type = JavaParser.getTypeFromString(tempStr); tempStr = tlt.GetField("visibility").str; tempStr = tempStr.Replace(redundantString_A, ""); modifier mod = JavaParser.getModifierFromString(tempStr); long loc = jsonCU.GetField("LOC").i; if (loc > maxLOC) { maxLOC = loc; } CompilationUnit compUnit = new CompilationUnit(tlt.GetField("name").str, type, mod, loc, currentFragment); //TODO: Add support for additional information about a compilation unit(Methods, references to others) currentFragment.addCompilationUnit(compUnit); } } currentBundle.addPackage(currentFragment); } } currentProject.addBundle(currentBundle); } GlobalVar.maximumLOCinProject = maxLOC; #endregion #region Services List <Bundle> bundles = currentProject.getBundles(); tmp = jsonObj.GetField("services"); if (tmp != null) { List <JSONObject> serviceJsonList = tmp.list; foreach (JSONObject jsonService in serviceJsonList) { string serviceName = jsonService.GetField("interfaceName").str; tmp = jsonService.GetField("interface"); CompilationUnit serviceCU = null; if (tmp != null) { Vector3 cuIdx = resolveCompilationUnitRef(tmp); serviceCU = bundles[(int)cuIdx.x].getPackages()[(int)cuIdx.y].getCompilationUnits()[(int)cuIdx.z]; serviceCU.setServiceDeclaration(true); } Service service = new Service(serviceName, serviceCU); currentProject.addService(service); } } #endregion #region Resolve import/export + construct ServiceComponents + build dependency graph int i = 0; BidirectionalGraph <GraphVertex, GraphEdge> dependencyGraph = currentProject.getDependencyGraph(); foreach (JSONObject jsonBundle in jsonBundleList) { //Resolve Exports for Bundle tmp = jsonBundle.GetField("exports"); if (tmp != null) { List <Vector2> exportList = resolvePckgFragmentRefList(tmp.list); foreach (Vector2 indexVec in exportList) { Package resolvedFragment = bundles[(int)indexVec.x].getPackages()[(int)indexVec.y]; resolvedFragment.setExport(true); bundles[i].addExportedPackage(resolvedFragment); } } //Resolve Imports for Bundle tmp = jsonBundle.GetField("imports"); if (tmp != null) { List <Vector2> importList = resolvePckgFragmentRefList(tmp.list); foreach (Vector2 indexVec in importList) { Package resolvedFragment = bundles[(int)indexVec.x].getPackages()[(int)indexVec.y]; // Ignore self Import redundancy if (string.Compare(bundles[i].getName(), resolvedFragment.getBundle().getName()) != 0) { bundles[i].addImportedPackage(resolvedFragment); //Package dependency //Check if Vertices already in Graph List <GraphVertex> allVertices = dependencyGraph.Vertices.ToList(); GraphVertex vert1 = allVertices.Find(v => (string.Equals(v.getName(), bundles[i].getName()))); GraphVertex vert2 = allVertices.Find(v => (string.Equals(v.getName(), bundles[(int)indexVec.x].getName()))); if (vert1 == null) { vert1 = new GraphVertex(bundles[i].getName()); } if (vert2 == null) { vert2 = new GraphVertex(bundles[(int)indexVec.x].getName()); } dependencyGraph.AddVertex(vert1); dependencyGraph.AddVertex(vert2); GraphEdge edge; bool edgePresent = dependencyGraph.TryGetEdge(vert1, vert2, out edge); if (edgePresent && dependencyGraph.AllowParallelEdges) { edge.incrementWeight(1f); } else { edge = new GraphEdge(vert1, vert2); dependencyGraph.AddEdge(edge); } GraphEdge opposingEdge; float bidirectionalEdgeWeight = edge.getWeight(); bool oppEdgePresent = dependencyGraph.TryGetEdge(vert2, vert1, out opposingEdge); if (oppEdgePresent) { bidirectionalEdgeWeight += opposingEdge.getWeight(); } if (bidirectionalEdgeWeight > currentProject.getMaxImportCount()) { currentProject.setMaxImportCount((int)bidirectionalEdgeWeight); } } else { Debug.Log("Spotted import redundancy in: " + bundles[i].getName()); } } } //Construct and resolve ServiceComponents List <Service> serviceList = currentProject.getServices(); tmp = jsonBundle.GetField("components"); if (tmp != null) { foreach (JSONObject jsonComponent in tmp.list) { string scName = jsonComponent.GetField("name").str; Vector3 implIdx = resolveCompilationUnitRef(jsonComponent.GetField("implementation")); CompilationUnit resolvedCu = bundles[(int)implIdx.x].getPackages()[(int)implIdx.y].getCompilationUnits()[(int)implIdx.z]; resolvedCu.setServiceComponentImpl(true); ServiceComponent sc = new ServiceComponent(scName, resolvedCu); tmp = jsonComponent.GetField("providedServices"); if (tmp != null) { List <int> serviceRefs = resolveServiceReferenceIdxList(tmp); foreach (int s in serviceRefs) { sc.addProvidedService(serviceList[s]); serviceList[s].addImplementingComponent(sc); } } tmp = jsonComponent.GetField("referencedServices"); if (tmp != null) { List <int> serviceRefs = resolveServiceReferenceIdxList(tmp); foreach (int s in serviceRefs) { sc.addReferencedService(serviceList[s]); serviceList[s].addReferencingComponent(sc); } } bundles[i].addServiceComponent(sc); } } i++; } #endregion Debug.Log("Max Import-count: " + currentProject.getMaxImportCount()); status = Status.Finished; Debug.Log("Finished OSGi-Project construction!"); cb(); }