1
resposta

[Dúvida] Dificuldade para fazer a implementação do controle de ociosidade no kakoBot

Olá, estou com dificuldade para fazer a implementação do controle de ociosidade no kakoBot qual seria a sugestão de vocês? Tenho a impressão de que o programa trava as chamadas assíncronas quando executa a linha "usuario = stdin.readLineSync().toString();" do arquivo "kako_bot.dart" pois não continua a execução da Stream, talvez um problema de executar esse comando via terminal? Já estudei a implementação deixada no Github (off: agora o chat tem boas maneiras, kkkk) vou postar o que tentei até agora (off: para outros alunos que verem essa postagem, tive que minimizar partes do código que não alterei pois não cabia dentro do limite de 5000 caracteres, são as partes com 3 pontos):

Arquivo "kako_bot.dart":

import 'dart:io';

import 'questions/good_manners.dart';
import 'questions/time_questions.dart';
import 'timing/waiting_time.dart';

void main() async{
  String kakoBot = 'KakoBOT:\n';
  var a = true;
  String usuario = '';

  /*...*/

  //INICIO MINHA IMPLEMENTAÇÃO ---------------------------------------------------------------
  int limiteTempoOsciosoEmSegundos = 10;
  var controleOsciosidade = BotClock().kakoBotControleOsiosidadeEmSegundos(limiteTempoOsciosoEmSegundos);
  var subscriberControleOsciosidade = controleOsciosidade.listen((event) => {},
  onDone: (){
    print('                                   KakoBot está sendo finalizado pois ficou ocioso por mais de $limiteTempoOsciosoEmSegundos segundos!');
    a = false;
  });
  //FIM MINHA IMPLEMENTAÇÃO ---------------------------------------------------------------

  print('-- Iniciando o KakoBOT, aguarde..--');
  await BotClock().clock(3);
  print('KakoBOT:\n Oi :) \n Como posso ajudar?');
  do {...} while (a);

  print('--Encerrando KakoBOT--');
}

Arquivo "timing\waiting_time.dart":

class BotClock{

  Future clock(int seconds){...}

  Stream kakoBotStream(int interval, [int? maxCount]) async* {...}

//INICIO MINHA IMPLEMENTAÇÃO ---------------------------------------------------------------
  Stream kakoBotControleOsiosidadeEmSegundos(int segundos) async*{
    int contarSegundos = 1;
    while(contarSegundos <= segundos){
      await Future.delayed(Duration(seconds: 1));
      print('                                   O controle de ociosidade está rodando a $contarSegundos');
      yield contarSegundos++;
    }
    //criar forma de reiniciar o contador cada vez que o usuario interagir
  }
  //FIM MINHA IMPLEMENTAÇÃO ---------------------------------------------------------------
}

Não houveram alterações nos arquivos "good_manners.dart" e "time_questions.dart" da pasta "questions".

Saída da execução do código (perceba que a Stream só funciona enquanto o terminal não está aguardando a entrada dos dados do usuário):

C:/sdk/dart-sdk/bin/dart.exe --enable-asserts --no-serve-devtools C:\Projetos\curso-5-dart-assincronismo-master\bin\desafioTempoOscioso\kako_bot.dart
-- Iniciando o KakoBOT, aguarde..--
                                   O controle de ociosidade está rodando a 1
                                   O controle de ociosidade está rodando a 2
KakoBOT:
 Oi :) 
 Como posso ajudar?
TESTE
-- Processando pergunta, aguarde..--
                                   O controle de ociosidade está rodando a 3
                                   O controle de ociosidade está rodando a 4
                                   O controle de ociosidade está rodando a 5
