00001 #include "LayoutPlugin.h" 00002 #include <random> 00003 #include <chrono> 00004 #include <QDebug> 00005 #include <Graph.h> 00006 #include <ExtendedGraph.h> 00007 #include "GraphWidgetListener.h" 00008 00009 namespace Elve { 00010 using namespace std; 00011 00012 LayoutPlugin::LayoutPlugin() 00013 { 00014 00015 } 00016 00017 LayoutPlugin::LayoutPlugin(const LayoutPlugin& other) : 00018 QObject(other.parent()) 00019 { 00020 00021 } 00022 00023 QVector2D LayoutPlugin::startPosition(const NodeID& id) { 00024 static default_random_engine gen; 00025 const QRectF& rect = mSystem.sizeHint(); 00026 00027 auto it = mStartPositions.find(id); 00028 if(it != mStartPositions.end()) { 00029 return it->second; 00030 } else { 00031 std::uniform_real_distribution<qreal> x(rect.left(),rect.right()); 00032 std::uniform_real_distribution<qreal> y(rect.top(),rect.bottom()); 00033 QVector2D p(x(gen),y(gen)); 00034 mStartPositions[id] = p; 00035 return p; 00036 } 00037 } 00038 00039 void LayoutPlugin::setGraph(SharedEGraph g,const NodePositions& positions) 00040 { 00041 mSystem.setOrientationHint(g->look()->orientationHint()); 00042 mStartPositions = positions; 00043 setGraph(g->graph()); 00044 } 00045 00046 void LayoutPlugin::clear(){ 00047 mSystem.clear(); 00048 } 00049 00050 System& LayoutPlugin::system() { 00051 return mSystem; 00052 } 00053 00054 QJsonObject LayoutPlugin::json() const { 00055 QJsonObject layout; 00056 QJsonObject positions; 00057 00058 layout.insert("name",name()); 00059 00060 using pair_type = NodePositions::value_type; 00061 for(const pair_type& p : system().positions()) { 00062 const QVector2D& pos = p.second; 00063 positions.insert(QString::number(p.first), 00064 QJsonArray{pos.x(),pos.y()}); 00065 } 00066 layout.insert("positions",positions); 00067 QJsonArray pinned; 00068 for(const PointsByID::value_type& p : system().pinnedPoints()) { 00069 pinned.append((int)p.first); 00070 } 00071 layout.insert("pinned",pinned); 00072 return layout; 00073 } 00074 00075 void LayoutPlugin::fromJson(const QJsonObject& layout) { 00076 QJsonArray pinned = layout.value("pinned").toArray(); 00077 QJsonObject poss = layout.value("positions").toObject(); 00078 for(const QJsonValue& v : pinned) { 00079 QJsonArray parr = poss.value(QString::number(v.toInt())).toArray(); 00080 QVector2D pos(parr[0].toDouble(),parr[1].toDouble()); 00081 system().pin(v.toInt(),pos); 00082 } 00083 } 00084 00085 const System& LayoutPlugin::system() const 00086 { 00087 return mSystem; 00088 } 00089 00090 void LayoutPlugin::tick(float dt, bool fast) { 00091 mSystem.tick(dt,fast); 00092 } 00093 00094 void LayoutPlugin::quickSim(size_t ticks) { 00095 if(ticks == 0) 00096 return; 00097 using namespace std::chrono; 00098 00099 high_resolution_clock::time_point t1 = high_resolution_clock::now(); 00100 for(int i = 0; i < ticks; i++) { 00101 tick(0.25,false); 00102 } 00103 high_resolution_clock::time_point t2 = high_resolution_clock::now(); 00104 duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 00105 qDebug() << "Simulating at mean of" << ticks/time_span.count() << "tps"; 00106 } 00107 00108 void LayoutPlugin::uiStart(Elve::GraphWidgetListener* listener,const SharedEGraph& graph) { 00109 listener->runCommand(QString("%1_layout").arg(cliName().c_str())); 00110 } 00111 00112 }