void QuiddityManager::clear_command_sync() { command_lock(); command_->set_id(QuiddityCommand::quit); invoke_in_thread(); g_async_queue_unref(command_queue_); command_unlock(); }
std::vector<std::string> QuiddityManager::list_signal_subscribers() { command_lock(); command_->set_id(QuiddityCommand::list_signal_subscribers); std::vector<std::string> res = manager_impl_->list_signal_subscribers(); command_->result_ = res; command_unlock(); return res; }
std::string QuiddityManager::get_signals_description_by_class(const std::string& class_name) { command_lock(); command_->set_id(QuiddityCommand::get_signals_description_by_class); command_->add_arg(class_name); std::string res = manager_impl_->get_signals_description_by_class(class_name); command_->result_.push_back(res); command_unlock(); return res; }
std::vector<std::string> QuiddityManager::get_classes() { std::vector<std::string> res; command_lock(); command_->set_id(QuiddityCommand::get_classes); invoke_in_thread(); res = command_->result_; command_unlock(); return res; }
std::string QuiddityManager::list_subscribed_signals_json(const std::string& subscriber_name) { command_lock(); command_->set_id(QuiddityCommand::list_subscribed_signals_json); command_->add_arg(subscriber_name); std::string res = manager_impl_->list_subscribed_signals_json(subscriber_name); command_->result_.push_back(res); command_unlock(); return res; }
std::vector<std::pair<std::string, std::string>> QuiddityManager::list_subscribed_signals( const std::string& subscriber_name) { command_lock(); command_->set_id(QuiddityCommand::list_subscribed_signals); std::vector<std::pair<std::string, std::string>> res = manager_impl_->list_subscribed_signals(subscriber_name); // FIXME no result... command_unlock(); return res; }
static struct command_t *command_find(struct command_head_t *cmd_head, char *cmd_name, int sys_cmd) { struct command_t *cmd; command_lock(cmd_head->lock); if (sys_cmd) cmd = __command_find(cmd_head->sys, cmd_name); else cmd = __command_find(cmd_head->user, cmd_name); command_unlock(cmd_head->lock); return cmd; }
std::string QuiddityManager::get_signal_description(const std::string& quiddity_name, const std::string& signal_name) { command_lock(); command_->set_id(QuiddityCommand::get_signal_description); command_->add_arg(quiddity_name); command_->add_arg(signal_name); std::string res = manager_impl_->get_signal_description(quiddity_name, signal_name); command_->result_.push_back(res); command_unlock(); return res; }
static int command_add(struct command_head_t *cmd_head, struct command_t *cmd, int sys_cmd) { int ret = 0; command_lock(cmd_head->lock); if (sys_cmd) ret = __command_add(&cmd_head->sys, cmd); else ret = __command_add(&cmd_head->user, cmd); command_unlock(cmd_head->lock); return ret; }
bool QuiddityManager::remove_signal_subscriber(const std::string& subscriber_name) { command_lock(); command_->set_id(QuiddityCommand::remove_signal_subscriber); command_->add_arg(subscriber_name); bool res = manager_impl_->remove_signal_subscriber(subscriber_name); if (res) command_->result_.push_back("true"); else command_->result_.push_back("false"); command_unlock(); return res; }
bool QuiddityManager::has_method(const std::string& quiddity_name, const std::string& method_name) { // FIXME do not have this command_lock(); command_->set_id(QuiddityCommand::has_method); command_->add_arg(quiddity_name); command_->add_arg(method_name); bool res = manager_impl_->has_method(quiddity_name, method_name); if (res) command_->result_.push_back("true"); else command_->result_.push_back("false"); command_unlock(); return res; }
bool QuiddityManager::invoke_va(const std::string& quiddity_name, const std::string& method_name, std::string** return_value, ...) { command_lock(); std::vector<std::string> method_args; command_->set_id(QuiddityCommand::invoke); if (quiddity_name.empty()) { g_warning("trying to invoke with a quiddity with empty name"); command_unlock(); return false; } if (method_name.empty()) { g_warning("trying to invoke with a method with empty name"); command_unlock(); return false; } va_list vl; va_start(vl, return_value); char* method_arg = va_arg(vl, char*); while (method_arg != nullptr) { method_args.push_back(method_arg); method_arg = va_arg(vl, char*); } va_end(vl); command_->add_arg(quiddity_name); command_->add_arg(method_name); command_->set_vector_arg(method_args); invoke_in_thread(); if (return_value != nullptr && !command_->result_.empty()) *return_value = new std::string(command_->result_[0]); bool res = command_->success_; command_unlock(); return res; }
bool QuiddityManager::make_signal_subscriber(const std::string& subscriber_name, QuiddityManager::SignalCallback callback, void* user_data) { command_lock(); command_->set_id(QuiddityCommand::make_signal_subscriber); command_->add_arg(subscriber_name); bool res = manager_impl_->make_signal_subscriber(subscriber_name, callback, user_data); if (res) command_->result_.push_back("true"); else command_->result_.push_back("false"); command_unlock(); return res; }
bool QuiddityManager::invoke(const std::string& quiddity_name, const std::string& method_name, std::string** return_value, const std::vector<std::string>& args) { // std::string res; command_lock(); command_->set_id(QuiddityCommand::invoke); command_->add_arg(quiddity_name); command_->add_arg(method_name); command_->set_vector_arg(args); invoke_in_thread(); if (return_value != nullptr && !command_->result_.empty()) *return_value = new std::string(command_->result_[0]); bool res = command_->success_; command_unlock(); return res; }
// works for char *args only. Use nullptr sentinel std::string QuiddityManager::seq_invoke(QuiddityCommand::command command, ...) { std::string res; command_lock(); va_list vl; va_start(vl, command); command_->set_id(command); char* command_arg = va_arg(vl, char*); while (command_arg != nullptr) { command_->add_arg(command_arg); command_arg = va_arg(vl, char*); } va_end(vl); invoke_in_thread(); res = command_->result_[0]; if (command_->id_ == QuiddityCommand::create || command_->id_ == QuiddityCommand::create_nick_named) auto_init(command_->result_[0]); command_unlock(); return res; }
void QuiddityManager::play_command_history(QuiddityManager::CommandHistory histo, QuiddityManager::PropCallbackMap* /*prop_cb_data*/, QuiddityManager::SignalCallbackMap* /*sig_cb_data*/, bool mute_existing_subscribers) { bool debug = false; if (mute_existing_subscribers) manager_impl_->mute_signal_subscribers(true); On_scope_exit { if (mute_existing_subscribers) manager_impl_->mute_signal_subscribers(false); }; if (debug) g_print("start playing history\n"); // making quiddities if (histo.quiddities_) { auto quids = histo.quiddities_->get_child_keys("."); // creating quiddities for (auto& it : quids) { std::string quid_class = histo.quiddities_->branch_get_value(it); if (it != create(quid_class, it)) { g_warning("error creating quiddity %s (of type %s)", it.c_str(), quid_class.c_str()); } } // loading custom state for (auto& it : quids) { if (!manager_impl_->has_instance(it)) continue; if (histo.custom_states_ && !histo.custom_states_->empty()) { manager_impl_->get_quiddity(it)->on_loading(histo.custom_states_->get_tree(it)); } else { manager_impl_->get_quiddity(it)->on_loading(InfoTree::make()); } } } // applying properties std::vector<std::string> quid_to_start; if (histo.properties_) { auto quids = histo.properties_->get_child_keys("."); for (auto& quid : quids) { auto props = histo.properties_->get_child_keys(quid); for (auto& prop : props) { if (prop == "started" && histo.properties_->branch_get_value(quid + ".started")) { quid_to_start.push_back(quid); } else { if (!use_prop<MPtr(&PContainer::set_str_str)>( quid, prop, Any::to_string(histo.properties_->branch_get_value(quid + "." + prop)))) g_warning( "failed to apply value, quiddity is %s, property is %s, value is %s", quid.c_str(), prop.c_str(), Any::to_string(histo.properties_->branch_get_value(quid + "." + prop)).c_str()); } } } } // playing history for (auto& it : histo.history_) { // do not run commands that not supposed to be saved if (!must_be_saved(it->id_)) continue; command_lock(); command_ = it; if (debug) { g_print("running command %s args:", QuiddityCommand::get_string_from_id(command_->id_)); for (auto& iter : command_->args_) g_print(" %s ", iter.c_str()); g_print("\n"); if (!command_->vector_arg_.empty()) { g_print(" vector args:"); for (auto& iter : command_->vector_arg_) g_print(" %s ", iter.c_str()); g_print("\n"); } } invoke_in_thread(); command_unlock(); } // end for (auto &it : histo) if (debug) g_print("finished playing history\n"); // applying user data to quiddities if (histo.quiddities_user_data_) { auto quids = histo.quiddities_user_data_->get_child_keys("."); for (auto& it : quids) { if (manager_impl_->has_instance(it)) { auto child_keys = histo.quiddities_user_data_->get_child_keys(it); for (auto& kit : child_keys) { manager_impl_->user_data<MPtr(&InfoTree::graft)>( it, kit, histo.quiddities_user_data_->get_tree(it + "." + kit)); } } } } // starting quiddities for (auto& quid : quid_to_start) { if (!use_prop<MPtr(&PContainer::set_str_str)>(quid, "started", "true")) { g_warning("failed to start quiddity %s", quid.c_str()); } } // Connect shmdata if (histo.readers_) { auto quids = histo.readers_->get_child_keys("."); for (auto& quid : quids) { auto readers = histo.readers_->get_child_keys(quid); for (auto& reader : readers) { manager_impl_->invoke( quid, "connect", nullptr, {Any::to_string(histo.readers_->branch_get_value(quid + "." + reader))}); } } } // on_loaded if (histo.quiddities_) { auto quids = histo.quiddities_->get_child_keys("."); for (auto& it : quids) { if (!manager_impl_->has_instance(it)) continue; manager_impl_->get_quiddity(it)->on_loaded(); } } }
/*! * Liest ein Kommando ein, ist blockierend! * Greift auf low_read() zurueck * @see low_read() */ int command_read(void){ int bytesRcvd; int start=0; // start of command sequence int i; command_t * command; // Pointer to Cast rceceived data char * ptr; // helper char buffer[RCVBUFSIZE]; // Buffer #if BYTE_ORDER == BIG_ENDIAN uint16 store; //store for endian conversion #endif buffer[0]=0; // Start with clean data // uint8 tmp=uart_data_available(); // Den ganzen Puffer abholen bytesRcvd=low_read(buffer,sizeof(command_t)); // LOG_DEBUG(("%d/%d read/av",bytesRcvd,tmp)); // LOG_DEBUG(("%x %x %x",buffer[0],buffer[1],buffer[2])); // Search for frame start while ((start<bytesRcvd)&&(buffer[start] != CMD_STARTCODE)) { // printf("."); start++; } // if no STARCODE ==> discard if (buffer[start] != CMD_STARTCODE){ // LOG_DEBUG(("start not found")); return -1; } // LOG_DEBUG(("Start @%d",start)); //is any chance, that the packet will still fit to buffer? if ((RCVBUFSIZE-start) < sizeof(command_t)){ // LOG_DEBUG(("not enough space")); return -1; // no ==> discard } i=sizeof(command_t) - (bytesRcvd-start); // get rest of package as long as buffer is full while (i > 0){ // LOG_DEBUG(("%d bytes missing",i)); i= low_read(buffer+bytesRcvd,i); // LOG_DEBUG(("%d read",i)); bytesRcvd+=i; i=sizeof(command_t) - (bytesRcvd-start); } // LOG_DEBUG(("%d/%d read/start",bytesRcvd,start)); // LOG_DEBUG(("%x %x %x",buffer[start],buffer[start+1],buffer[start+2])); // Cast to command_t command= (command_t *) ( buffer +start); // LOG_DEBUG(("start: %x ",command->startCode)); // command_display(command); // validate (startcode is already ok, or we won't be here) if (command->CRC==CMD_STOPCODE){ // LOG_DEBUG(("Command is valid")); // Transfer #ifdef PC command_lock(); // on PC make storage threadsafe #endif ptr = (char *) &received_command; for (i=0; i<sizeof(command_t);i++){ *ptr=buffer[i+start]; ptr++; } #if BYTE_ORDER == BIG_ENDIAN /* Umwandeln der 16 bit Werte in Big Endian */ store = received_command.data_l; received_command.data_l = store << 8; received_command.data_l |= (store >> 8) & 0xff; store = received_command.data_r; received_command.data_r = store << 8; received_command.data_r |= (store >> 8) & 0xff; store = received_command.seq; received_command.seq = store << 8; received_command.seq |= (store >> 8) & 0xff; /* "Umdrehen" des Bitfields */ store = received_command.request.subcommand; received_command.request.subcommand = store << 1; received_command.request.direction = store >> 7; #endif #ifdef PC command_unlock(); // on PC make storage threadsafe #endif return 0; } else { // Command not valid