KakoBOT:
 Não fui treinado para responder a essa pergunta 
 Desculpe :( 
KakoBOT:
 Você pode fazer outra pergunta ou dizer Adeus
TESTE
-- Processando pergunta, aguarde..--
                                   O controle de ociosidade está rodando a 6
                                   O controle de ociosidade está rodando a 7
                                   O controle de ociosidade está rodando a 8
KakoBOT:
 Não fui treinado para responder a essa pergunta 
 Desculpe :( 
KakoBOT:
 Você pode fazer outra pergunta ou dizer Adeus
TESTE
-- Processando pergunta, aguarde..--
                                   O controle de ociosidade está rodando a 9
                                   O controle de ociosidade está rodando a 10
                                   KakoBot está sendo finalizado pois ficou ocioso por mais de 10 segundos!
KakoBOT:
 Não fui treinado para responder a essa pergunta 
 Desculpe :( 
KakoBOT:
 Você pode fazer outra pergunta ou dizer Adeus
--Encerrando KakoBOT--

Process finished with exit code 0
1 resposta

Oi

O problema é que a função stdin.readLineSync() está bloqueando o fluxo assíncrono da sua Stream.

Você pode usar a função stdin.listen pra ler a entrada do usuário de forma assíncrona. Isso vai fazer com que a Stream de controle de ociosidade continue rodando enquanto espera pela entrada do usuário.

import 'dart:io';

import 'questions/good_manners.dart';
import 'questions/time_questions.dart';
import 'timing/waiting_time.dart';

void main() async {
  String kakoBot = 'KakoBOT:\n';
  var a = true;
  String usuario = '';

  // INÍCIO DA IMPLEMENTAÇÃO ---------------------------------------------------------------
  int limiteTempoOciosoEmSegundos = 10;
  var controleOciosidade = BotClock().kakoBotControleOciosidadeEmSegundos(limiteTempoOciosoEmSegundos);
  var subscriberControleOciosidade = controleOciosidade.listen((event) => {},
    onDone: () {
      print('                                   KakoBot está sendo finalizado pois ficou ocioso por mais de $limiteTempoOciosoEmSegundos segundos!');
      a = false;
    });
  // FIM DA IMPLEMENTAÇÃO ---------------------------------------------------------------

  print('-- Iniciando o KakoBOT, aguarde..--');
  await BotClock().clock(3);
  print('KakoBOT:\n Oi :) \n Como posso ajudar?');

  stdin.listen((input) {
    usuario = input.trim();
    // Reiniciar o contador de ociosidade aqui
    subscriberControleOciosidade.cancel();
    controleOciosidade = BotClock().kakoBotControleOciosidadeEmSegundos(limiteTempoOciosoEmSegundos);
    subscriberControleOciosidade = controleOciosidade.listen((event) => {},
      onDone: () {
        print('                                   KakoBot está sendo finalizado pois ficou ocioso por mais de $limiteTempoOciosoEmSegundos segundos!');
        a = false;
      });

    if (usuario.toLowerCase() == 'adeus') {
      a = false;
    } else {
      print('-- Processando pergunta, aguarde..--');
      // Aqui você pode adicionar o processamento da pergunta do usuário
    }
  });

  while (a) {
    await Future.delayed(Duration(seconds: 1));
  }

  print('--Encerrando KakoBOT--');
}
class BotClock {
  Future clock(int seconds) async {
    await Future.delayed(Duration(seconds: seconds));
  }

  Stream kakoBotStream(int interval, [int? maxCount]) async* {
    int i = 0;
    while (maxCount == null || i < maxCount) {
      await Future.delayed(Duration(seconds: interval));
      yield i++;
    }
  }

  // INÍCIO DA IMPLEMENTAÇÃO ---------------------------------------------------------------
  Stream kakoBotControleOciosidadeEmSegundos(int segundos) async* {
    int contarSegundos = 1;
    while (contarSegundos <= segundos) {
      await Future.delayed(Duration(seconds: 1));
      print('                                   O controle de ociosidade está rodando há $contarSegundos segundos');
      yield contarSegundos++;
    }
  }
  // FIM DA IMPLEMENTAÇÃO ---------------------------------------------------------------
}

Valeu!