diff --git a/framework/cybertron/tools/cvt/monitor/channel_msg_factory.h b/framework/cybertron/tools/cvt/monitor/channel_msg_factory.h index e987739742711aa73d78f3563d5914647ae88fb1..f4abd1bfefb68f226ec10d7cd48d37248910ad94 100644 --- a/framework/cybertron/tools/cvt/monitor/channel_msg_factory.h +++ b/framework/cybertron/tools/cvt/monitor/channel_msg_factory.h @@ -68,8 +68,7 @@ class ChannelMsgFactory final { private: explicit ChannelMsgFactory(); ChannelMsgFactory(const ChannelMsgFactory& other) = delete; - ChannelMsgFactory& operator=(const ChannelMsgFactory&) = - delete; + ChannelMsgFactory& operator=(const ChannelMsgFactory&) = delete; int pid_; std::map::const_iterator default_child_factory_; diff --git a/framework/cybertron/tools/cvt/monitor/cybertron_channel_message.h b/framework/cybertron/tools/cvt/monitor/cybertron_channel_message.h index dab41c427aa35c113eb79617ad672e20b34e8517..b53e49766725c58f8c705223d1d4de6fb90317c8 100644 --- a/framework/cybertron/tools/cvt/monitor/cybertron_channel_message.h +++ b/framework/cybertron/tools/cvt/monitor/cybertron_channel_message.h @@ -17,10 +17,10 @@ #ifndef TOOLS_CVT_MONITOR_CYBERTRON_CHANNEL_MESSAGE_H_ #define TOOLS_CVT_MONITOR_CYBERTRON_CHANNEL_MESSAGE_H_ +#include "cybertron/cybertron.h" #include "cybertron/time/duration.h" #include "cybertron/time/time.h" #include "renderable_message.h" -#include "cybertron/cybertron.h" #include #include @@ -91,8 +91,11 @@ class ChannelMessage : public RenderableMessage { } const std::string& message_type(void) const { return message_type_; } - bool is_enabled(void)const{ return is_enabled_; } - void set_enabled(bool b){ is_enabled_ = b; if(!b) set_has_message_come(false); } + bool is_enabled(void) const { return is_enabled_; } + void set_enabled(bool b) { + is_enabled_ = b; + if (!b) set_has_message_come(false); + } bool has_message_come(void) const { return has_message_come_; } @@ -116,9 +119,9 @@ class ChannelMessage : public RenderableMessage { void del_reader(const std::string& reader) { DoDelete(readers_, reader); } void add_writer(const std::string& writer) { writers_.push_back(writer); } - void del_writer(const std::string& writer) { - DoDelete(writers_, writer); - if(!writers_.size()){ + void del_writer(const std::string& writer) { + DoDelete(writers_, writer); + if (!writers_.size()) { set_has_message_come(false); } } @@ -133,7 +136,7 @@ class ChannelMessage : public RenderableMessage { } } - void set_has_message_come(bool b){ has_message_come_ = b; } + void set_has_message_come(bool b) { has_message_come_ = b; } bool is_enabled_; bool has_message_come_; @@ -159,9 +162,13 @@ class CybertronChannelMessage : public ChannelMessage { channel_message_.reset(); } + std::string GetChannelName(void)const{ return channel_reader_->GetChannelName(); } + protected: void updateRawMessage(const std::shared_ptr& rawMsg) { - if(!is_enabled_){ return; } + if (!is_enabled_) { + return; + } ++frame_counter_; std::lock_guard _g(inner_lock_); @@ -184,46 +191,52 @@ class CybertronChannelMessage : public ChannelMessage { mutable std::mutex inner_lock_; }; -#define RegisterChannelMsgClass(ChannelMsgSubClass, MessageType) \ - static ChannelMessage* Instance(const std::string& channelName, \ - const std::string& nodeName) { \ - ChannelMessage* ret = castErrorCode2Ptr(ErrorCode::NewSubClassFailed); \ - ChannelMsgSubClass* subClass = new ChannelMsgSubClass(); \ - if (subClass) { \ - ret = subClass; \ - subClass->channel_node_ = apollo::cybertron::CreateNode(nodeName); \ - if (subClass->channel_node_ == nullptr) { \ - delete subClass; \ - subClass = nullptr; \ - ret = castErrorCode2Ptr(ErrorCode::CreateNodeFailed); \ - } else { \ - auto callBack = \ - [subClass](const std::shared_ptr& rawMsg) { \ - subClass->updateRawMessage(rawMsg); \ - }; \ - subClass->channel_reader_ = \ - subClass->channel_node_->CreateReader(channelName, \ - callBack); \ - if (subClass->channel_reader_ == nullptr) { \ - subClass->channel_node_.reset(); \ - delete subClass; \ - subClass = nullptr; \ - ret = castErrorCode2Ptr(ErrorCode::CreateReaderFailed); \ - } \ - } \ - } \ - return ret; \ +#define RegisterChannelMsgClass(ChannelMsgSubClass, MessageType) \ + static ChannelMessage* Instance(const std::string& channelName, \ + const std::string& nodeName) { \ + ChannelMessage* ret = castErrorCode2Ptr(ErrorCode::NewSubClassFailed); \ + ChannelMsgSubClass* subClass = new ChannelMsgSubClass(); \ + if (subClass) { \ + ret = subClass; \ + subClass->channel_node_ = apollo::cybertron::CreateNode(nodeName); \ + if (subClass->channel_node_ == nullptr) { \ + delete subClass; \ + subClass = nullptr; \ + ret = castErrorCode2Ptr(ErrorCode::CreateNodeFailed); \ + } else { \ + auto callBack = \ + [subClass](const std::shared_ptr& rawMsg) { \ + subClass->updateRawMessage(rawMsg); \ + }; \ + subClass->channel_reader_ = \ + subClass->channel_node_->CreateReader(channelName, \ + callBack); \ + if (subClass->channel_reader_ == nullptr) { \ + subClass->channel_node_.reset(); \ + delete subClass; \ + subClass = nullptr; \ + ret = castErrorCode2Ptr(ErrorCode::CreateReaderFailed); \ + } \ + } \ + } \ + return ret; \ } -#define BegDefineChannelMsgSubClass(SubClassName, MessageType) \ - class SubClassName : public CybertronChannelMessage { \ - public: \ - RegisterChannelMsgClass(SubClassName, MessageType) virtual void Render( \ - const Screen* s, int key) override; \ - virtual ~SubClassName() {} \ - \ - private: \ - explicit SubClassName(RenderableMessage* parent = nullptr) \ +#define BegDefineChannelMsgSubClass(SubClassName, MessageType) \ + class SubClassName : public CybertronChannelMessage { \ + public: \ + RegisterChannelMsgClass(SubClassName, MessageType) virtual void Render( \ + const Screen* s, int key) override + +#define SubClassDeconstructor(SubClassName) \ + public: \ + virtual ~SubClassName() + +#define SubClassConstructor(SubClassName, MessageType) \ + private: \ + SubClassName(const SubClassName&) = delete; \ + SubClassName& operator=(const SubClassName&) = delete; \ + explicit SubClassName(RenderableMessage* parent = nullptr) \ : CybertronChannelMessage(parent) #define EndDefineChannelMsgSubClass(SubClassName) } /* SubClassName */ diff --git a/framework/cybertron/tools/cvt/monitor/cybertron_topology_message.cpp b/framework/cybertron/tools/cvt/monitor/cybertron_topology_message.cpp index df08d0b38161a2b4939cf88a697f8fb102f8deb1..385a036a86ce17da527f1c96b53ab9de1b43b34b 100644 --- a/framework/cybertron/tools/cvt/monitor/cybertron_topology_message.cpp +++ b/framework/cybertron/tools/cvt/monitor/cybertron_topology_message.cpp @@ -96,8 +96,8 @@ void CybertronTopologyMessage::TopologyChanged( if (iter == all_channels_map_.cend()) { ChannelMessage* channelMsg = - ChannelMsgFactory::Instance()->CreateChannelMessage( - msgTypeName, channelName); + ChannelMsgFactory::Instance()->CreateChannelMessage(msgTypeName, + channelName); if (!ChannelMessage::isErrorCode(channelMsg)) { channelMsg->set_parent(this); @@ -172,10 +172,10 @@ void CybertronTopologyMessage::ChangeState(const Screen* s, int key) { if (page_index_ < 1) page_index_ = 0; break; - case ' ': - { - ChannelMessage* child = static_cast(Child(s->highlight_line_no())); - if(child){ + case ' ': { + ChannelMessage* child = + static_cast(Child(s->highlight_line_no())); + if (child) { child->set_enabled(!child->is_enabled()); } } @@ -223,7 +223,8 @@ void CybertronTopologyMessage::Render(const Screen* s, int key) { color = Screen::RED_BLACK; if (!ChannelMessage::isErrorCode(iter->second)) { - if (iter->second->is_enabled() && iter->second->has_message_come()) color = Screen::GREEN_BLACK; + if (iter->second->is_enabled() && iter->second->has_message_come()) + color = Screen::GREEN_BLACK; } s->SetCurrentColor(color); diff --git a/framework/cybertron/tools/cvt/monitor/general_message.cpp b/framework/cybertron/tools/cvt/monitor/general_message.cpp index ea9c29cae55f086e11e5c75badec4989464c9b1d..66c38ac774ed6727f0ac5705263cbfb48b0036e0 100644 --- a/framework/cybertron/tools/cvt/monitor/general_message.cpp +++ b/framework/cybertron/tools/cvt/monitor/general_message.cpp @@ -15,30 +15,163 @@ *****************************************************************************/ #include "general_message.h" +#include "repeated_items_message.h" #include "screen.h" -#include #include #include #include -namespace{ - constexpr int ReaderWriterOffset = 4; - constexpr int PageItemCountOffset = 3; - int lineCount(const std::string& str) - { - int ret = 0; - for(int i = 0; i < str.length(); ++i) - { - if(str.at(i) == '\n') - ++ret; +namespace { +constexpr int ReaderWriterOffset = 4; +constexpr int PageItemCountOffset = 3; +int lineCount(const google::protobuf::Message& msg, int screenWidth, + std::map* childrenMap = nullptr, + GeneralMessage* gMsg = nullptr) { + const google::protobuf::Descriptor* descriptor = msg.GetDescriptor(); + const google::protobuf::Reflection* reflection = msg.GetReflection(); + + std::vector fields; + reflection->ListFields(msg, &fields); + + int fsize = fields.size(); + int ret = 0; + for (int i = 0; i < fsize; ++i, ++ret) { + const google::protobuf::FieldDescriptor* field = fields[i]; + if (childrenMap && field->is_repeated()) { + RepeatedItemsMessage* item = new RepeatedItemsMessage(gMsg, i); + childrenMap->insert(std::make_pair(ret, item)); } - return ret + 1; + if (!field->is_repeated()) { + switch (field->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + std::string scratch; + const std::string& value = + reflection->GetStringReference(msg, field, &scratch); + ret += value.size() / screenWidth; + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + const google::protobuf::Message& childMsg = + reflection->GetMessage(msg, field); + ret += lineCount(childMsg, screenWidth) + 1; + break; + + } // end switch + } + } // end for + + return ret; +} +} // namespace + +void GeneralMessage::PrintMessage(const google::protobuf::Message& msg, const Screen* s, + unsigned& lineNo, int indent, int jumpLines) { + // const google::protobuf::Descriptor* descriptor = msg.GetDescriptor(); + const google::protobuf::Reflection* reflection = msg.GetReflection(); + + std::vector fields; + reflection->ListFields(msg, &fields); + + int i = 0; + for (; i < fields.size() && jumpLines > 1; ++i) { + const google::protobuf::FieldDescriptor* field = fields[i]; + --jumpLines; + + if (!field->is_repeated()) { + switch (field->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + std::string scratch; + const std::string& value = + reflection->GetStringReference(msg, field, &scratch); + jumpLines -= value.size() / s->Width(); + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + jumpLines -= + lineCount(reflection->GetMessage(msg, field), s->Width()); + break; + } // end switch + } + } + + for (; i < fields.size(); ++i) { + GeneralMessage::PrintFieldValue(msg, reflection, s, lineNo, indent, + fields[i]); + } // end for +} + +void GeneralMessage::PrintFieldValue( + const google::protobuf::Message& msg, + const google::protobuf::Reflection* reflection, const Screen* s, + unsigned& lineNo, int indent, + const google::protobuf::FieldDescriptor* field) { + + const std::string& fieldName = field->name(); + std::ostringstream outStr; + + outStr << fieldName << ": "; + if (field->is_repeated()) { + outStr << "+[" << reflection->FieldSize(msg, field) << " items]"; + } else { + switch (field->cpp_type()) { +#define OUTPUT_FIELD(CPPTYPE, METHOD) \ + case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \ + outStr << reflection->Get##METHOD(msg, field); \ + break + + OUTPUT_FIELD(INT32, Int32); + OUTPUT_FIELD(INT64, Int64); + OUTPUT_FIELD(UINT32, UInt32); + OUTPUT_FIELD(UINT64, UInt64); + OUTPUT_FIELD(FLOAT, Float); + OUTPUT_FIELD(DOUBLE, Double); + OUTPUT_FIELD(BOOL, Bool); +#undef OUTPUT_FIELD + + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + int enum_value = reflection->GetEnumValue(msg, field); + outStr << enum_value; + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + std::string scratch; + const std::string& value = + reflection->GetStringReference(msg, field, &scratch); + outStr << value; + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + s->AddStr(indent, lineNo++, outStr.str().c_str()); + PrintMessage(reflection->GetMessage(msg, field), s, lineNo, indent + 2); + outStr.str(""); + break; + } // end switch + } // end else + + s->AddStr(indent, lineNo++, outStr.str().c_str()); +} + +RenderableMessage* GeneralMessage::Child(int lineNo) const { + lineNo -= 3; // 3 is the fixed offset value, 0 for ChannelName, 1 for + // MessageType, 2 for FrameRatio + if (lineNo < 0) { + return nullptr; + } + auto iter = children_map_.find(lineNo); + if (iter == children_map_.cend()) { + return nullptr; } + + return iter->second; } -void GeneralMessage::Render(const Screen *s, int key) { +void GeneralMessage::Render(const Screen* s, int key) { switch (key) { case 'b': case 'B': @@ -53,16 +186,31 @@ void GeneralMessage::Render(const Screen *s, int key) { default:; } - if (current_state_ == State::ShowDebugString) { - RenderDebugString(s, key); - } else { - RenderInfo(s, key); + unsigned lineNo = 0; + + s->SetCurrentColor(Screen::WHITE_BLACK); + s->AddStr(0, lineNo++, "ChannelName: "); + s->AddStr(channel_reader_->GetChannelName().c_str()); + + s->AddStr(0, lineNo++, "MessageType: "); + s->AddStr(message_type().c_str()); + // ++lineNo; + + switch (current_state_) { + case State::ShowDebugString: + RenderDebugString(s, key, lineNo); + break; + case State::ShowInfo: + RenderInfo(s, key, lineNo); + break; + case State::ShowRepeatedItems: + break; } + s->ClearCurrentColor(Screen::WHITE_BLACK); } -void GeneralMessage::SplitPages(int key) -{ - switch(key){ +void GeneralMessage::SplitPages(int key) { + switch (key) { case CTRL('d'): case KEY_NPAGE: ++page_index_; @@ -75,20 +223,22 @@ void GeneralMessage::SplitPages(int key) if (page_index_ < 1) page_index_ = 0; break; default:; - } + } } -void GeneralMessage::RenderInfo(const Screen *s, int key) { +void GeneralMessage::RenderInfo(const Screen* s, int key, unsigned lineNo) { int pageItemCount = s->Height() - PageItemCountOffset; - pages_ = (readers_.size() + writers_.size() + PageItemCountOffset)/pageItemCount + 1; + pages_ = (readers_.size() + writers_.size() + PageItemCountOffset) / + pageItemCount + + 1; SplitPages(key); bool hasReader = true; - std::vector< std::string >* vec = &readers_; + std::vector* vec = &readers_; auto iter = vec->cbegin(); int y = page_index_ * pageItemCount; - if(y < vec->size()){ + if (y < vec->size()) { while (y < page_index_ * pageItemCount) { ++iter; ++y; @@ -97,8 +247,7 @@ void GeneralMessage::RenderInfo(const Screen *s, int key) { y -= vec->size(); vec = &writers_; iter = vec->cbegin(); - while(y) - { + while (y) { ++iter; --y; } @@ -106,91 +255,71 @@ void GeneralMessage::RenderInfo(const Screen *s, int key) { hasReader = false; } - y = 0; - - s->SetCurrentColor(Screen::WHITE_BLACK); - - s->AddStr(0, y++, "ChannelName: "); - s->AddStr(channel_reader_->GetChannelName().c_str()); - - s->AddStr(0, y++, "MessageType: "); - s->AddStr(message_type().c_str()); - - ++y; - - if(hasReader) - { - s->AddStr(0, y++, "Readers:"); + if (hasReader) { + s->AddStr(0, lineNo++, "Readers:"); for (; iter != vec->cend(); ++iter) { - s->AddStr(ReaderWriterOffset, y++, iter->c_str()); + s->AddStr(ReaderWriterOffset, lineNo++, iter->c_str()); } - ++y; + ++lineNo; vec = &writers_; iter = vec->cbegin(); } - s->AddStr(0, y++, "Writers:"); + s->AddStr(0, lineNo++, "Writers:"); for (; iter != vec->cend(); ++iter) { - s->AddStr(ReaderWriterOffset, y++, iter->c_str()); + s->AddStr(ReaderWriterOffset, lineNo++, iter->c_str()); } - - s->ClearCurrentColor(Screen::WHITE_BLACK); } -void GeneralMessage::RenderDebugString(const Screen *s, int key) { - unsigned y = 0; - - s->SetCurrentColor(Screen::WHITE_BLACK); - - s->AddStr(0, y++, "ChannelName: "); - s->AddStr(channel_reader_->GetChannelName().c_str()); - - s->AddStr(0, y++, "MessageType: "); - s->AddStr(message_type().c_str()); - ++y; - +void GeneralMessage::RenderDebugString(const Screen* s, int key, + unsigned lineNo) { if (has_message_come()) { + if (raw_msg_class_ == nullptr) { + auto rawFactory = apollo::cybertron::message::ProtobufFactory::Instance(); + raw_msg_class_ = rawFactory->GenerateMessageByType(message_type()); + } - auto rawFactory = apollo::cybertron::message::ProtobufFactory::Instance(); - auto rawMsg = rawFactory->GenerateMessageByType(message_type()); + for (auto& iter : children_map_) { + delete iter.second; + } - if (rawMsg == nullptr) { - s->AddStr(0, y++, "Cannot Generate Message by Message Type"); + children_map_.clear(); + + if (raw_msg_class_ == nullptr) { + s->AddStr(0, lineNo++, "Cannot Generate Message by Message Type"); } else { std::ostringstream outStr; outStr << std::fixed << std::setprecision(2) << frame_ratio(); - s->AddStr(0, y++, "FrameRatio: "); + s->AddStr(0, lineNo++, "FrameRatio: "); s->AddStr(outStr.str().c_str()); decltype(channel_message_) channelMsg = CopyMsgPtr(); - if (rawMsg->ParseFromString(channelMsg->message)) { - s->AddStr(0, y++, "DebugString:"); - std::string debugStr = rawMsg->DebugString(); - - int pageItemCount = s->Height() - 4; - pages_ = lineCount(debugStr)/pageItemCount + 1; + if (raw_msg_class_->ParseFromString(channelMsg->message)) { + int lcount = + lineCount(*raw_msg_class_, s->Width(), &children_map_, this); + int pageItemCount = s->Height() - lineNo; + pages_ = lcount / pageItemCount + 1; SplitPages(key); - int jumpline = page_index_ * pageItemCount; - const char* ptr = debugStr.c_str(); - while(*ptr != '\0') - { - if(*ptr == '\n') --jumpline; - if(!jumpline) break; - ++ptr; + + PrintMessage(*raw_msg_class_, s, lineNo, 0, + page_index_ * pageItemCount); + + outStr.str(""); + outStr << "Child Count: " << children_map_.size(); + s->AddStr(0, lineNo++, outStr.str().c_str()); + for (auto& iter : children_map_) { + outStr.str(""); + outStr << "lineNo = " << iter.first; + s->AddStr(0, lineNo++, outStr.str().c_str()); } - s->AddStr(0, y++, ptr); } else { - s->AddStr(0, y++, "Cannot parse the raw message"); + s->AddStr(0, lineNo++, "Cannot parse the raw message"); } - - delete rawMsg; } } else { - s->AddStr(0, y++, "No Message Came"); + s->AddStr(0, lineNo++, "No Message Came"); } - - s->ClearCurrentColor(Screen::WHITE_BLACK); } diff --git a/framework/cybertron/tools/cvt/monitor/general_message.h b/framework/cybertron/tools/cvt/monitor/general_message.h index e3387488bd133ab6e309685a55fcec17c44bb901..1cef68ded41bd4848c5f40a642d0b580923d2feb 100644 --- a/framework/cybertron/tools/cvt/monitor/general_message.h +++ b/framework/cybertron/tools/cvt/monitor/general_message.h @@ -17,21 +17,51 @@ #ifndef TOOLS_CVT_MONITOR_GENERAL_MESSAGE_H_ #define TOOLS_CVT_MONITOR_GENERAL_MESSAGE_H_ -#include "cybertron_channel_message.h" #include +#include "cybertron_channel_message.h" + +class RepeatedItemsMessage; BegDefineChannelMsgSubClass(GeneralMessage, - apollo::cybertron::message::RawMessage), - current_state_(State::ShowDebugString), page_index_(0) {} + apollo::cybertron::message::RawMessage); +SubClassDeconstructor(GeneralMessage) { + if (raw_msg_class_) { + delete raw_msg_class_; + raw_msg_class_ = nullptr; + } + + for(auto& iter : children_map_){ + delete iter.second; + } +} + +RenderableMessage* Child(int lineNo) const override; -void RenderDebugString(const Screen* s, int key); -void RenderInfo(const Screen* s, int key); +SubClassConstructor(GeneralMessage, apollo::cybertron::message::RawMessage), + current_state_(State::ShowDebugString), page_index_(0), + raw_msg_class_(nullptr), children_map_() {} + +void RenderDebugString(const Screen* s, int key, unsigned lineNo); +void RenderInfo(const Screen* s, int key, unsigned lineNo); void SplitPages(int key); -enum class State { ShowDebugString, ShowInfo } current_state_; +static void PrintFieldValue(const google::protobuf::Message& msg, + const google::protobuf::Reflection* reflection, + const Screen* s, unsigned& lineNo, int indent, + const google::protobuf::FieldDescriptor* field); + +static void PrintMessage(const google::protobuf::Message& msg, const Screen* s, + unsigned& lineNo, int indent, int jumpLines = 0); + +enum class State { ShowDebugString, ShowInfo, ShowRepeatedItems } current_state_; int pages_; int page_index_; +google::protobuf::Message* raw_msg_class_; + +std::map children_map_; + +friend class RepeatedItemsMessage; EndDefineChannelMsgSubClass(GeneralMessage); diff --git a/framework/cybertron/tools/cvt/monitor/repeated_items_message.cpp b/framework/cybertron/tools/cvt/monitor/repeated_items_message.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae6d555a84e37bae876ef66d2a454551ba60745a --- /dev/null +++ b/framework/cybertron/tools/cvt/monitor/repeated_items_message.cpp @@ -0,0 +1,129 @@ +/****************************************************************************** + * Copyright 2018 The Apollo Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +#include "repeated_items_message.h" +#include "general_message.h" +#include "screen.h" + +#include + +void RepeatedItemsMessage::PrintFieldValue( + const Screen* s, unsigned& lineNo, int indent, + const google::protobuf::Message& message, + const google::protobuf::Reflection* reflection, + const google::protobuf::FieldDescriptor* field, int index) { + std::ostringstream outStr; + const std::string& fieldName = field->name(); + outStr << fieldName << ": "; + + switch (field->cpp_type()) { +#define OUTPUT_FIELD(CPPTYPE, METHOD) \ + case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \ + outStr << reflection->GetRepeated##METHOD(message, field, index); \ + break + + OUTPUT_FIELD(INT32, Int32); + OUTPUT_FIELD(INT64, Int64); + OUTPUT_FIELD(UINT32, UInt32); + OUTPUT_FIELD(UINT64, UInt64); + OUTPUT_FIELD(FLOAT, Float); + OUTPUT_FIELD(DOUBLE, Double); + OUTPUT_FIELD(BOOL, Bool); +#undef OUTPUT_FIELD + + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + std::string scratch; + const std::string& value = reflection->GetRepeatedStringReference( + message, field, index, &scratch); + outStr << value; + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + int enum_value = reflection->GetRepeatedEnumValue(message, field, index); + outStr << enum_value; + break; + } + + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + outStr << "[" << index << "]"; + s->AddStr(indent, lineNo++, outStr.str().c_str()); + GeneralMessage::PrintMessage( + reflection->GetRepeatedMessage(message, field, index), s, lineNo, indent + 2); + outStr.str(""); + break; + } + + s->AddStr(indent, lineNo++, outStr.str().c_str()); +} + +RepeatedItemsMessage::RepeatedItemsMessage(GeneralMessage* parent, + int fieldIndex) + : RenderableMessage(parent), + fieldIndex_(fieldIndex), + itemIndex_(0), + channel_message_(parent->channel_message_) {} + +void RepeatedItemsMessage::Render(const Screen* s, int key) { + unsigned lineNo = 0; + + GeneralMessage* parentPtr = static_cast(parent()); + s->SetCurrentColor(Screen::WHITE_BLACK); + s->AddStr(0, lineNo++, "ChannelName: "); + s->AddStr(parentPtr->GetChannelName().c_str()); + + s->AddStr(0, lineNo++, "MessageType: "); + s->AddStr(parentPtr->message_type().c_str()); + + std::ostringstream outStr; + outStr << std::fixed << std::setprecision(2) << parentPtr->frame_ratio(); + s->AddStr(0, lineNo++, "FrameRatio: "); + s->AddStr(outStr.str().c_str()); + + if (parentPtr->raw_msg_class_->ParseFromString(channel_message_->message)) { + const google::protobuf::Descriptor* descriptor = + parentPtr->raw_msg_class_->GetDescriptor(); + const google::protobuf::Reflection* reflection = + parentPtr->raw_msg_class_->GetReflection(); + + std::vector fields; + reflection->ListFields(*(parentPtr->raw_msg_class_), &fields); + + const google::protobuf::FieldDescriptor* field = fields[fieldIndex_]; + + int size = reflection->FieldSize(*(parentPtr->raw_msg_class_), field); + + switch (key) { + case 'n': + case 'N': + ++itemIndex_; + if (itemIndex_ >= size) itemIndex_ = 0; + break; + + case 'm': + case 'M': + --itemIndex_; + if (itemIndex_ < 0) itemIndex_ = size - 1; + break; + + default:; + } + + RepeatedItemsMessage::PrintFieldValue(s, lineNo, 0, + *(parentPtr->raw_msg_class_), + reflection, field, itemIndex_); + } +} diff --git a/framework/cybertron/tools/cvt/monitor/repeated_items_message.h b/framework/cybertron/tools/cvt/monitor/repeated_items_message.h new file mode 100644 index 0000000000000000000000000000000000000000..9079790266182857e94a1c3a20d94234e1261a19 --- /dev/null +++ b/framework/cybertron/tools/cvt/monitor/repeated_items_message.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Copyright 2018 The Apollo Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +#ifndef TOOLS_CVT_MONITOR_REPEATED_ITEMS_MESSAGE_H_ +#define TOOLS_CVT_MONITOR_REPEATED_ITEMS_MESSAGE_H_ + +#include +#include +#include "renderable_message.h" + +class GeneralMessage; +class Screen; + +class RepeatedItemsMessage : public RenderableMessage { + public: + explicit RepeatedItemsMessage(GeneralMessage* parent, int fieldIndex); + ~RepeatedItemsMessage() {} + + void Render(const Screen* s, int key) override; + + private: + RepeatedItemsMessage(const RepeatedItemsMessage&) = delete; + RepeatedItemsMessage& operator=(const RepeatedItemsMessage&) = delete; + + static void PrintFieldValue(const Screen* s, unsigned& lineNo, int indent, + const google::protobuf::Message& message, + const google::protobuf::Reflection* reflection, + const google::protobuf::FieldDescriptor* field, int index); + + int fieldIndex_; + int itemIndex_; + std::shared_ptr channel_message_; +}; + +#endif // TOOLS_CVT_MONITOR_REPEATED_ITEMS_MESSAGE_H_ \ No newline at end of file diff --git a/framework/cybertron/tools/cvt/monitor/screen.cpp b/framework/cybertron/tools/cvt/monitor/screen.cpp index 14777c935df8d3b9a4257297a656b12e19514f50..e7329ff9c0f87c8e12dc9fe532b911f5183a733f 100644 --- a/framework/cybertron/tools/cvt/monitor/screen.cpp +++ b/framework/cybertron/tools/cvt/monitor/screen.cpp @@ -34,26 +34,35 @@ const char Screen::InteractiveCmdStr[] = "Common Commands:\n" " q | Q | Esc -- quit\n" " Backspace -- go back\n" - " h | H -- go to show help info\n\n" - - "Commands for top-level topology message:\n" + " h | H -- go to show help info\n" + "\n" + " PgDn | ^d -- show next page\n" + " PgUp | ^u -- show previous page\n" + "\n" " Up Arrow -- move up one line\n" " Down Arrow -- move down one line\n" - " Right Arrow -- show the selected channel Data\n" - " Left Arrow -- go back to the upper level\n\n" + " Right Arrow -- enter the selected Channel or Repeated Data Item\n" + " Left Arrow -- go back to the upper level\n" + "\n" " Enter -- the same with Right Arrow key\n" " a | A -- the same with Left Arrow key\n" " d | D -- the same with Right Arrow key\n" " w | W -- the same with Up Arrow key\n" - " s | S -- the same with Down Arrow key\n\n" + " s | S -- the same with Down Arrow key\n" + "\n" + "Commands for top-level topology message:\n" " f | F -- show frame ratio for all channel messages\n" " t | T -- show channel message type\n" - " PgDn | ^d -- show next page\n" - " PgUp | ^u -- show previous page\n\n" - " Space -- Enable|Disable channel Message\n\n" + "\n" + " Space -- Enable|Disable channel Message\n" + "\n" "Commands for Channel:\n" " i | I -- show Reader and Writers of Channel\n" - " b | B -- show Debug String of Channel Message\n"; + " b | B -- show Debug String of Channel Message\n" + "\n" + "Commands for " + " n | N -- next repeated data item\n" + " m | M -- previous repeated data item\n"; Screen::Screen() : current_state_(State::RenderMessage), @@ -192,7 +201,8 @@ void Screen::Run() { SwitchState(ch); - (this->*showFuncs[static_cast(current_state_)])(highlight_line_no_, ch); + (this->*showFuncs[static_cast(current_state_)])(highlight_line_no_, + ch); } while (true); } diff --git a/framework/cybertron/tools/cvt/monitor/screen.h b/framework/cybertron/tools/cvt/monitor/screen.h index cecc934ebd7254f33a1a3bd16994808299eac319..e990ca913592844f9cdd8bf4743a72a4186b8133 100644 --- a/framework/cybertron/tools/cvt/monitor/screen.h +++ b/framework/cybertron/tools/cvt/monitor/screen.h @@ -63,7 +63,7 @@ class Screen final { } } - int highlight_line_no(void)const{ return highlight_line_no_; } + int highlight_line_no(void) const { return highlight_line_no_; } private: explicit Screen();