2017-01-11 23:45:03 +01:00
/*
2020-01-02 06:44:10 +01:00
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
2017-01-11 23:45:03 +01:00
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "QueryCallback.h"
2024-06-12 23:39:27 +02:00
#include "Duration.h"
2017-05-12 18:49:51 +02:00
#include "Errors.h"
2017-01-11 23:45:03 +01:00
2024-06-12 23:39:27 +02:00
QueryCallback :: QueryCallback ( std :: future < QueryResult >&& result ) : _query ( std :: move ( result ))
2017-01-13 21:38:03 +01:00
{
}
2024-06-12 23:39:27 +02:00
QueryCallback :: QueryCallback ( std :: future < PreparedQueryResult >&& result ) : _query ( std :: move ( result ))
2017-01-12 19:40:33 +01:00
{
}
2024-06-12 23:39:27 +02:00
QueryCallback :: QueryCallback ( QueryCallback && right ) noexcept : _query ( std :: move ( right . _query )), _callbacks ( std :: move ( right . _callbacks ))
2017-01-13 21:38:03 +01:00
{
2017-01-11 23:45:03 +01:00
}
2022-11-06 01:03:35 +01:00
QueryCallback & QueryCallback :: operator = ( QueryCallback && right ) noexcept
2017-01-11 23:45:03 +01:00
{
2017-01-13 21:38:03 +01:00
if ( this != & right )
{
2024-06-12 23:39:27 +02:00
_query = std :: move ( right . _query );
2017-01-13 21:38:03 +01:00
_callbacks = std :: move ( right . _callbacks );
}
2017-01-11 23:45:03 +01:00
return * this ;
}
2024-06-12 23:39:27 +02:00
QueryCallback ::~ QueryCallback () = default ;
2017-01-11 23:45:03 +01:00
2017-01-13 21:38:03 +01:00
QueryCallback && QueryCallback :: WithCallback ( std :: function < void ( QueryResult ) >&& callback )
{
2024-06-12 23:39:27 +02:00
return WithChainingCallback ([ callback = std :: move ( callback )]( QueryCallback & /*this*/ , QueryResult result ) { callback ( std :: move ( result )); });
2017-01-13 21:38:03 +01:00
}
QueryCallback && QueryCallback :: WithPreparedCallback ( std :: function < void ( PreparedQueryResult ) >&& callback )
{
2024-06-12 23:39:27 +02:00
return WithChainingPreparedCallback ([ callback = std :: move ( callback )]( QueryCallback & /*this*/ , PreparedQueryResult result ) { callback ( std :: move ( result )); });
2017-01-13 21:38:03 +01:00
}
QueryCallback && QueryCallback :: WithChainingCallback ( std :: function < void ( QueryCallback & , QueryResult ) >&& callback )
2017-01-11 23:45:03 +01:00
{
2024-06-12 23:39:27 +02:00
ASSERT ( ! _callbacks . empty () || std :: holds_alternative < std :: future < QueryResult >> ( _query ), "Attempted to set callback function for string query on a prepared async query" );
2017-01-12 19:40:33 +01:00
_callbacks . emplace ( std :: move ( callback ));
2017-01-11 23:45:03 +01:00
return std :: move ( * this );
}
2017-01-13 21:38:03 +01:00
QueryCallback && QueryCallback :: WithChainingPreparedCallback ( std :: function < void ( QueryCallback & , PreparedQueryResult ) >&& callback )
2017-01-11 23:45:03 +01:00
{
2024-06-12 23:39:27 +02:00
ASSERT ( ! _callbacks . empty () || std :: holds_alternative < std :: future < PreparedQueryResult >> ( _query ), "Attempted to set callback function for prepared query on a string async query" );
2017-01-12 19:40:33 +01:00
_callbacks . emplace ( std :: move ( callback ));
2017-01-11 23:45:03 +01:00
return std :: move ( * this );
}
2017-01-13 21:38:03 +01:00
void QueryCallback :: SetNextQuery ( QueryCallback && next )
{
2024-06-12 23:39:27 +02:00
if ( this != & next )
_query = std :: move ( next ). _query ;
2017-01-13 21:38:03 +01:00
}
2020-04-14 16:23:44 +02:00
bool QueryCallback :: InvokeIfReady ()
2017-01-11 23:45:03 +01:00
{
2017-01-13 21:38:03 +01:00
auto checkStateAndReturnCompletion = [ this ]()
{
_callbacks . pop ();
2024-06-12 23:39:27 +02:00
bool hasNext = std :: visit ([]( auto const & future ) { return future . valid (); }, _query );
2017-01-13 21:38:03 +01:00
if ( _callbacks . empty ())
{
ASSERT ( ! hasNext );
2020-04-14 16:23:44 +02:00
return true ;
2017-01-13 21:38:03 +01:00
}
// abort chain
if ( ! hasNext )
2020-04-14 16:23:44 +02:00
return true ;
2017-01-13 21:38:03 +01:00
2024-06-12 23:39:27 +02:00
ASSERT ( _query . index () == _callbacks . front (). index ());
2020-04-14 16:23:44 +02:00
return false ;
2017-01-13 21:38:03 +01:00
};
2024-06-12 23:39:27 +02:00
return std :: visit ([ & ] < typename Result > ( std :: future < Result >&& future )
2017-01-11 23:45:03 +01:00
{
2024-06-12 23:39:27 +02:00
if ( future . valid () && future . wait_for ( 0 s ) == std :: future_status :: ready )
2017-01-11 23:45:03 +01:00
{
2024-06-12 23:39:27 +02:00
std :: future < Result > f ( std :: move ( future ));
std :: function < void ( QueryCallback & , Result ) > cb ( std :: get < std :: function < void ( QueryCallback & , Result ) >> ( std :: move ( _callbacks . front ())));
2017-01-13 21:38:03 +01:00
cb ( * this , f . get ());
return checkStateAndReturnCompletion ();
2017-01-11 23:45:03 +01:00
}
2024-06-12 23:39:27 +02:00
return false ;
}, std :: move ( _query ));
2017-01-11 23:45:03 +01:00
}