Implement proxy field python methods

This commit is contained in:
Gaute Lindkvist
2020-02-28 14:38:24 +01:00
parent d2e51bdb9b
commit 2cea7c0321
16 changed files with 720 additions and 101 deletions

View File

@@ -1737,7 +1737,8 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
return lhs->classKeyword() < rhs->classKeyword();
} );
std::map<QString, std::map<QString, std::pair<QString, QString>>> classesGenerated;
std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated;
std::map<QString, std::map<QString, QString>> classMethodsGenerated;
std::map<QString, QString> classCommentsGenerated;
// First generate all attributes and comments to go into each object
@@ -1767,10 +1768,13 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
auto ricfHandle = field->template capability<RicfFieldHandle>();
if ( ricfHandle != nullptr )
{
QString snake_field_name = RiaTextStringTools::camelToSnakeCase( ricfHandle->fieldName() );
if ( classesGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
bool shouldBeMethod = false;
auto proxyField = dynamic_cast<const caf::PdmProxyFieldHandle*>( field );
if ( proxyField && proxyField->isStreamingField() ) shouldBeMethod = true;
QString fieldPythonCode = QString( " self.%1 = None\n" ).arg( snake_field_name );
QString snake_field_name = RiaTextStringTools::camelToSnakeCase( ricfHandle->fieldName() );
if ( classAttributesGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
if ( classMethodsGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
QString comment;
{
@@ -1784,9 +1788,47 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
QVariant valueVariant = pdmValueField->toQVariant();
QString dataTypeString = valueVariant.typeName();
classesGenerated[field->ownerClass()][snake_field_name].first = fieldPythonCode;
classesGenerated[field->ownerClass()][snake_field_name].second =
QString( "%1 (%2): %3\n" ).arg( snake_field_name ).arg( dataTypeString ).arg( comment );
if ( shouldBeMethod )
{
if ( proxyField->hasGetter() )
{
QString fullComment =
QString( " \"\"\"%1\n Returns:\n %2\n \"\"\"" )
.arg( comment )
.arg( dataTypeString );
QString fieldCode = QString( " def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( ricfHandle->fieldName() );
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
if ( proxyField->hasSetter() )
{
QString fullComment = QString( " \"\"\"Set %1\n Attributes:\n"
" values (%2): data\n \"\"\"" )
.arg( comment )
.arg( dataTypeString );
QString fieldCode = QString( " def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( ricfHandle->fieldName() );
classMethodsGenerated[field->ownerClass()][QString( "set_%1" ).arg( snake_field_name )] =
fieldCode;
}
}
else
{
QString fieldCode = QString( " self.%1 = None\n" ).arg( snake_field_name );
QString fullComment =
QString( "%1 (%2): %3\n" ).arg( snake_field_name ).arg( dataTypeString ).arg( comment );
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment;
}
}
}
}
@@ -1818,20 +1860,23 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
{
classCode = QString( "class %1(%2):\n" ).arg( scriptClassName ).arg( scriptSuperClassNames.back() );
}
if ( !classCommentsGenerated[classKeyword].isEmpty() || !classesGenerated[classKeyword].empty() )
if ( !classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty() )
{
classCode += " \"\"\"\n";
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
classCode += QString( " %1\n\n" ).arg( classCommentsGenerated[classKeyword] );
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
classCode += QString( " %1\n\n" ).arg( classCommentsGenerated[classKeyword] );
}
}
classCode += " Attributes\n";
classCode += " class_keyword (string): the class keyword that uniquely defines a class\n";
for ( auto keyWordValuePair : classesGenerated[classKeyword] )
if ( !classAttributesGenerated[classKeyword].empty() )
{
classCode += " " + keyWordValuePair.second.second;
classCode += " Attributes\n";
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += " " + keyWordValuePair.second.second;
}
}
classCode += " \"\"\"\n";
}
@@ -1844,7 +1889,7 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
{
// Own attributes. This initializes a lot of attributes to None.
// This means it has to be done before we set any values.
for ( auto keyWordValuePair : classesGenerated[classKeyword] )
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += keyWordValuePair.second.first;
}
@@ -1857,6 +1902,13 @@ void RiaApplication::generatePythonClasses( const QString& fileName )
classCode += QString( " %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n" )
.arg( scriptClassName );
for ( auto keyWordValuePair : classMethodsGenerated[classKeyword] )
{
classCode += "\n";
classCode += keyWordValuePair.second;
classCode += "\n";
}
out << classCode << "\n";
classesWritten.insert( scriptClassName );
}

View File

@@ -11,6 +11,8 @@ service PdmObjectService
rpc GetAncestorPdmObject(PdmParentObjectRequest) returns (PdmObject) {}
rpc CreateChildPdmObject(CreatePdmChildObjectRequest) returns (PdmObject) {}
rpc UpdateExistingPdmObject(PdmObject) returns (Empty) {}
rpc CallPdmObjectGetMethod(PdmObjectMethodRequest) returns (stream PdmObjectGetMethodReply) {}
rpc CallPdmObjectSetMethod(stream PdmObjectSetMethodChunk) returns (ClientToServerStreamReply) {}
}
message PdmDescendantObjectRequest
@@ -49,3 +51,52 @@ message PdmObjectArray
{
repeated PdmObject objects = 1;
}
message PdmObjectMethodRequest
{
PdmObject object = 1;
string method = 2;
}
message PdmObjectSetMethodRequest
{
PdmObjectMethodRequest request = 1;
int32 data_count = 2;
}
message PdmObjectSetMethodChunk
{
oneof data
{
PdmObjectSetMethodRequest set_request = 1;
DoubleArray doubles = 2;
IntArray ints = 3;
StringArray strings = 4;
}
}
message DoubleArray
{
repeated double data = 1;
}
message IntArray
{
repeated int32 data = 1;
}
message StringArray
{
repeated string data = 1;
}
message PdmObjectGetMethodReply
{
oneof data
{
DoubleArray doubles = 1;
IntArray ints = 2;
StringArray strings = 3;
}
}

