@@ -14,7 +14,7 @@ SymbolTableModel::SymbolTableModel(SymbolTableView* parent)
1414
1515int SymbolTableModel::rowCount (const QModelIndex& parent) const {
1616 Q_UNUSED (parent);
17- return static_cast <int >(m_symbols .size ());
17+ return static_cast <int >(m_modelSymbols .size ());
1818}
1919
2020int SymbolTableModel::columnCount (const QModelIndex& parent) const {
@@ -28,7 +28,7 @@ QVariant SymbolTableModel::data(const QModelIndex& index, int role) const {
2828 return QVariant ();
2929 }
3030
31- const CacheSymbol& symbol = m_symbols. at (index.row ());
31+ auto symbol = symbolAt (index.row ());
3232 auto symbolType = GetSymbolTypeAsString (symbol.type );
3333
3434 switch (index.column ()) {
@@ -60,13 +60,15 @@ QVariant SymbolTableModel::headerData(int section, Qt::Orientation orientation,
6060 }
6161}
6262
63- void SymbolTableModel::updateSymbols () {
64- m_symbols = m_parent->m_symbols ;
63+ void SymbolTableModel::updateSymbols (std::vector<CacheSymbol>&& symbols)
64+ {
65+ m_preparedSymbols = symbols;
6566 setFilter (m_filter);
6667}
6768
68- const CacheSymbol& SymbolTableModel::symbolAt (int row) const {
69- return m_symbols.at (row);
69+ const CacheSymbol& SymbolTableModel::symbolAt (int row) const
70+ {
71+ return m_modelSymbols.at (row);
7072}
7173
7274
@@ -75,23 +77,19 @@ void SymbolTableModel::setFilter(std::string text)
7577 beginResetModel ();
7678
7779 m_filter = text;
78- m_symbols. clear () ;
80+ m_modelSymbols = {} ;
7981
80- if (m_filter.empty ())
82+ // Skip filtering if no filter applied.
83+ if (!m_filter.empty ())
8184 {
82- m_symbols = m_parent->m_symbols ;
83- }
84- else
85- {
86- m_symbols.reserve (m_parent->m_symbols .size ());
87- for (const auto & symbol : m_parent->m_symbols )
88- {
85+ m_modelSymbols.reserve (m_preparedSymbols.size ());
86+ for (const auto & symbol : m_preparedSymbols)
8987 if (((std::string_view)symbol.name ).find (m_filter) != std::string::npos)
90- {
91- m_symbols. push_back (symbol );
92- }
93- }
94- m_symbols. shrink_to_fit () ;
88+ m_modelSymbols. push_back (symbol);
89+ m_modelSymbols. shrink_to_fit ( );
90+ } else
91+ {
92+ m_modelSymbols = m_preparedSymbols ;
9593 }
9694
9795 endResetModel ();
@@ -121,14 +119,26 @@ SymbolTableView::~SymbolTableView() {
121119void SymbolTableView::populateSymbols (BinaryView &view)
122120{
123121 if (auto controller = SharedCacheController::GetController (view)) {
124- BackgroundThread::create (this )
125- ->thenBackground ([this , controller]() {
126- // TODO: There is a crash related to `this` being destructed. https://github.com/Vector35/binaryninja-api/issues/6300
127- std::vector<CacheSymbol> newSymbols = controller->GetSymbols ();
128- m_symbols.swap (newSymbols);
129- })
130- ->thenMainThread ([this ](){ m_model->updateSymbols (); })
131- ->start ();
122+ typedef std::vector<CacheSymbol> SymbolList;
123+ // Retrieve the symbols from the controller in a future than pass that to the model.
124+ QPointer<QFutureWatcher<SymbolList>> watcher = new QFutureWatcher<SymbolList>(this );
125+ connect (watcher, &QFutureWatcher<SymbolList>::finished, this , [watcher, this ]() {
126+ if (watcher)
127+ {
128+ auto symbols = watcher->result ();
129+ m_model->updateSymbols (std::move (symbols));
130+ }
131+ });
132+ QFuture<SymbolList> future = QtConcurrent::run ([controller]() {
133+ return controller->GetSymbols ();
134+ });
135+ watcher->setFuture (future);
136+ connect (this , &QObject::destroyed, this , [watcher]() {
137+ if (watcher && watcher->isRunning ()) {
138+ watcher->cancel ();
139+ watcher->waitForFinished ();
140+ }
141+ });
132142 }
133143}
134144
0 commit comments