ttiming代码

一、applet::ttiming::tdisable_stop_timing_lock

图1 错误时机调用aplt::tros::request_task

图1函数栈是这么形成的。

  1. 到时间点了,机器人执行控制某个ble设备的定时任务A。首先要导航到设备附近。于是启动导航,界面出现“导航中”绿条,执行操作是moveto_function。即图1高亮的那个函数。
  2. moveto_function调用时间片tpropress_::show_slice,后者调用app_rose_slice。
  3. app_rose_slice调用语音驱动(tleagor_speech)时间片slice:tleagor_speech::slice。
  4. tleagor_speech::slice此刻检测到用户说了句“去窗台”,由此语音产生(request_task)一个临时任务:导航去窗台。
  5. 在执行game_instance::request_task时,发现当前正有一个任务A,临时任务优先级要比任务A高,于是调用stop_timing先结束这个任务A。
  6. 执行stop_timing,导致任务A相关变量被清空。但是,等绿条结束后,机器人还要任务A的后绪操作,可那时相关变量都变了,导致程序崩溃。

为避免这个问题,就要保证在执行绿条函数moveto_function的整个过程,禁止结束任务A。为达到这个目的,方法是不调用语音驱动时间片函数tleagor_speech::slice。既然不会产生新临时任务,自然也就不会有结束任务A操作。

由于tleagor_speech::slice没被调用,由“去窗台”这个声音指令产生操作会被延时。但要是没发生意外,绿条时间不会长,应该能接受。

回到tdisable_stop_timing_lock,它就是为实现上面这个思路而提供的一个类。

 

1.1 放置tdisable_stop_timing_lock对象

一个tdisable_stop_timing_lock对象会改变timing_.disable_stop_timing_值。disable_stop_timing_平时是false,一旦存在一个tdisable_stop_timing_lock对象,该值会改为true。一旦tdisable_stop_timing_lock销毁,该值恢复到false。

存在一个tdisable_stop_timing_lock对象期间,在受它“保护”的代码执行后,要确保已有的timing任务必须依旧存在,即中间不能发生stop_timing操作。

bool tros_instance::moveto_guid_bh(tros_instance::ttask* task_ptr)
{
    applet::ttiming::tdisable_stop_timing_lock lock(instance->timing());
    ...
    gui2::tprogress_default_slot slot(std::bind(&tros_instance::moveto_function, this, _1, ...));
    bool ret = gui2::run_with_progress(slot, null_str, _("Starting navigation"), 1);
    ...
    return ret;
}

tdisable_stop_timing_lock放在了moveto_function的上一级函数moveto_guid_bh,意味着moveto_function整个过程disable_stop_timing_是true。那(disable_stop_timing_==true)是如何保证不发生stop_timing操作?

 

1.2 使用timing_.disable_stop_timing()

timing_.disable_stop_timing()返回timing_.disable_stop_timing_当前值。

void game_instance::app_ros_slice()
{
    ...
    if (!timing_.disable_stop_timing()) {
        speech_.slice();
    }
    ...
}

app_ros_slice发现“timing_.disable_stop_timing_==true”,就不执行语音驱动时间片slice。于是保证了moveto_function内不发生stop_timing操作。

 

1.3 弹出窗口时,像message提示框

message提示框包括简单一句提示、带“YES、NO”确认的提示。这些窗口在显示时,一直会调用app_ros_slice。这意味着,要是用户发的语音指令能生成一个临时任务,并且任务需要导航的话,会在这个“小窗口”上出现“导航中”绿条。

思考一个问题,弹出message提示框时,如果已在运行一个任务A,又新来一个要导航的临时任务,执行临时任务前的stop_timing会导致程序崩溃吗?——不会。这时不像绿条情况,任务A结束就结束了,结束后就没有代码要用到任务A。

message提示框上出绿条,让人看到是界面不美观。除base_instance::stop_timing_if_runing内的message不让产生临时任务,其它没做额外处理。不让产生临时任务方法也是使用tdisable_stop_timing_lock。

 

目前只有语音驱动slice能产生临时任务,将来如果有其它用户小程序能产生,也得做同样处理。即“disable_stop_timing==true”时不调用它的时间片。

全部评论: 0

    写评论: