Add full inspector support (getString/getRecord) to Seabreeze.
This commit is contained in:
parent
bf181787cb
commit
c647a670b1
|
@ -10,7 +10,7 @@
|
||||||
// | Author : Vu Hoang Anh PHAM |
|
// | Author : Vu Hoang Anh PHAM |
|
||||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||||
// | =============================================================== |
|
// | =============================================================== |
|
||||||
// | C++ Header : "./seabreeze/Delay.h" |
|
// | C++ Header : "./seabreeze/Delay.h" |
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/DebugSession.h"
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
#include "seabreeze/Elmore.h"
|
#include "seabreeze/Elmore.h"
|
||||||
|
#include "seabreeze/Node.h"
|
||||||
#include "seabreeze/SeabreezeEngine.h"
|
#include "seabreeze/SeabreezeEngine.h"
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
@ -49,6 +50,7 @@ namespace Seabreeze {
|
||||||
|
|
||||||
Elmore::~Elmore ()
|
Elmore::~Elmore ()
|
||||||
{
|
{
|
||||||
|
cdebug_log(199,0) << "Elmore::~Elmore() " << endl;
|
||||||
delete _tree;
|
delete _tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +297,30 @@ namespace Seabreeze {
|
||||||
{ _tree->print( os ); }
|
{ _tree->print( os ); }
|
||||||
|
|
||||||
|
|
||||||
|
string Elmore::_getTypeName () const
|
||||||
|
{ return "Seabreeze::Elmore"; }
|
||||||
|
|
||||||
|
|
||||||
|
string Elmore::_getString () const
|
||||||
|
{
|
||||||
|
string s = "<" + _getTypeName() + ">";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Elmore::_getRecord () const
|
||||||
|
{
|
||||||
|
Record* record = new Record ( _getString() );
|
||||||
|
if (record != nullptr) {
|
||||||
|
record->add( getSlot("_seabreeze", _seabreeze) );
|
||||||
|
record->add( getSlot("_contacts" , &_contacts) );
|
||||||
|
record->add( getSlot("_checker" , &_checker ) );
|
||||||
|
record->add( getSlot("_tree" , _tree ) );
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Class : "ElmoreProperty"
|
// Class : "ElmoreProperty"
|
||||||
|
|
||||||
|
@ -314,6 +340,7 @@ namespace Seabreeze {
|
||||||
}
|
}
|
||||||
_elmore.setSeabreeze( seabreeze );
|
_elmore.setSeabreeze( seabreeze );
|
||||||
}
|
}
|
||||||
|
cdebug_log(199,0) << "ElmoreProperty::ElmoreProperty() on " << net << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -337,25 +364,48 @@ namespace Seabreeze {
|
||||||
{ return "ElmoreProperty"; }
|
{ return "ElmoreProperty"; }
|
||||||
|
|
||||||
|
|
||||||
|
string ElmoreProperty::_getString () const
|
||||||
|
{
|
||||||
|
string s = PrivateProperty::_getString ();
|
||||||
|
s.insert ( s.length() - 1 , " " + getString(&_elmore) );
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* ElmoreProperty::_getRecord () const
|
||||||
|
{
|
||||||
|
Record* record = PrivateProperty::_getRecord();
|
||||||
|
if ( record ) {
|
||||||
|
record->add( getSlot( "_name" , _name ) );
|
||||||
|
record->add( getSlot( "_elmore", &_elmore ) );
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Class : "ElmoreExtension"
|
// Class : "ElmoreExtension"
|
||||||
|
|
||||||
Elmore* ElmoreExtension::create ( Net* net )
|
Elmore* ElmoreExtension::create ( Net* net )
|
||||||
{
|
{
|
||||||
|
cdebug_log(199,1) << "ElmoreExtension::create() " << net << endl;
|
||||||
Elmore* elmore = get( net );
|
Elmore* elmore = get( net );
|
||||||
if (not elmore) {
|
if (not elmore) {
|
||||||
ElmoreProperty* property = new ElmoreProperty( net );
|
ElmoreProperty* property = new ElmoreProperty( net );
|
||||||
net->put( property );
|
net->put( property );
|
||||||
elmore = property->getElmore();
|
elmore = property->getElmore();
|
||||||
}
|
}
|
||||||
|
cdebug_tabw(199,-1);
|
||||||
return elmore;
|
return elmore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ElmoreExtension::destroy ( Net* net )
|
void ElmoreExtension::destroy ( Net* net )
|
||||||
{
|
{
|
||||||
|
cdebug_log(199,1) << "ElmoreExtension::destroy() " << net << endl;
|
||||||
Property* property = net->getProperty( ElmoreProperty::staticGetName() );
|
Property* property = net->getProperty( ElmoreProperty::staticGetName() );
|
||||||
if (property) net->remove( property );
|
if (property) net->remove( property );
|
||||||
|
cdebug_tabw(199,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
|
||||||
Node::Node ()
|
Node::Node ()
|
||||||
: _R (0.0)
|
: _R (0.0)
|
||||||
|
@ -50,4 +52,35 @@ namespace Seabreeze {
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
string Node::_getTypeName () const
|
||||||
|
{ return "Seabreeze::Node"; }
|
||||||
|
|
||||||
|
|
||||||
|
string Node::_getString () const
|
||||||
|
{
|
||||||
|
string s = "<Node ";
|
||||||
|
s += getString( _contact );
|
||||||
|
s += " R=" + getString( _R );
|
||||||
|
s += " C=" + getString( _C );
|
||||||
|
s += ">";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Node::_getRecord () const
|
||||||
|
{
|
||||||
|
Record* record = new Record ( _getString() );
|
||||||
|
if (record != nullptr) {
|
||||||
|
record->add( getSlot("_R" , _R ) );
|
||||||
|
record->add( getSlot("_Rt" , _Rt ) );
|
||||||
|
record->add( getSlot("_C" , _C ) );
|
||||||
|
record->add( getSlot("_parent" , _parent ) );
|
||||||
|
record->add( getSlot("_childs" , &_childs ) );
|
||||||
|
record->add( getSlot("_contact", _contact) );
|
||||||
|
record->add( getSlot("_label" , _label ) );
|
||||||
|
record->add( getSlot("_ap" , _ap ) );
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
} // Seabreeze namespace.
|
} // Seabreeze namespace.
|
||||||
|
|
|
@ -89,29 +89,26 @@ namespace Seabreeze {
|
||||||
|
|
||||||
const Name& SeabreezeEngine::getName () const
|
const Name& SeabreezeEngine::getName () const
|
||||||
{ return _toolName; };
|
{ return _toolName; };
|
||||||
|
|
||||||
|
|
||||||
|
string SeabreezeEngine::_getTypeName () const
|
||||||
Record* SeabreezeEngine::_getRecord () const
|
{ return getString(_toolName); }
|
||||||
{
|
|
||||||
Record* record= Super::_getRecord ();
|
|
||||||
|
|
||||||
if ( record ) {
|
|
||||||
// Add new records here
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string SeabreezeEngine::_getString () const
|
string SeabreezeEngine::_getString () const
|
||||||
{
|
{
|
||||||
ostringstream os;
|
ostringstream os;
|
||||||
os << "<" << "SeabreezeEngine " << _cell->getName() << ">";
|
os << "<" << _toolName << " " << _cell->getName() << ">";
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string SeabreezeEngine::_getTypeName () const
|
Record* SeabreezeEngine::_getRecord () const
|
||||||
{ return "Seabreeze::SeabreezeEngine"; }
|
{
|
||||||
|
Record* record = Super::_getRecord();
|
||||||
|
record->add( getSlot("_configuration", _configuration) );
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SeabreezeEngine::buildElmore ( Net* net )
|
void SeabreezeEngine::buildElmore ( Net* net )
|
||||||
|
@ -129,7 +126,7 @@ namespace Seabreeze {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Elmore* elmore = ElmoreProperty::create( net )->getElmore();
|
Elmore* elmore = ElmoreExtension::create( net );
|
||||||
elmore->contFromNet( net );
|
elmore->contFromNet( net );
|
||||||
|
|
||||||
cdebug_log(199,0) << "Found " << elmore->getContacts().size() << " RoutingPads:" << endl;
|
cdebug_log(199,0) << "Found " << elmore->getContacts().size() << " RoutingPads:" << endl;
|
||||||
|
@ -182,6 +179,5 @@ namespace Seabreeze {
|
||||||
|
|
||||||
void SeabreezeEngine::_preDestroy ()
|
void SeabreezeEngine::_preDestroy ()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
} // Seabreeze namespace.
|
} // Seabreeze namespace.
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
|
#include "hurricane/RoutingPad.h"
|
||||||
#include "seabreeze/Tree.h"
|
#include "seabreeze/Tree.h"
|
||||||
|
#include "seabreeze/Node.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
@ -30,6 +32,7 @@ namespace Seabreeze {
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Component;
|
||||||
|
|
||||||
|
|
||||||
Tree::Tree ()
|
Tree::Tree ()
|
||||||
|
@ -169,4 +172,25 @@ namespace Seabreeze {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Tree::_getTypeName () const
|
||||||
|
{ return "Seabreeze::Tree"; }
|
||||||
|
|
||||||
|
|
||||||
|
string Tree::_getString () const
|
||||||
|
{
|
||||||
|
string s = "<" + _getTypeName() + ">";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Tree::_getRecord () const
|
||||||
|
{
|
||||||
|
Record* record = new Record ( _getString() );
|
||||||
|
if (record != nullptr) {
|
||||||
|
record->add( getSlot("_nodes", &_nodes) );
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // Seabreeze namespace.
|
} // Seabreeze namespace.
|
||||||
|
|
|
@ -19,27 +19,41 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "hurricane/RoutingPad.h"
|
#include "hurricane/RoutingPad.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
|
||||||
|
using Hurricane::DBo;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Class : Seabreeze::Delay
|
// Class : Seabreeze::Delay
|
||||||
|
|
||||||
class Delay {
|
class Delay {
|
||||||
public:
|
public:
|
||||||
Delay ();
|
typedef std::map< RoutingPad*
|
||||||
~Delay ();
|
, std::map< RoutingPad*, double, DBo::CompareById >
|
||||||
inline const map<RoutingPad*, map<RoutingPad*, double>>& getValues () const ;
|
, DBo::CompareById> DelayMap;
|
||||||
void addPair ( RoutingPad*, RoutingPad*, double );
|
public:
|
||||||
void addValue ( RoutingPad*, RoutingPad*, double );
|
Delay ();
|
||||||
void printDelays ();
|
~Delay ();
|
||||||
|
inline const DelayMap& getValues () const ;
|
||||||
|
void addPair ( RoutingPad*, RoutingPad*, double );
|
||||||
|
void addValue ( RoutingPad*, RoutingPad*, double );
|
||||||
|
void printDelays ();
|
||||||
|
Record* _getRecord () const;
|
||||||
|
std::string _getString () const;
|
||||||
|
std::string _getTypeName () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<RoutingPad*, map<RoutingPad*, double>> _values;
|
DelayMap _values;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const map<RoutingPad*, map<RoutingPad*, double>>& Delay::getValues () const { return _values; }
|
|
||||||
}
|
inline const Delay::DelayMap& Delay::getValues () const { return _values; }
|
||||||
|
|
||||||
|
|
||||||
|
} // Seabreeze namespace.
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Seabreeze::Delay);
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace Hurricane {
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using Hurricane::Name;
|
using Hurricane::Name;
|
||||||
using Hurricane::DBo;
|
using Hurricane::DBo;
|
||||||
using Hurricane::Net;
|
using Hurricane::Net;
|
||||||
|
@ -48,33 +47,38 @@ namespace Seabreeze {
|
||||||
|
|
||||||
class Elmore {
|
class Elmore {
|
||||||
public:
|
public:
|
||||||
Elmore ( Net* );
|
typedef std::set<Contact*,DBo::CompareById> ContactSet;
|
||||||
~Elmore ();
|
public:
|
||||||
inline SeabreezeEngine* getSeabreeze () const;
|
Elmore ( Net* );
|
||||||
const Configuration* getConfiguration () const;
|
~Elmore ();
|
||||||
void contFromNet ( Net* );
|
inline SeabreezeEngine* getSeabreeze () const;
|
||||||
void buildTree ( RoutingPad* );
|
const Configuration* getConfiguration () const;
|
||||||
void buildFromNode ( Node* source, Segment* );
|
void contFromNet ( Net* );
|
||||||
Contact* buildBranch ( double* R, double* C, Contact* contact );
|
void buildTree ( RoutingPad* );
|
||||||
void setRC ( double* R, double* C, Contact* , Segment* );
|
void buildFromNode ( Node* source, Segment* );
|
||||||
void clearTree ();
|
Contact* buildBranch ( double* R, double* C, Contact* contact );
|
||||||
inline Tree* getTree ();
|
void setRC ( double* R, double* C, Contact* , Segment* );
|
||||||
inline const set<Contact*>& getContacts () const;
|
void clearTree ();
|
||||||
double delayElmore ( RoutingPad* );
|
inline Tree* getTree ();
|
||||||
void toTree ( ostream& ) const;
|
inline const ContactSet& getContacts () const;
|
||||||
inline void setSeabreeze ( SeabreezeEngine* );
|
double delayElmore ( RoutingPad* );
|
||||||
|
void toTree ( std::ostream& ) const;
|
||||||
|
inline void setSeabreeze ( SeabreezeEngine* );
|
||||||
|
virtual Record* _getRecord () const;
|
||||||
|
virtual std::string _getString () const;
|
||||||
|
virtual std::string _getTypeName () const;
|
||||||
private:
|
private:
|
||||||
SeabreezeEngine* _seabreeze;
|
SeabreezeEngine* _seabreeze;
|
||||||
set<Contact*> _contacts;
|
ContactSet _contacts;
|
||||||
set<Contact*> _checker;
|
ContactSet _checker;
|
||||||
Tree* _tree;
|
Tree* _tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline SeabreezeEngine* Elmore::getSeabreeze () const { return _seabreeze; }
|
inline SeabreezeEngine* Elmore::getSeabreeze () const { return _seabreeze; }
|
||||||
inline const set<Contact*>& Elmore::getContacts () const { return _contacts; }
|
inline const Elmore::ContactSet& Elmore::getContacts () const { return _contacts; }
|
||||||
inline Tree* Elmore::getTree () { return _tree; }
|
inline Tree* Elmore::getTree () { return _tree; }
|
||||||
inline void Elmore::setSeabreeze ( SeabreezeEngine* seabreeze ) { _seabreeze = seabreeze; }
|
inline void Elmore::setSeabreeze ( SeabreezeEngine* seabreeze ) { _seabreeze = seabreeze; }
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -90,6 +94,8 @@ namespace Seabreeze {
|
||||||
Name getName () const;
|
Name getName () const;
|
||||||
inline Elmore* getElmore ();
|
inline Elmore* getElmore ();
|
||||||
virtual string _getTypeName () const;
|
virtual string _getTypeName () const;
|
||||||
|
virtual Record* _getRecord () const;
|
||||||
|
virtual std::string _getString () const;
|
||||||
protected:
|
protected:
|
||||||
Elmore _elmore;
|
Elmore _elmore;
|
||||||
protected:
|
protected:
|
||||||
|
@ -129,3 +135,7 @@ namespace Seabreeze {
|
||||||
|
|
||||||
|
|
||||||
} // Seabreeze Namespace
|
} // Seabreeze Namespace
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Seabreeze::Elmore);
|
||||||
|
INSPECTOR_P_SUPPORT(Seabreeze::ElmoreProperty);
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
namespace Hurricane {
|
#include "hurricane/Contact.h"
|
||||||
class Contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
|
||||||
|
using Hurricane::Record;
|
||||||
using Hurricane::Contact;
|
using Hurricane::Contact;
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,23 +29,26 @@ namespace Seabreeze {
|
||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
Node ();
|
Node ();
|
||||||
Node ( Node* parent, Contact* );
|
Node ( Node* parent, Contact* );
|
||||||
~Node ();
|
~Node ();
|
||||||
inline double R () const;
|
inline double R () const;
|
||||||
inline double Rt () const;
|
inline double Rt () const;
|
||||||
inline double C () const;
|
inline double C () const;
|
||||||
inline int label () const;
|
inline int label () const;
|
||||||
inline int ap () const;
|
inline int ap () const;
|
||||||
inline Contact* contact () const;
|
inline Contact* contact () const;
|
||||||
inline Node* parent () const;
|
inline Node* parent () const;
|
||||||
inline const std::vector<Node*>& childs () const;
|
inline const std::vector<Node*>& childs () const;
|
||||||
inline void addChild ( Node* );
|
inline void addChild ( Node* );
|
||||||
inline void setLabel ( int );
|
inline void setLabel ( int );
|
||||||
inline void setAp ( int );
|
inline void setAp ( int );
|
||||||
inline void setRt ( double );
|
inline void setRt ( double );
|
||||||
inline void setR ( double );
|
inline void setR ( double );
|
||||||
inline void setC ( double );
|
inline void setC ( double );
|
||||||
|
Record* _getRecord () const;
|
||||||
|
std::string _getString () const;
|
||||||
|
std::string _getTypeName () const;
|
||||||
private :
|
private :
|
||||||
double _R;
|
double _R;
|
||||||
double _Rt;
|
double _Rt;
|
||||||
|
@ -75,3 +78,6 @@ namespace Seabreeze {
|
||||||
|
|
||||||
|
|
||||||
} // Seabreeze namespace;
|
} // Seabreeze namespace;
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Seabreeze::Node);
|
||||||
|
|
|
@ -18,17 +18,18 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "hurricane/Contact.h"
|
namespace Hurricane {
|
||||||
#include "hurricane/RoutingPad.h"
|
class Contact;
|
||||||
#include "hurricane/Component.h"
|
class RoutingPad;
|
||||||
#include "Node.h"
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Seabreeze {
|
namespace Seabreeze {
|
||||||
|
|
||||||
|
using Hurricane::Record;
|
||||||
using Hurricane::Contact;
|
using Hurricane::Contact;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
using Hurricane::Component;
|
class Node;
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -49,6 +50,9 @@ namespace Seabreeze {
|
||||||
void printNode ( std::ostream& , Node* , size_t depth );
|
void printNode ( std::ostream& , Node* , size_t depth );
|
||||||
void print ( std::ostream& );
|
void print ( std::ostream& );
|
||||||
void clear ();
|
void clear ();
|
||||||
|
Record* _getRecord () const;
|
||||||
|
std::string _getString () const;
|
||||||
|
std::string _getTypeName () const;
|
||||||
private:
|
private:
|
||||||
std::vector<Node*> _nodes;
|
std::vector<Node*> _nodes;
|
||||||
};
|
};
|
||||||
|
@ -59,3 +63,6 @@ namespace Seabreeze {
|
||||||
|
|
||||||
|
|
||||||
} // Seabreeze namespace.
|
} // Seabreeze namespace.
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Seabreeze::Tree);
|
||||||
|
|
Loading…
Reference in New Issue