mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 15:10:22 -05:00
Migrate all assert macros in ApplicationLibCode to CAF_ASSERT and remove every use of cvfAssert.h. CVF_ASSERT is replaced one to one. CVF_TIGHT_ASSERT is also replaced by CAF_ASSERT, which is semantically exact: CVF_ENABLE_TIGHT_ASSERTS is 1 only under _DEBUG, and that is what CAF_ASSERT now does. The two CVF_FAIL_MSG sites become CAF_ASSERT( false && "message" ), preserving the message with the idiom already used elsewhere in the code base. Counts before and after: CVF_ASSERT 1044 to 0, CVF_TIGHT_ASSERT 66 to 0, CVF_FAIL_MSG 2 to 0, cvfAssert.h references 154 to 0. Include handling: files that included cvfAssert.h directly now include cafAssert.h instead, includes left dead by the migration are removed, and files that were relying on cvfAssert.h transitively get an explicit cafAssert.h. Files that reach cafAssert.h through another caf header are left unchanged; a missing include here is a compile error, not a silently disabled assert. ResultStatisticsCache links only LibCore and therefore had no path to cafAssert.h. Add the cafPdmCore directory as a private include path rather than linking the library, since cafAssert.h is header only. Note that this stops these asserts from firing in Release and RelWithDebInfo, where CVF_ASSERT was previously active.
414 lines
16 KiB
C++
414 lines
16 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2018- Equinor ASA
|
|
//
|
|
// ResInsight 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 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RicHoloLensSession.h"
|
|
#include "RicHoloLensSessionObserver.h"
|
|
|
|
#include "RiaLogging.h"
|
|
#include "RiaPreferences.h"
|
|
#include "RiaPreferencesSystem.h"
|
|
#include "RiaQStringFormatter.h"
|
|
|
|
#include "VdeArrayDataPacket.h"
|
|
#include "VdeFileExporter.h"
|
|
#include "VdePacketDirectory.h"
|
|
#include "VdeVizDataExtractor.h"
|
|
|
|
#include "cvfTimer.h"
|
|
|
|
#include <QDir>
|
|
|
|
#include <algorithm>
|
|
|
|
//==================================================================================================
|
|
//
|
|
//
|
|
//
|
|
//==================================================================================================
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RicHoloLensSession::RicHoloLensSession()
|
|
: m_isSessionValid( false )
|
|
, m_lastExtractionMetaDataSequenceNumber( -1 )
|
|
, m_sessionObserver( nullptr )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RicHoloLensSession::~RicHoloLensSession()
|
|
{
|
|
destroySession();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RicHoloLensSession* RicHoloLensSession::createSession( const QString& serverUrl,
|
|
const QString& sessionName,
|
|
const QByteArray& sessionPinCode,
|
|
RicHoloLensSessionObserver* sessionObserver )
|
|
{
|
|
RicHoloLensSession* newSession = new RicHoloLensSession;
|
|
|
|
newSession->m_restClient = new RicHoloLensRestClient( serverUrl, sessionName, newSession );
|
|
|
|
if ( RiaPreferences::current()->holoLensDisableCertificateVerification() )
|
|
{
|
|
RiaLogging::warning( "HoloLens: Disabling certificate verification for HTTPS connections" );
|
|
newSession->m_restClient->dbgDisableCertificateVerification();
|
|
}
|
|
|
|
newSession->m_restClient->createSession( sessionPinCode );
|
|
|
|
newSession->m_sessionObserver = sessionObserver;
|
|
|
|
const QString dbgExportFolder = RiaPreferencesSystem::current()->holoLensExportFolder();
|
|
if ( !dbgExportFolder.isEmpty() )
|
|
{
|
|
newSession->m_dbgFileExportDestinationFolder = dbgExportFolder;
|
|
RiaLogging::info( std::format( "HoloLens: Debug file export will be written to folder: {}", dbgExportFolder ) );
|
|
}
|
|
|
|
return newSession;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RicHoloLensSession* RicHoloLensSession::createDummyFileBackedSession()
|
|
{
|
|
RicHoloLensSession* newSession = new RicHoloLensSession;
|
|
|
|
newSession->m_isSessionValid = true;
|
|
|
|
newSession->m_dbgFileExportDestinationFolder = RiaPreferencesSystem::current()->holoLensExportFolder();
|
|
|
|
return newSession;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::destroySession()
|
|
{
|
|
if ( m_restClient )
|
|
{
|
|
if ( m_isSessionValid )
|
|
{
|
|
m_restClient->deleteSession();
|
|
}
|
|
|
|
m_restClient->clearResponseHandler();
|
|
m_restClient->deleteLater();
|
|
m_restClient = nullptr;
|
|
}
|
|
|
|
m_isSessionValid = false;
|
|
|
|
m_lastExtractionMetaDataSequenceNumber = -1;
|
|
m_lastExtractionAllReferencedPacketIdsArr.clear();
|
|
m_packetDirectory.clear();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RicHoloLensSession::isSessionValid() const
|
|
{
|
|
return m_isSessionValid;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::updateSessionDataFromView( const RimGridView& activeView )
|
|
{
|
|
RiaLogging::info( "HoloLens: Updating visualization data" );
|
|
|
|
// Grab the current max ID as an easy way to detect if new IDs have been added for debugging purposes
|
|
const int dbgMaxAssignedIdBeforeExtraction = m_cachingIdFactory.lastAssignedId();
|
|
|
|
// Note that we pass the caching ID factory on the constructor which will try and detect data payloads that
|
|
// are equal, and will then "recycle" the array IDs for these
|
|
VdeVizDataExtractor extractor( activeView, &m_cachingIdFactory );
|
|
|
|
QString modelMetaJsonStr;
|
|
std::vector<int> allReferencedPacketIds;
|
|
extractor.extractViewContents( &modelMetaJsonStr, &allReferencedPacketIds, &m_packetDirectory );
|
|
|
|
// Note!
|
|
// The packet directory should now contain all the packets that are being actively referenced.
|
|
// We now prune out any packets that are no longer being referenced. This means we do no caching of actual packet
|
|
// data over time and that we assume that the server will ask for data packets/arrays right after having received
|
|
// updated meta data
|
|
m_packetDirectory.pruneUnreferencedPackets( allReferencedPacketIds );
|
|
|
|
m_lastExtractionMetaDataSequenceNumber++;
|
|
m_lastExtractionAllReferencedPacketIdsArr = allReferencedPacketIds;
|
|
|
|
if ( m_restClient )
|
|
{
|
|
RiaLogging::info( std::format( "HoloLens: Sending updated meta data to sharing server (sequenceNumber={})",
|
|
m_lastExtractionMetaDataSequenceNumber ) );
|
|
m_restClient->sendMetaData( m_lastExtractionMetaDataSequenceNumber, modelMetaJsonStr );
|
|
}
|
|
|
|
// Debug export to file
|
|
if ( !m_dbgFileExportDestinationFolder.isEmpty() )
|
|
{
|
|
const QDir outputDir( m_dbgFileExportDestinationFolder );
|
|
const QString absOutputFolder = outputDir.absolutePath();
|
|
|
|
if ( !outputDir.mkpath( "." ) )
|
|
{
|
|
RiaLogging::error( std::format( "HoloLens: Could not create debug file export folder: {}", absOutputFolder ) );
|
|
return;
|
|
}
|
|
|
|
// For debugging, write only the new packets to file
|
|
// Determine which packets are new by comparing the IDs to the max known ID before extraction
|
|
std::vector<int> packetIdsToWrite;
|
|
for ( int packetId : allReferencedPacketIds )
|
|
{
|
|
if ( packetId > dbgMaxAssignedIdBeforeExtraction )
|
|
{
|
|
packetIdsToWrite.push_back( packetId );
|
|
}
|
|
}
|
|
|
|
// This will write all packets seen in this extraction to file
|
|
// packetIdsToWrite = allReferencedPacketIds;
|
|
|
|
RiaLogging::info( QString( "HoloLens: Doing debug export of data (%1 packets) to folder: %2" )
|
|
.arg( packetIdsToWrite.size() )
|
|
.arg( absOutputFolder )
|
|
.toStdString() );
|
|
VdeFileExporter fileExporter( absOutputFolder );
|
|
if ( !fileExporter.exportToFile( modelMetaJsonStr, m_packetDirectory, packetIdsToWrite ) )
|
|
{
|
|
RiaLogging::error( "HoloLens: Error exporting debug data to folder" );
|
|
}
|
|
|
|
RiaLogging::info( "HoloLens: Done exporting debug data" );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::handleSuccessfulCreateSession()
|
|
{
|
|
RiaLogging::info( "HoloLens: Session successfully created" );
|
|
m_isSessionValid = true;
|
|
|
|
notifyObserver( RicHoloLensSessionObserver::CreateSessionSucceeded );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::handleFailedCreateSession()
|
|
{
|
|
RiaLogging::error( "HoloLens: Failed to create session" );
|
|
m_isSessionValid = false;
|
|
|
|
notifyObserver( RicHoloLensSessionObserver::CreateSessionFailed );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Handle the server response we receive after sending new meta data
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::handleSuccessfulSendMetaData( int metaDataSequenceNumber, const QByteArray& jsonServerResponseString )
|
|
{
|
|
cvf::Timer tim;
|
|
|
|
RiaLogging::info( std::format( "HoloLens: Processing server response (meta data sequenceNumber={})", metaDataSequenceNumber ) );
|
|
|
|
if ( m_lastExtractionMetaDataSequenceNumber != metaDataSequenceNumber )
|
|
{
|
|
RiaLogging::warning( std::format( "HoloLens: Ignoring server response, the meta data sequenceNumber({}) has been superseded",
|
|
metaDataSequenceNumber ) );
|
|
return;
|
|
}
|
|
|
|
std::vector<int> arrayIdsToSend;
|
|
|
|
// cvf::Trace::show("Raw JSON response from server: '%s'", jsonServerResponseString.data());
|
|
QByteArray trimmedServerResponseString = jsonServerResponseString.trimmed();
|
|
if ( trimmedServerResponseString.size() > 0 )
|
|
{
|
|
if ( !parseJsonIntegerArray( trimmedServerResponseString, &arrayIdsToSend ) )
|
|
{
|
|
RiaLogging::error( "HoloLens: Error parsing array server response with array Ids, no data will be sent to server" );
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// An empty server response means we should send all array referenced by the last sent meta data
|
|
if ( !m_lastExtractionAllReferencedPacketIdsArr.empty() )
|
|
{
|
|
arrayIdsToSend = m_lastExtractionAllReferencedPacketIdsArr;
|
|
RiaLogging::info( "HoloLens: Empty server response, sending all arrays referenced by last meta data" );
|
|
}
|
|
}
|
|
|
|
if ( arrayIdsToSend.empty() )
|
|
{
|
|
RiaLogging::info( "HoloLens: Nothing to do, no data requested by server" );
|
|
return;
|
|
}
|
|
|
|
RiaLogging::info( std::format( "HoloLens: Start sending data to server, {} data arrays have been requested", arrayIdsToSend.size() ) );
|
|
|
|
size_t totalBytesSent = 0;
|
|
size_t totalNumArraysSent = 0;
|
|
|
|
const bool sendAsIndividualPackets = false;
|
|
|
|
// Sending data packets one by one
|
|
if ( sendAsIndividualPackets )
|
|
{
|
|
for ( size_t i = 0; i < arrayIdsToSend.size(); i++ )
|
|
{
|
|
const int arrayId = arrayIdsToSend[i];
|
|
const VdeArrayDataPacket* packet = m_packetDirectory.lookupPacket( arrayId );
|
|
if ( !packet )
|
|
{
|
|
RiaLogging::warning( std::format( "HoloLens: Could not get the requested data from cache, array id: {} ", arrayId ) );
|
|
continue;
|
|
}
|
|
|
|
QByteArray packetByteArr( packet->fullPacketRawPtr(), static_cast<int>( packet->fullPacketSize() ) );
|
|
|
|
RiaLogging::info( QString( "HoloLens: sending array id: %1, %2KB (%3 bytes)" )
|
|
.arg( arrayId )
|
|
.arg( packetByteArr.size() / 1024.0, 0, 'f', 2 )
|
|
.arg( packetByteArr.size() )
|
|
.toStdString() );
|
|
|
|
m_restClient->sendBinaryData( packetByteArr, "arrId" + QByteArray::number( arrayId ) );
|
|
|
|
totalNumArraysSent++;
|
|
totalBytesSent += packetByteArr.size();
|
|
}
|
|
}
|
|
// Sending all requested arrays/packets in one combined packet
|
|
else
|
|
{
|
|
QByteArray combinedPacketArr;
|
|
if ( !m_packetDirectory.getPacketsAsCombinedBuffer( arrayIdsToSend, &combinedPacketArr ) )
|
|
{
|
|
RiaLogging::warning( "HoloLens: Error gathering the requested arrays, no data will be sent" );
|
|
return;
|
|
}
|
|
|
|
totalNumArraysSent = arrayIdsToSend.size();
|
|
totalBytesSent = combinedPacketArr.size();
|
|
|
|
RiaLogging::info( QString( "HoloLens: Sending data to server (%1 arrays combined), %2KB (%3 bytes)" )
|
|
.arg( totalNumArraysSent )
|
|
.arg( totalBytesSent / 1024.0, 0, 'f', 2 )
|
|
.arg( totalBytesSent )
|
|
.toStdString() );
|
|
|
|
m_restClient->sendBinaryData( combinedPacketArr, "metaSeqNum" + QByteArray::number( metaDataSequenceNumber ) );
|
|
}
|
|
|
|
const double totalMb = totalBytesSent / ( 1024.0 * 1024.0 );
|
|
RiaLogging::info( QString( "HoloLens: Finished sending data to server, %1 arrays, total %2MB (%3 bytes) in %4ms" )
|
|
.arg( totalNumArraysSent )
|
|
.arg( totalMb, 0, 'f', 2 )
|
|
.arg( totalBytesSent )
|
|
.arg( static_cast<int>( tim.time() * 1000 ) )
|
|
.toStdString() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RicHoloLensSession::parseJsonIntegerArray( const QByteArray& jsonString, std::vector<int>* integerArr )
|
|
{
|
|
// cvf::Trace::show("jsonString: '%s'", jsonString.data());
|
|
|
|
const int openBraceIdx = jsonString.indexOf( '[' );
|
|
const int closeBraceIdx = jsonString.lastIndexOf( ']' );
|
|
if ( openBraceIdx < 0 || closeBraceIdx < 0 )
|
|
{
|
|
RiaLogging::debug( "Error parsing JSON array, could not find opening or closing braces" );
|
|
return false;
|
|
}
|
|
|
|
if ( closeBraceIdx <= openBraceIdx )
|
|
{
|
|
RiaLogging::debug( "Error parsing JSON array, wrong placement of braces" );
|
|
return false;
|
|
}
|
|
|
|
QByteArray arrayContents = jsonString.mid( openBraceIdx + 1, closeBraceIdx - openBraceIdx - 1 ).trimmed();
|
|
// cvf::Trace::show("arrayContents: '%s'", arrayContents.data());
|
|
|
|
QList<QByteArray> stringList = arrayContents.split( ',' );
|
|
for ( const QByteArray& entry : stringList )
|
|
{
|
|
bool convertOk = false;
|
|
const int intVal = entry.toInt( &convertOk );
|
|
if ( convertOk )
|
|
{
|
|
integerArr->push_back( intVal );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::handleError( const QString& errMsg, const QString& url, const QString& serverData )
|
|
{
|
|
QString fullMsg = "HoloLens communication error: " + errMsg;
|
|
|
|
if ( !serverData.isEmpty() )
|
|
{
|
|
fullMsg += "\n serverMsg: " + serverData;
|
|
}
|
|
|
|
fullMsg += "\n url: " + url;
|
|
|
|
RiaLogging::error( fullMsg.toStdString() );
|
|
|
|
// It is probably not correct to always consider an error a state change, but for now
|
|
notifyObserver( RicHoloLensSessionObserver::GeneralError );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RicHoloLensSession::notifyObserver( RicHoloLensSessionObserver::Notification notification )
|
|
{
|
|
if ( m_sessionObserver )
|
|
{
|
|
m_sessionObserver->handleSessionNotification( this, notification );
|
|
}
|
|
}
|