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();
        }
Exemple #2
0
        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();
        }