View File

@@ -0,0 +1,17 @@
######################################################################
# This script retrieves cell result data and alters it
######################################################################
import rips
resinsight = rips.Instance.find()
view = resinsight.project.views()[0]
results = view.cell_result_data()
print ("Number of result values: ", len(results))
newresults = []
for i in range(0, len(results)):
newresults.append(results[i] * -1.0)
view.set_cell_result_data(newresults)

View File

@@ -52,9 +52,12 @@ def _execute_command(self, **command_params):
def __custom_init__(self, pb2_object, channel):
self.__warnings = []
self.__keyword_translation = {}
self.__chunk_size = 8160
if pb2_object is not None:
assert(not isinstance(pb2_object, PdmObject))
self._pb2_object = pb2_object
else:
self._pb2_object = PdmObject_pb2.PdmObject(class_keyword=self.__class__.__name__)
self.class_keyword = self._pb2_object.class_keyword
@@ -246,7 +249,7 @@ def children(self, child_field, class_definition=PdmObject):
A list of PdmObjects inside the child_field
"""
request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object,
child_field=child_field)
child_field=child_field)
try:
object_list = self._pdm_object_stub.GetChildPdmObjects(request).objects
return self.__from_pb2_to_pdm_objects(object_list, class_definition)
@@ -281,6 +284,61 @@ def ancestor(self, class_definition):
return None
raise e
@add_method(PdmObject)
def _call_get_method_async(self, method_name):
request = PdmObject_pb2.PdmObjectMethodRequest(object=self._pb2_object, method=method_name)
for chunk in self._pdm_object_stub.CallPdmObjectGetMethod(request):
yield chunk
@add_method(PdmObject)
def _call_get_method(self, method_name):
all_values = []
generator = self._call_get_method_async(method_name)
for chunk in generator:
data = getattr(chunk, chunk.WhichOneof('data'))
for value in data.data:
all_values.append(value)
return all_values
@add_method(PdmObject)
def __generate_set_method_chunks(self, array, method_request):
index = -1
while index < len(array):
chunk = PdmObject_pb2.PdmObjectSetMethodChunk()
if index is -1:
chunk.set_request.CopyFrom(PdmObject_pb2.PdmObjectSetMethodRequest(request=method_request, data_count=len(array)))
index += 1
else:
actual_chunk_size = min(len(array) - index + 1, self.__chunk_size)
if isinstance(array[0], float):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetMethodChunk(doubles=PdmObject_pb2.DoubleArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], int):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetMethodChunk(ints=PdmObject_pb2.IntArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], str):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetMethodChunk(strings=PdmObject_pb2.StringArray(data=array[index:index +
actual_chunk_size])))
else:
raise Exception("Wrong data type for set method")
index += actual_chunk_size
yield chunk
# Final empty message to signal completion
chunk = PdmObject_pb2.PdmObjectSetMethodChunk()
yield chunk
@add_method(PdmObject)
def _call_set_method(self, method_name, values):
method_request = PdmObject_pb2.PdmObjectMethodRequest(object=self._pb2_object, method=method_name)
request_iterator = self.__generate_set_method_chunks(values, method_request)
reply = self._pdm_object_stub.CallPdmObjectSetMethod(request_iterator)
if reply.accepted_value_count < len(values):
raise IndexError
@add_method(PdmObject)
def update(self):
"""Sync all fields from the Python Object to ResInsight"""

View File

@@ -348,8 +348,8 @@ void RiaGrpcClientToServerStreamCallback<ServiceT, RequestT, ReplyT, StateHandle
}
else
{
CAF_ASSERT( m_stateHandler->streamedValueCount() <= m_stateHandler->cellCount() );
if ( m_stateHandler->streamedValueCount() == m_stateHandler->cellCount() )
CAF_ASSERT( m_stateHandler->streamedValueCount() <= m_stateHandler->totalValueCount() );
if ( m_stateHandler->streamedValueCount() == m_stateHandler->totalValueCount() )
{
this->setNextCallState( RiaGrpcCallbackInterface::FINISH_REQUEST );
m_reader.Finish( this->m_reply, grpc::Status::OK, this );

View File

@@ -422,7 +422,7 @@ grpc::Status RiaNNCInputValuesStateHandler::receiveStreamRequest( const NNCValue
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RiaNNCInputValuesStateHandler::cellCount() const
size_t RiaNNCInputValuesStateHandler::totalValueCount() const
{
return m_cellCount;
}

View File

@@ -84,7 +84,7 @@ public:
grpc::Status init( const rips::NNCValuesInputRequest* request );
grpc::Status receiveStreamRequest( const rips::NNCValuesChunk* request, rips::ClientToServerStreamReply* reply );
size_t cellCount() const;
size_t totalValueCount() const;
size_t streamedValueCount() const;
void finish();

View File

@@ -28,6 +28,303 @@
using namespace rips;
template <typename DataType>
struct DataHolder : public AbstractDataHolder
{
DataHolder( const DataType& data )
: data( data )
{
}
size_t dataCount() const override { return data.size(); }
size_t dataSizeOf() const override { return sizeof( typename DataType::value_type ); }
void reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const;
void addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const;
size_t getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk );
void applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField );
DataType data;
};
template <>
void DataHolder<std::vector<int>>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_ints()->mutable_data()->Reserve( data.size() );
}
template <>
void DataHolder<std::vector<int>>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_ints()->add_data( data[valueIndex] );
}
template <>
size_t DataHolder<std::vector<int>>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk )
{
size_t chunkSize = chunk->ints().data_size();
size_t currentIndex = startIndex;
size_t chunkIndex = 0u;
for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex )
{
data[currentIndex] = chunk->ints().data()[chunkIndex];
}
return chunkSize;
}
template <>
void DataHolder<std::vector<int>>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField )
{
auto proxyValueField = dynamic_cast<caf::PdmProxyValueField<std::vector<int>>*>( proxyField );
CAF_ASSERT( proxyValueField );
if ( proxyValueField )
{
proxyValueField->setValue( data );
}
}
template <>
void DataHolder<std::vector<double>>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_doubles()->mutable_data()->Reserve( data.size() );
}
template <>
void DataHolder<std::vector<double>>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_doubles()->add_data( data[valueIndex] );
}
template <>
size_t DataHolder<std::vector<double>>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk )
{
size_t chunkSize = chunk->doubles().data_size();
size_t currentIndex = startIndex;
size_t chunkIndex = 0u;
for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex )
{
data[currentIndex] = chunk->doubles().data()[chunkIndex];
}
return chunkSize;
}
template <>
void DataHolder<std::vector<double>>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField )
{
auto proxyValueField = dynamic_cast<caf::PdmProxyValueField<std::vector<double>>*>( proxyField );
CAF_ASSERT( proxyValueField );
if ( proxyValueField )
{
proxyValueField->setValue( data );
}
}
template <>
void DataHolder<std::vector<QString>>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_strings()->mutable_data()->Reserve( data.size() );
}
template <>
void DataHolder<std::vector<QString>>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const
{
reply->mutable_strings()->add_data( data[valueIndex].toStdString() );
}
template <>
size_t DataHolder<std::vector<QString>>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk )
{
size_t chunkSize = chunk->strings().data_size();
size_t currentIndex = startIndex;
size_t chunkIndex = 0u;
for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex )
{
data[currentIndex] = QString::fromStdString( chunk->strings().data()[chunkIndex] );
}
return chunkSize;
}
template <>
void DataHolder<std::vector<QString>>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField )
{
auto proxyValueField = dynamic_cast<caf::PdmProxyValueField<std::vector<QString>>*>( proxyField );
CAF_ASSERT( proxyValueField );
if ( proxyValueField )
{
proxyValueField->setValue( data );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPdmObjectMethodStateHandler::RiaPdmObjectMethodStateHandler( bool clientToServerStreamer )
: m_fieldOwner( nullptr )
, m_proxyField( nullptr )
, m_currentDataIndex( 0u )
, m_clientToServerStreamer( clientToServerStreamer )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectMethodRequest* request )
{
CAF_ASSERT( !m_clientToServerStreamer );
m_fieldOwner = RiaGrpcPdmObjectService::findCafObjectFromRipsObject( request->object() );
QString fieldName = QString::fromStdString( request->method() );
std::vector<caf::PdmFieldHandle*> fields;
m_fieldOwner->fields( fields );
for ( auto field : fields )
{
if ( field->keyword() == fieldName )
{
caf::PdmProxyFieldHandle* proxyField = dynamic_cast<caf::PdmProxyFieldHandle*>( field );
if ( proxyField )
{
m_proxyField = proxyField;
if ( dynamic_cast<caf::PdmProxyValueField<std::vector<int>>*>( field ) )
{
auto dataField = dynamic_cast<caf::PdmProxyValueField<std::vector<int>>*>( field );
m_dataHolder.reset( new DataHolder<std::vector<int>>( dataField->value() ) );
return grpc::Status::OK;
}
else if ( dynamic_cast<caf::PdmProxyValueField<std::vector<double>>*>( field ) )
{
auto dataField = dynamic_cast<caf::PdmProxyValueField<std::vector<double>>*>( field );
m_dataHolder.reset( new DataHolder<std::vector<double>>( dataField->value() ) );
return grpc::Status::OK;
}
else if ( dynamic_cast<caf::PdmProxyValueField<std::vector<QString>>*>( field ) )
{
auto dataField = dynamic_cast<caf::PdmProxyValueField<std::vector<QString>>*>( field );
m_dataHolder.reset( new DataHolder<std::vector<QString>>( dataField->value() ) );
return grpc::Status::OK;
}
else
{
CAF_ASSERT( false && "The proxy field data type is not yet supported for streaming fields" );
}
}
}
}
return grpc::Status( grpc::NOT_FOUND, "Proxy field not found" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectSetMethodChunk* chunk )
{
CAF_ASSERT( m_clientToServerStreamer );
CAF_ASSERT( chunk->has_set_request() );
auto setRequest = chunk->set_request();
auto methodRequest = setRequest.request();
m_fieldOwner = RiaGrpcPdmObjectService::findCafObjectFromRipsObject( methodRequest.object() );
QString fieldName = QString::fromStdString( methodRequest.method() );
int valueCount = setRequest.data_count();
std::vector<caf::PdmFieldHandle*> fields;
m_fieldOwner->fields( fields );
for ( auto field : fields )
{
if ( field->keyword() == fieldName )
{
caf::PdmProxyFieldHandle* proxyField = dynamic_cast<caf::PdmProxyFieldHandle*>( field );
if ( proxyField )
{
m_proxyField = proxyField;
if ( dynamic_cast<caf::PdmProxyValueField<std::vector<int>>*>( field ) )
{
m_dataHolder.reset( new DataHolder<std::vector<int>>( std::vector<int>( valueCount ) ) );
return grpc::Status::OK;
}
else if ( dynamic_cast<caf::PdmProxyValueField<std::vector<double>>*>( field ) )
{
m_dataHolder.reset( new DataHolder<std::vector<double>>( std::vector<double>( valueCount ) ) );
return grpc::Status::OK;
}
else if ( dynamic_cast<caf::PdmProxyValueField<std::vector<QString>>*>( field ) )
{
m_dataHolder.reset( new DataHolder<std::vector<QString>>( std::vector<QString>( valueCount ) ) );
return grpc::Status::OK;
}
else
{
CAF_ASSERT( false && "The proxy field data type is not yet supported for streaming fields" );
}
}
}
}
return grpc::Status( grpc::NOT_FOUND, "Proxy field not found" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaPdmObjectMethodStateHandler::assignReply( rips::PdmObjectGetMethodReply* reply )
{
CAF_ASSERT( m_dataHolder );
const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( m_dataHolder->dataSizeOf() );
size_t indexInPackage = 0u;
m_dataHolder->reserveReplyStorage( reply );
for ( ; indexInPackage < packageSize && m_currentDataIndex < m_dataHolder->dataCount(); ++indexInPackage )
{
m_dataHolder->addValueToReply( m_currentDataIndex, reply );
m_currentDataIndex++;
}
if ( indexInPackage > 0u )
{
return grpc::Status::OK;
}
return grpc::Status( grpc::OUT_OF_RANGE,
"We've reached the end. This is not an error but means transmission is finished" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Status RiaPdmObjectMethodStateHandler::receiveRequest( const rips::PdmObjectSetMethodChunk* chunk,
rips::ClientToServerStreamReply* reply )
{
size_t valuesWritten = m_dataHolder->getValuesFromChunk( m_currentDataIndex, chunk );
m_currentDataIndex += valuesWritten;
if ( m_currentDataIndex > totalValueCount() )
{
return grpc::Status( grpc::OUT_OF_RANGE, "Attempting to write out of bounds" );
}
reply->set_accepted_value_count( static_cast<int64_t>( m_currentDataIndex ) );
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RiaPdmObjectMethodStateHandler::streamedValueCount() const
{
return m_currentDataIndex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RiaPdmObjectMethodStateHandler::totalValueCount() const
{
return m_dataHolder->dataCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaPdmObjectMethodStateHandler::finish()
{
if ( m_proxyField )
{
QVariant before = m_proxyField->toQVariant();
m_dataHolder->applyValuesToProxyField( m_proxyField );
QVariant after = m_proxyField->toQVariant();
m_fieldOwner->fieldChangedByUi( m_proxyField, before, after );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -74,22 +371,7 @@ grpc::Status RiaGrpcPdmObjectService::GetDescendantPdmObjects( grpc::ServerConte
const rips::PdmDescendantObjectRequest* request,
rips::PdmObjectArray* reply )
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( request->object().class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
caf::PdmObject* matchingObject = nullptr;
for ( caf::PdmObject* testObject : objectsOfCurrentClass )
{
if ( reinterpret_cast<uint64_t>( testObject ) == request->object().address() )
{
matchingObject = testObject;
}
}
auto matchingObject = findCafObjectFromRipsObject( request->object() );
if ( matchingObject )
{
@@ -114,23 +396,7 @@ grpc::Status RiaGrpcPdmObjectService::GetChildPdmObjects( grpc::ServerContext*
const rips::PdmChildObjectRequest* request,
rips::PdmObjectArray* reply )
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( request->object().class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
caf::PdmObject* matchingObject = nullptr;
for ( caf::PdmObject* testObject : objectsOfCurrentClass )
{
if ( reinterpret_cast<uint64_t>( testObject ) == request->object().address() )
{
matchingObject = testObject;
}
}
auto matchingObject = findCafObjectFromRipsObject( request->object() );
if ( matchingObject )
{
QString fieldName = QString::fromStdString( request->child_field() );
@@ -162,22 +428,7 @@ grpc::Status RiaGrpcPdmObjectService::UpdateExistingPdmObject( grpc::ServerConte
const rips::PdmObject* request,
rips::Empty* response )
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( request->class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
caf::PdmObject* matchingObject = nullptr;
for ( caf::PdmObject* pdmObject : objectsOfCurrentClass )
{
if ( reinterpret_cast<uint64_t>( pdmObject ) == request->address() )
{
matchingObject = pdmObject;
}
}
auto matchingObject = findCafObjectFromRipsObject( *request );
if ( matchingObject )
{
@@ -191,7 +442,8 @@ grpc::Status RiaGrpcPdmObjectService::UpdateExistingPdmObject( grpc::ServerConte
}
matchingObject->updateAllRequiredEditors();
project->scheduleCreateDisplayModelAndRedrawAllViews();
RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews();
Rim3dView* view = dynamic_cast<Rim3dView*>( matchingObject );
if ( view )
{
@@ -209,22 +461,7 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext*
const rips::CreatePdmChildObjectRequest* request,
rips::PdmObject* reply )
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( request->object().class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
caf::PdmObject* matchingObject = nullptr;
for ( caf::PdmObject* testObject : objectsOfCurrentClass )
{
if ( reinterpret_cast<uint64_t>( testObject ) == request->object().address() )
{
matchingObject = testObject;
}
}
auto matchingObject = findCafObjectFromRipsObject( request->object() );
if ( matchingObject )
{
@@ -242,6 +479,28 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext*
return grpc::Status( grpc::NOT_FOUND, "Could not find PdmObject" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::CallPdmObjectGetMethod( grpc::ServerContext* context,
const rips::PdmObjectMethodRequest* request,
rips::PdmObjectGetMethodReply* reply,
RiaPdmObjectMethodStateHandler* stateHandler )
{
return stateHandler->assignReply( reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::CallPdmObjectSetMethod( grpc::ServerContext* context,
const rips::PdmObjectSetMethodChunk* chunk,
rips::ClientToServerStreamReply* reply,
RiaPdmObjectMethodStateHandler* stateHandler )
{
return stateHandler->receiveRequest( chunk, reply );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -262,7 +521,47 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcPdmObjectService::createCallbacks(
&Self::RequestUpdateExistingPdmObject ),
new RiaGrpcUnaryCallback<Self, CreatePdmChildObjectRequest, PdmObject>( this,
&Self::CreateChildPdmObject,
&Self::RequestCreateChildPdmObject )};
&Self::RequestCreateChildPdmObject ),
new RiaGrpcServerToClientStreamCallback<Self,
PdmObjectMethodRequest,
PdmObjectGetMethodReply,
RiaPdmObjectMethodStateHandler>( this,
&Self::CallPdmObjectGetMethod,
&Self::RequestCallPdmObjectGetMethod,
new RiaPdmObjectMethodStateHandler ),
new RiaGrpcClientToServerStreamCallback<Self,
PdmObjectSetMethodChunk,
ClientToServerStreamReply,
RiaPdmObjectMethodStateHandler>( this,
&Self::CallPdmObjectSetMethod,
&Self::RequestCallPdmObjectSetMethod,
new RiaPdmObjectMethodStateHandler(
true ) )};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmObject* RiaGrpcPdmObjectService::findCafObjectFromRipsObject( const rips::PdmObject& ripsObject )
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
QString scriptClassName = QString::fromStdString( ripsObject.class_keyword() );
QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName );
project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass );
caf::PdmObject* matchingObject = nullptr;
for ( caf::PdmObject* testObject : objectsOfCurrentClass )
{
if ( reinterpret_cast<uint64_t>( testObject ) == ripsObject.address() )
{
matchingObject = testObject;
}
}
return matchingObject;
}
static bool RiaGrpcPdmObjectService_init = RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcPdmObjectService>(

View File

@@ -23,6 +23,50 @@
#include <grpcpp/grpcpp.h>
#include <vector>
namespace caf
{
class PdmProxyFieldHandle;
}
struct AbstractDataHolder
{
virtual size_t dataCount() const = 0;
virtual size_t dataSizeOf() const = 0;
virtual void reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const = 0;
virtual void addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const = 0;
virtual size_t getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ) = 0;
virtual void applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ) = 0;
};
//==================================================================================================
//
// State handler for streaming of active cell info
//
//==================================================================================================
class RiaPdmObjectMethodStateHandler
{
typedef grpc::Status Status;
public:
RiaPdmObjectMethodStateHandler( bool clientToServerStreamer = false );
Status init( const rips::PdmObjectMethodRequest* request );
Status init( const rips::PdmObjectSetMethodChunk* chunk );
Status assignReply( rips::PdmObjectGetMethodReply* reply );
Status receiveRequest( const rips::PdmObjectSetMethodChunk* chunk, rips::ClientToServerStreamReply* reply );
size_t streamedValueCount() const;
size_t totalValueCount() const;
void finish();
protected:
caf::PdmObject* m_fieldOwner;
caf::PdmProxyFieldHandle* m_proxyField;
std::unique_ptr<AbstractDataHolder> m_dataHolder;
size_t m_currentDataIndex;
bool m_clientToServerStreamer;
};
//==================================================================================================
//
// gRPC-service answering request searching for PdmObjects in property tree
@@ -49,5 +93,16 @@ public:
const rips::PdmObject* request,
rips::Empty* response ) override;
grpc::Status CallPdmObjectGetMethod( grpc::ServerContext* context,
const rips::PdmObjectMethodRequest* request,
rips::PdmObjectGetMethodReply* reply,
RiaPdmObjectMethodStateHandler* stateHandler );
grpc::Status CallPdmObjectSetMethod( grpc::ServerContext* context,
const rips::PdmObjectSetMethodChunk* chunk,
rips::ClientToServerStreamReply* reply,
RiaPdmObjectMethodStateHandler* stateHandler );
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
static caf::PdmObject* findCafObjectFromRipsObject( const rips::PdmObject& ripsObject );
};

View File

@@ -70,7 +70,7 @@ public:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t cellCount() const { return m_cellCount; }
size_t totalValueCount() const { return m_cellCount; }
//--------------------------------------------------------------------------------------------------
///

View File

@@ -29,6 +29,7 @@
#include "cafPdmChildField.h"
#include "cafPdmDataValueField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmXmlFieldHandle.h"
#include <grpcpp/grpcpp.h>
@@ -100,10 +101,14 @@ void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHa
auto ricfHandle = field->template capability<RicfFieldHandle>();
if ( ricfHandle != nullptr )
{
QString text;
QTextStream outStream( &text );
ricfHandle->writeFieldData( outStream, false );
( *parametersMap )[ricfHandle->fieldName().toStdString()] = text.toStdString();
auto pdmProxyField = dynamic_cast<const caf::PdmProxyFieldHandle*>( field );
if ( !( pdmProxyField && pdmProxyField->isStreamingField() ) )
{
QString text;
QTextStream outStream( &text );
ricfHandle->writeFieldData( outStream, false );
( *parametersMap )[ricfHandle->fieldName().toStdString()] = text.toStdString();
}
}
}
}

View File

@@ -21,6 +21,7 @@
#include "RimEclipseCellColors.h"
#include "RiaColorTables.h"
#include "RicfCommandObject.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigFlowDiagResults.h"
@@ -50,7 +51,7 @@ CAF_PDM_SOURCE_INIT( RimEclipseCellColors, "ResultSlot" );
//--------------------------------------------------------------------------------------------------
RimEclipseCellColors::RimEclipseCellColors()
{
CAF_PDM_InitObject( "Cell Result", ":/CellResult.png", "", "" );
RICF_InitObjectWithScriptNameAndComment( "Cell Result", ":/CellResult.png", "", "", "CellColors", "Eclipse Cell Colors class" );
CAF_PDM_InitFieldNoDefault( &obsoleteField_legendConfig, "LegendDefinition", "Color Legend", "", "", "" );
this->obsoleteField_legendConfig.xmlCapability()->setIOWritable( false );

View File

@@ -95,7 +95,7 @@ RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::Labe
, m_labelPosition( labelPosition )
, m_ternaryEnabled( true )
{
CAF_PDM_InitObject( "Result Definition", "", "", "" );
RICF_InitObjectWithScriptNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" );
RICF_InitFieldNoDefault( &m_resultType, "ResultType", "Type", "", "", "" );
m_resultType.uiCapability()->setUiHidden( true );

View File

@@ -172,8 +172,12 @@ RimEclipseView::RimEclipseView()
CAF_PDM_InitField( &m_showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells", "", "", "" );
CAF_PDM_InitField( &m_showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", "" );
this->cellResult()->setReservoirView( this );
RICF_InitFieldNoDefault( &m_cellResultData, "CellResultData", "", "", "", "Current Eclipse Cell Result" );
m_cellResultData.xmlCapability()->disableIO();
m_cellResultData.registerGetMethod( this, &RimEclipseView::currentCellResultData );
m_cellResultData.registerSetMethod( this, &RimEclipseView::setCurrentCellResultData );
this->cellResult()->setReservoirView( this );
this->cellEdgeResult()->setReservoirView( this );
this->cellEdgeResult()->legendConfig()->setColorRange( RimRegularLegendConfig::PINK_WHITE );
@@ -351,6 +355,12 @@ void RimEclipseView::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
scheduleCreateDisplayModelAndRedraw();
}
else if ( changedField == &m_cellResultData )
{
currentGridCellResults()->recalculateStatistics( m_cellResult->eclipseResultAddress() );
setCurrentTimeStepAndUpdate( currentTimeStep() );
createDisplayModelAndRedraw();
}
}
//--------------------------------------------------------------------------------------------------
@@ -1120,7 +1130,7 @@ void RimEclipseView::onUpdateDisplayModelVisibility()
//--------------------------------------------------------------------------------------------------
/// Convenience for quick access to results
//--------------------------------------------------------------------------------------------------
RigCaseCellResultsData* RimEclipseView::currentGridCellResults()
RigCaseCellResultsData* RimEclipseView::currentGridCellResults() const
{
if ( m_eclipseCase )
{
@@ -1894,6 +1904,45 @@ RimEclipseCellColors* RimEclipseView::currentFaultResultColors()
return faultResultColors;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimEclipseView::currentCellResultData() const
{
std::vector<double> resultData;
if ( currentGridCellResults() && cellResult() )
{
int timeStep = 0;
if ( cellResult()->hasDynamicResult() )
{
timeStep = this->currentTimeStep();
}
resultData = currentGridCellResults()->cellScalarResults( cellResult()->eclipseResultAddress() )[timeStep];
}
return resultData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseView::setCurrentCellResultData( const std::vector<double>& values )
{
if ( currentGridCellResults() && cellResult() )
{
int timeStep = 0;
if ( cellResult()->hasDynamicResult() )
{
timeStep = this->currentTimeStep();
}
std::vector<double>* modResult =
currentGridCellResults()->modifiableCellScalarResult( cellResult()->eclipseResultAddress(), timeStep );
if ( modResult->size() == values.size() )
{
*modResult = values;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -24,6 +24,7 @@
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cvfArray.h"
@@ -101,10 +102,13 @@ public:
const RimEclipsePropertyFilterCollection* eclipsePropertyFilterCollection() const;
void setOverridePropertyFilterCollection( RimEclipsePropertyFilterCollection* pfc );
RigCaseCellResultsData* currentGridCellResults();
RigCaseCellResultsData* currentGridCellResults() const;
const RigActiveCellInfo* currentActiveCellInfo() const;
RimEclipseCellColors* currentFaultResultColors();
std::vector<double> currentCellResultData() const;
void setCurrentCellResultData( const std::vector<double>& values );
void setEclipseCase( RimEclipseCase* reservoir );
RimEclipseCase* eclipseCase() const;
RimCase* ownerCase() const override;
@@ -206,6 +210,8 @@ private:
caf::PdmChildField<RimStimPlanColors*> m_fractureColors;
caf::PdmChildField<RimVirtualPerforationResults*> m_virtualPerforationResult;
caf::PdmProxyValueField<std::vector<double>> m_cellResultData;
caf::PdmChildField<RimSimWellInViewCollection*> m_wellCollection;
caf::PdmChildField<RimFaultInViewCollection*> m_faultCollection;

View File

@@ -8,21 +8,42 @@
#include <QVariant>
#include <type_traits>
#include <vector>
namespace caf
{
//==================================================================================================
/// Abstract non-templated base class for PdmProxyValueField
/// Exists only to be able to determine that a field is a proxy field
//==================================================================================================
class PdmProxyFieldHandle : public PdmValueField
{
public:
virtual bool isStreamingField() const = 0;
virtual bool hasGetter() const = 0;
virtual bool hasSetter() const = 0;
};
//==================================================================================================
/// Type traits magic to check if a template argument is a vector
//==================================================================================================
template<typename T> struct is_vector : public std::false_type {};
template<typename T, typename A> struct is_vector<std::vector<T, A>> : public std::true_type{};
//==================================================================================================
/// Field class encapsulating data access through object setter/getter with input and output of this
/// data to/from a QXmlStream
/// read/write-FieldData is supposed to be specialized for types needing specialization
//==================================================================================================
template<typename DataType >
class PdmProxyValueField : public PdmValueField
class PdmProxyValueField : public PdmProxyFieldHandle
{
public:
typedef DataType FieldDataType;
PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; }
PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; }
~PdmProxyValueField() override { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; }
// Assignment
@@ -34,6 +55,10 @@ public:
void setValue(const DataType& fieldValue) { CAF_ASSERT(isInitializedByInitFieldMacro()); if (m_valueSetter) m_valueSetter->setValue(fieldValue); }
DataType value() const { CAF_ASSERT(m_valueGetter); return m_valueGetter->getValue(); }
bool isStreamingField() const override { return is_vector<DataType>(); }
bool hasGetter() const override { return m_valueGetter != nullptr; }
bool hasSetter() const override { return m_valueSetter != nullptr; }
// Implementation of PdmValueField interface
QVariant toQVariant() const override { DataType val = value(); return PdmValueFieldSpecialization<DataType>::convert(val); }
@@ -130,6 +155,7 @@ private:
SetValueInterface* m_valueSetter;
GetValueInterface* m_valueGetter;
};
} // End of namespace caf