本文整理汇总了C++中DatagramIterator::read_doid方法的典型用法代码示例。如果您正苦于以下问题:C++ DatagramIterator::read_doid方法的具体用法?C++ DatagramIterator::read_doid怎么用?C++ DatagramIterator::read_doid使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DatagramIterator
的用法示例。
在下文中一共展示了DatagramIterator::read_doid方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: handle_object_entrance
void Client::handle_object_entrance(DatagramIterator &dgi, bool other)
{
doid_t do_id = dgi.read_doid();
doid_t parent = dgi.read_doid();
zone_t zone = dgi.read_zone();
uint16_t dc_id = dgi.read_uint16();
// this object is no longer pending
m_pending_objects.erase(do_id);
if(m_owned_objects.find(do_id) != m_owned_objects.end() ||
m_seen_objects.find(do_id) != m_seen_objects.end()) {
return;
}
if(m_visible_objects.find(do_id) == m_visible_objects.end()) {
VisibleObject obj;
obj.id = do_id;
obj.dcc = g_dcf->get_class_by_id(dc_id);
obj.parent = parent;
obj.zone = zone;
m_visible_objects[do_id] = obj;
}
m_seen_objects.insert(do_id);
handle_add_object(do_id, parent, zone, dc_id, dgi, other);
}
示例2: handle_generate
void StateServer::handle_generate(DatagramIterator &dgi, bool has_other)
{
doid_t do_id = dgi.read_doid();
doid_t parent_id = dgi.read_doid();
zone_t zone_id = dgi.read_zone();
uint16_t dc_id = dgi.read_uint16();
// Make sure the object id is unique
if(m_objs.find(do_id) != m_objs.end()) {
m_log->warning() << "Received generate for already-existing object ID=" << do_id << std::endl;
return;
}
// Make sure the class exists in the file
const Class *dc_class = g_dcf->get_class_by_id(dc_id);
if(!dc_class) {
m_log->error() << "Received create for unknown dclass with class id '" << dc_id << "'\n";
return;
}
// Create the object
DistributedObject *obj;
try {
obj = new DistributedObject(this, do_id, parent_id, zone_id, dc_class, dgi, has_other);
} catch(const DatagramIteratorEOF&) {
m_log->error() << "Received truncated generate for "
<< dc_class->get_name() << "(" << do_id << ")" << std::endl;
return;
}
m_objs[do_id] = obj;
}
示例3: initialize
bool DBOperationSet::initialize(channel_t sender, uint16_t msg_type, DatagramIterator &dgi)
{
m_sender = sender;
m_type = SET_FIELDS;
m_doid = dgi.read_doid();
uint16_t field_count;
if(msg_type == DBSERVER_OBJECT_SET_FIELDS ||
msg_type == DBSERVER_OBJECT_DELETE_FIELDS) {
field_count = dgi.read_uint16();
} else {
field_count = 1;
}
bool delete_values = false;
if(msg_type == DBSERVER_OBJECT_DELETE_FIELD ||
msg_type == DBSERVER_OBJECT_DELETE_FIELDS) {
delete_values = true;
}
if(!populate_set_fields(dgi, field_count, delete_values, false)) {
on_failure();
return false;
}
return true;
}
示例4: handle_get_all
void DBStateServer::handle_get_all(channel_t sender, DatagramIterator &dgi)
{
uint32_t r_context = dgi.read_uint32();
doid_t r_do_id = dgi.read_doid();
if(is_activated_object(r_do_id)) {
return;
}
m_log->trace() << "Received GetAll for inactive object with id " << r_do_id << std::endl;
// Get context for db query, and remember caller with it
uint32_t db_context = m_next_context++;
DatagramPtr resp_dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_ALL_RESP);
resp_dg->add_uint32(r_context);
resp_dg->add_doid(r_do_id);
resp_dg->add_channel(INVALID_CHANNEL); // Location
m_context_datagrams[db_context] = resp_dg;
// Cache the do_id --> context in case we get a dbss_activate
m_inactive_loads[r_do_id].insert(db_context);
// Send query to database
DatagramPtr dg = Datagram::create(m_db_channel, r_do_id, DBSERVER_OBJECT_GET_ALL);
dg->add_uint32(db_context);
dg->add_doid(r_do_id);
route_datagram(dg);
}
示例5: handle_get_activated
void DBStateServer::handle_get_activated(channel_t sender, DatagramIterator& dgi)
{
uint32_t r_context = dgi.read_uint32();
doid_t r_do_id = dgi.read_doid();
if(m_loading.find(r_do_id) != m_loading.end()) {
return;
}
m_log->trace() << "Received GetActivated for id " << r_do_id << "\n";
if(m_objs.find(r_do_id) != m_objs.end()) {
// If object is active return true
DatagramPtr dg = Datagram::create(sender, r_do_id, DBSS_OBJECT_GET_ACTIVATED_RESP);
dg->add_uint32(r_context);
dg->add_doid(r_do_id);
dg->add_bool(true);
route_datagram(dg);
} else {
// If object isn't active or loading, we can return false
DatagramPtr dg = Datagram::create(sender, r_do_id, DBSS_OBJECT_GET_ACTIVATED_RESP);
dg->add_uint32(r_context);
dg->add_doid(r_do_id);
dg->add_bool(false);
route_datagram(dg);
}
}
示例6: handle_activate
void DBStateServer::handle_activate(DatagramIterator &dgi, bool has_other)
{
doid_t do_id = dgi.read_doid();
doid_t parent_id = dgi.read_doid();
zone_t zone_id = dgi.read_zone();
// Check object is not already active
if(m_objs.find(do_id) != m_objs.end() || m_loading.find(do_id) != m_loading.end()) {
m_log->warning() << "Received activate for already-active object with id " << do_id << "\n";
return;
}
if(!has_other) {
auto load_it = m_inactive_loads.find(do_id);
if(load_it == m_inactive_loads.end()) {
m_loading[do_id] = new LoadingObject(this, do_id, parent_id, zone_id);
m_loading[do_id]->begin();
} else {
m_loading[do_id] = new LoadingObject(this, do_id, parent_id, zone_id, load_it->second);
}
} else {
uint16_t dc_id = dgi.read_uint16();
// Check id is a valid type id
if(dc_id >= g_dcf->get_num_types()) {
m_log->error() << "Received activate_other with unknown dclass"
" with id " << dc_id << "\n";
return;
}
const Class *dcc = g_dcf->get_class_by_id(dc_id);
if(!dcc) {
m_log->error() << "Tried to activate_other with non-class distributed_type '"
<< g_dcf->get_class_by_id(dc_id)->get_name() << "'\n";
}
auto load_it = m_inactive_loads.find(do_id);
if(load_it == m_inactive_loads.end()) {
m_loading[do_id] = new LoadingObject(this, do_id, parent_id, zone_id, dcc, dgi);
m_loading[do_id]->begin();
} else {
m_loading[do_id] = new LoadingObject(this, do_id, parent_id, zone_id, dcc, dgi, load_it->second);
}
}
}
示例7: handle_get_field
void DBStateServer::handle_get_field(channel_t sender, DatagramIterator &dgi)
{
uint32_t r_context = dgi.read_uint32();
doid_t r_do_id = dgi.read_doid();
uint16_t field_id = dgi.read_uint16();
if(is_activated_object(r_do_id)) {
return;
}
m_log->trace() << "Received GetField for field with id " << field_id
<< " on inactive object with id " << r_do_id << "\n";
// Check field is "ram db" or "required"
const Field* field = g_dcf->get_field_by_id(field_id);
if(!field || !(field->has_keyword("required") || field->has_keyword("ram"))) {
DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELD_RESP);
dg->add_uint32(r_context);
dg->add_bool(false);
route_datagram(dg);
return;
}
if(field->has_keyword("db")) {
// Get context for db query
uint32_t db_context = m_next_context++;
// Prepare reponse datagram
DatagramPtr dg_resp = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELD_RESP);
dg_resp->add_uint32(r_context);
m_context_datagrams[db_context] = dg_resp;
// Send query to database
DatagramPtr dg = Datagram::create(m_db_channel, r_do_id, DBSERVER_OBJECT_GET_FIELD);
dg->add_uint32(db_context);
dg->add_doid(r_do_id);
dg->add_uint16(field_id);
route_datagram(dg);
} else if(field->has_default_value()) { // Field is required and not-db
DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELD_RESP);
dg->add_uint32(r_context);
dg->add_bool(true);
dg->add_uint16(field_id);
dg->add_data(field->get_default_value());
route_datagram(dg);
} else {
DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELD_RESP);
dg->add_uint32(r_context);
dg->add_bool(false);
route_datagram(dg);
}
}
示例8: handle_delete_disk
void DBStateServer::handle_delete_disk(channel_t sender, DatagramIterator& dgi)
{
doid_t do_id = dgi.read_doid();
if(m_loading.find(do_id) != m_loading.end()) {
// Ignore this message for now, it'll be bounced back to us
// from the loading object if it succeeds or fails at loading.
return;
}
// If object exists broadcast the delete message
auto obj_keyval = m_objs.find(do_id);
if(obj_keyval != m_objs.end()) {
DistributedObject* obj = obj_keyval->second;
std::unordered_set<channel_t> targets;
// Add location to broadcast
if(obj->get_location()) {
targets.insert(obj->get_location());
}
// Add AI to broadcast
if(obj->get_ai()) {
targets.insert(obj->get_ai());
}
// Add owner to broadcast
if(obj->get_owner()) {
targets.insert(obj->get_owner());
}
// Build and send datagram
DatagramPtr dg = Datagram::create(targets, sender, DBSS_OBJECT_DELETE_DISK);
dg->add_doid(do_id);
route_datagram(dg);
}
// Send delete to database
DatagramPtr dg = Datagram::create(m_db_channel, do_id, DBSERVER_OBJECT_DELETE);
dg->add_doid(do_id);
route_datagram(dg);
}
示例9: build_interest
// build_interest will build an interest from a datagram. It is expected that the datagram
// iterator is positioned such that next item to be read is the interest_id.
void Client::build_interest(DatagramIterator &dgi, bool multiple, Interest &out)
{
uint16_t interest_id = dgi.read_uint16();
doid_t parent = dgi.read_doid();
out.id = interest_id;
out.parent = parent;
uint16_t count = 1;
if(multiple) {
count = dgi.read_uint16();
}
// TODO: We shouldn't have to do this ourselves, figure out where else we're doing
// something wrong.
out.zones.rehash((unsigned int)(ceil(count / out.zones.max_load_factor())));
for(uint16_t x{}; x < count; ++x) {
zone_t zone = dgi.read_zone();
out.zones.insert(out.zones.end(), zone);
}
}
示例10: handle_set_fields
void DBStateServer::handle_set_fields(DatagramIterator &dgi)
{
doid_t do_id = dgi.read_doid();
if(m_loading.find(do_id) != m_loading.end()) {
// Ignore this message for now, it'll be bounced back to us
// from the loading object if it succeeds or fails at loading.
return;
}
uint16_t field_count = dgi.read_uint16();
FieldValues db_fields;
for(uint16_t i = 0; i < field_count; ++i) {
uint16_t field_id = dgi.read_uint16();
const Field* field = g_dcf->get_field_by_id(field_id);
if(!field) {
m_log->warning() << "Received invalid field with id " << field_id << " in SetFields.\n";
return;
}
if(field->has_keyword("db")) {
dgi.unpack_field(field, db_fields[field]);
} else {
dgi.skip_field(field);
}
}
if(db_fields.size() > 0) {
m_log->trace() << "Forwarding SetFields on object with id " << do_id << " to database.\n";
DatagramPtr dg = Datagram::create(m_db_channel, do_id, DBSERVER_OBJECT_SET_FIELDS);
dg->add_doid(do_id);
dg->add_uint16(db_fields.size());
for(const auto& it : db_fields) {
dg->add_uint16(it.first->get_id());
dg->add_data(it.second);
}
route_datagram(dg);
}
}
示例11: handle_set_field
void DBStateServer::handle_set_field(DatagramIterator &dgi)
{
doid_t do_id = dgi.read_doid();
if(m_loading.find(do_id) != m_loading.end()) {
// Ignore this message for now, it'll be bounced back to us
// from the loading object if it succeeds or fails at loading.
return;
}
uint16_t field_id = dgi.read_uint16();
const Field* field = g_dcf->get_field_by_id(field_id);
if(field && field->has_keyword("db")) {
m_log->trace() << "Forwarding SetField for field \"" << field->get_name()
<< "\" on object with id " << do_id << " to database.\n";
DatagramPtr dg = Datagram::create(m_db_channel, do_id, DBSERVER_OBJECT_SET_FIELD);
dg->add_doid(do_id);
dg->add_uint16(field_id);
dg->add_data(dgi.read_remainder());
route_datagram(dg);
}
}
示例12: handle_datagram
// handle_datagram is the handler for datagrams received from the Astron cluster
void Client::handle_datagram(DatagramHandle in_dg, DatagramIterator &dgi)
{
lock_guard<recursive_mutex> lock(m_client_lock);
if(is_terminated()) {
return;
}
channel_t sender = dgi.read_channel();
if(sender == m_channel) {
return; // ignore messages from ourselves
}
uint16_t msgtype = dgi.read_uint16();
switch(msgtype) {
case CLIENTAGENT_EJECT: {
uint16_t reason = dgi.read_uint16();
string error_string = dgi.read_string();
send_disconnect(reason, error_string);
return;
}
break;
case CLIENTAGENT_DROP: {
handle_drop();
return;
}
break;
case CLIENTAGENT_SET_STATE: {
m_state = (ClientState)dgi.read_uint16();
}
break;
case CLIENTAGENT_ADD_INTEREST: {
uint32_t context = m_next_context++;
Interest i;
build_interest(dgi, false, i);
handle_add_interest(i, context);
add_interest(i, context, sender);
}
break;
case CLIENTAGENT_ADD_INTEREST_MULTIPLE: {
uint32_t context = m_next_context++;
Interest i;
build_interest(dgi, true, i);
handle_add_interest(i, context);
add_interest(i, context, sender);
}
break;
case CLIENTAGENT_REMOVE_INTEREST: {
uint32_t context = m_next_context++;
uint16_t id = dgi.read_uint16();
Interest &i = m_interests[id];
handle_remove_interest(id, context);
remove_interest(i, context, sender);
}
break;
case CLIENTAGENT_SET_CLIENT_ID: {
if(m_channel != m_allocated_channel) {
unsubscribe_channel(m_channel);
}
m_channel = dgi.read_channel();
subscribe_channel(m_channel);
}
break;
case CLIENTAGENT_SEND_DATAGRAM: {
DatagramPtr forward = Datagram::create();
forward->add_data(dgi.read_string());
forward_datagram(forward);
}
break;
case CLIENTAGENT_OPEN_CHANNEL: {
subscribe_channel(dgi.read_channel());
}
break;
case CLIENTAGENT_CLOSE_CHANNEL: {
unsubscribe_channel(dgi.read_channel());
}
break;
case CLIENTAGENT_ADD_POST_REMOVE: {
add_post_remove(m_allocated_channel, dgi.read_datagram());
}
break;
case CLIENTAGENT_CLEAR_POST_REMOVES: {
clear_post_removes(m_allocated_channel);
}
break;
case CLIENTAGENT_DECLARE_OBJECT: {
doid_t do_id = dgi.read_doid();
uint16_t dc_id = dgi.read_uint16();
if(m_declared_objects.find(do_id) != m_declared_objects.end()) {
m_log->warning() << "Received object declaration for previously declared object "
<< do_id << ".\n";
return;
}
DeclaredObject obj;
//.........这里部分代码省略.........
示例13: handle_get_fields
void DBStateServer::handle_get_fields(channel_t sender, DatagramIterator &dgi)
{
uint32_t r_context = dgi.read_uint32();
doid_t r_do_id = dgi.read_doid();
uint16_t field_count = dgi.read_uint16();
if(is_activated_object(r_do_id)) {
return;
}
m_log->trace() << "Received GetFields for inactive object with id " << r_do_id << std::endl;
// Read requested fields from datagram
std::vector<const Field*> db_fields; // Ram|required db fields in request
std::vector<const Field*> ram_fields; // Ram|required but not-db fields in request
for(uint16_t i = 0; i < field_count; ++i) {
uint16_t field_id = dgi.read_uint16();
const Field* field = g_dcf->get_field_by_id(field_id);
if(!field) {
DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELDS_RESP);
dg->add_uint32(r_context);
dg->add_uint8(false);
route_datagram(dg);
} else if(field->has_keyword("ram") || field->has_keyword("required")) {
if(field->has_keyword("db")) {
db_fields.push_back(field);
} else {
ram_fields.push_back(field);
}
}
}
if(db_fields.size()) {
// Get context for db query
uint32_t db_context = m_next_context++;
// Prepare reponse datagram
if(m_context_datagrams.find(db_context) == m_context_datagrams.end()) {
m_context_datagrams[db_context] = Datagram::create(sender, r_do_id,
STATESERVER_OBJECT_GET_FIELDS_RESP);
}
m_context_datagrams[db_context]->add_uint32(r_context);
m_context_datagrams[db_context]->add_bool(true);
m_context_datagrams[db_context]->add_uint16(ram_fields.size() + db_fields.size());
for(const auto& it : ram_fields) {
m_context_datagrams[db_context]->add_uint16(it->get_id());
m_context_datagrams[db_context]->add_data(it->get_default_value());
}
// Send query to database
DatagramPtr dg = Datagram::create(m_db_channel, r_do_id, DBSERVER_OBJECT_GET_FIELDS);
dg->add_uint32(db_context);
dg->add_doid(r_do_id);
dg->add_uint16(db_fields.size());
for(const auto& it : db_fields) {
dg->add_uint16(it->get_id());
}
route_datagram(dg);
} else { // If no database fields exist
DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELDS_RESP);
dg->add_uint32(r_context);
dg->add_bool(true);
dg->add_uint16(ram_fields.size());
for(const auto& it : ram_fields) {
dg->add_uint16(it->get_id());
dg->add_data(it->get_default_value());
}
route_datagram(dg);
}
}
示例14: handle_datagram
// handle_datagram is the handler for datagrams received from the Astron cluster
void Client::handle_datagram(DatagramHandle, DatagramIterator &dgi)
{
std::lock_guard<std::recursive_mutex> lock(m_client_lock);
channel_t sender = dgi.read_channel();
uint16_t msgtype = dgi.read_uint16();
switch(msgtype) {
case CLIENTAGENT_EJECT: {
uint16_t reason = dgi.read_uint16();
std::string error_string = dgi.read_string();
send_disconnect(reason, error_string);
return;
}
break;
case CLIENTAGENT_DROP: {
handle_drop();
return;
}
break;
case CLIENTAGENT_SET_STATE: {
m_state = (ClientState)dgi.read_uint16();
}
break;
case CLIENTAGENT_ADD_INTEREST: {
uint32_t context = m_next_context++;
Interest i;
build_interest(dgi, false, i);
handle_add_interest(i, context);
add_interest(i, context, sender);
}
break;
case CLIENTAGENT_ADD_INTEREST_MULTIPLE: {
uint32_t context = m_next_context++;
Interest i;
build_interest(dgi, true, i);
handle_add_interest(i, context);
add_interest(i, context, sender);
}
break;
case CLIENTAGENT_REMOVE_INTEREST: {
uint32_t context = m_next_context++;
uint16_t id = dgi.read_uint16();
Interest &i = m_interests[id];
handle_remove_interest(id, context);
remove_interest(i, context, sender);
}
break;
case CLIENTAGENT_SET_CLIENT_ID: {
if(m_channel != m_allocated_channel) {
unsubscribe_channel(m_channel);
}
m_channel = dgi.read_channel();
subscribe_channel(m_channel);
}
break;
case CLIENTAGENT_SEND_DATAGRAM: {
DatagramPtr forward = Datagram::create();
forward->add_data(dgi.read_string());
forward_datagram(forward);
}
break;
case CLIENTAGENT_OPEN_CHANNEL: {
subscribe_channel(dgi.read_channel());
}
break;
case CLIENTAGENT_CLOSE_CHANNEL: {
unsubscribe_channel(dgi.read_channel());
}
break;
case CLIENTAGENT_ADD_POST_REMOVE: {
add_post_remove(dgi.read_datagram());
}
break;
case CLIENTAGENT_CLEAR_POST_REMOVES: {
clear_post_removes();
}
break;
case CLIENTAGENT_DECLARE_OBJECT: {
doid_t do_id = dgi.read_doid();
uint16_t dc_id = dgi.read_uint16();
if(m_declared_objects.find(do_id) != m_declared_objects.end()) {
m_log->warning() << "Received object declaration for previously declared object "
<< do_id << ".\n";
return;
}
DeclaredObject obj;
obj.id = do_id;
obj.dcc = g_dcf->get_class_by_id(dc_id);
m_declared_objects[do_id] = obj;
}
break;
case CLIENTAGENT_UNDECLARE_OBJECT: {
doid_t do_id = dgi.read_doid();
//.........这里部分代码省略.........
示例15: handle_datagram
void DistributedObject::handle_datagram(DatagramHandle, DatagramIterator &dgi)
{
channel_t sender = dgi.read_channel();
uint16_t msgtype = dgi.read_uint16();
switch(msgtype) {
case STATESERVER_DELETE_AI_OBJECTS: {
if(m_ai_channel != dgi.read_channel()) {
m_log->warning() << " received reset for wrong AI channel.\n";
break; // Not my AI!
}
annihilate(sender);
break;
}
case STATESERVER_OBJECT_DELETE_RAM: {
if(m_do_id != dgi.read_doid()) {
break; // Not meant for me!
}
// Delete object
annihilate(sender);
break;
}
case STATESERVER_OBJECT_DELETE_CHILDREN: {
doid_t r_do_id = dgi.read_doid();
if(r_do_id == m_do_id) {
delete_children(sender);
} else if(r_do_id == m_parent_id) {
annihilate(sender, false);
}
break;
}
case STATESERVER_OBJECT_SET_FIELD: {
if(m_do_id != dgi.read_doid()) {
break; // Not meant for me!
}
handle_one_update(dgi, sender);
break;
}
case STATESERVER_OBJECT_SET_FIELDS: {
if(m_do_id != dgi.read_doid()) {
break; // Not meant for me!
}
uint16_t field_count = dgi.read_uint16();
for(int16_t i = 0; i < field_count; ++i) {
if(!handle_one_update(dgi, sender)) {
break;
}
}
break;
}
case STATESERVER_OBJECT_CHANGING_AI: {
doid_t r_parent_id = dgi.read_doid();
channel_t new_channel = dgi.read_channel();
m_log->trace() << "Received ChangingAI notification from " << r_parent_id << ".\n";
if(r_parent_id != m_parent_id) {
m_log->warning() << "Received AI channel from " << r_parent_id
<< " but my parent_id is " << m_parent_id << ".\n";
break;
}
if(m_ai_explicitly_set) {
break;
}
handle_ai_change(new_channel, sender, false);
break;
}
case STATESERVER_OBJECT_SET_AI: {
channel_t new_channel = dgi.read_channel();
m_log->trace() << "Updating AI to " << new_channel << ".\n";
handle_ai_change(new_channel, sender, true);
break;
}
case STATESERVER_OBJECT_GET_AI: {
m_log->trace() << "Received AI query from " << sender << ".\n";
DatagramPtr dg = Datagram::create(sender, m_do_id, STATESERVER_OBJECT_GET_AI_RESP);
dg->add_uint32(dgi.read_uint32()); // Get context
dg->add_doid(m_do_id);
dg->add_channel(m_ai_channel);
route_datagram(dg);
break;
}
case STATESERVER_OBJECT_GET_AI_RESP: {
dgi.read_uint32(); // Discard context
doid_t r_parent_id = dgi.read_doid();
m_log->trace() << "Received AI query response from " << r_parent_id << ".\n";
if(r_parent_id != m_parent_id) {
m_log->warning() << "Received AI channel from " << r_parent_id
<< " but my parent_id is " << m_parent_id << ".\n";
break;
}
channel_t new_ai = dgi.read_channel();
if(m_ai_explicitly_set) {
break;
}
//.........这里部分代码省略.........