Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

398
LINES

< > BotCompany Repo | #1002317 // Sub-Bot Dispatcher (LIVE)

JavaX source code [tags: dont-transpile use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (8044L/52K).

!7

set flag Matches_fsi.

static new L<Bot> bots;
static S whoSaidThat;
static new ThreadLocal<S> sendingAnswer;
static new ThreadLocal<Bool> dispatcherAuth;
static ThreadLocal<L<Answer>> answers = new ThreadLocal;
static boolean showMultiResponse = false;
static Set<S> reloading = syncSet();

static class Answer {
  S bot, text;
  
  *(S *bot, S *text) {}
  *() {}
}

static volatile S loadingBotID;

static class Bot {
  S id; // always formatted
  boolean enabled, always;
  double prio;
  
  *(S *id, boolean *enabled) {}
  *() {}
}

static Map<S, Class> classes = synchroTreeMap();

// wait while a bot is reloading; not used yet
static Set<S> gracePeriods = expiringSet(20.0);

static volatile long ticks;
static volatile boolean tickActionsEnabled = true;

p {
  load("bots");
  loadAll();
  
  load("ticks");
  load("tickActionsEnabled");
  //startTicking();
}

static void loadAll() {
  for (Bot bot : bots) pcall {
    loadBot(bot);
  }
}

static void loadBot(Bot bot) {
  loadingBotID = bot.id;
  try {
    Class c;
    try {
      c = hotwire(bot.id);
    } catch (Throwable e) {
      throw new RuntimeException("Error in hotwire of " + bot.id, e);
    }
    classes.put(bot.id, c);
    setOpt(c, "mainBot", getMainBot());
    try {
      callMain(c);
    } catch (Throwable e) {
      throw new RuntimeException("Error in main of " + bot.id, e);
    }
  } finally {
    loadingBotID = null;
  }
}

static Class getSubBot(S id) {
  ret getBot(id);
}

static Class getBot(S id) {
  ret classes.get(formatSnippetID(id));
}

static Bot findSubBot(S id) {
  ret findByField(bots, "id", formatSnippetID(id));
}

answer {
try {
 synchronized(main.class) {
  if "ticks" ret str(ticks);
  
  if (master()) {
    if "enable ticks" {
      tickActionsEnabled = true;
      save("tickActionsEnabled");
      ret "OK, enabled";
    }
    
    if "disable ticks" {
      tickActionsEnabled = false;
      save("tickActionsEnabled");
      ret "OK, disabled";
    }
  }
  
  if "count sub bots"
    ret lstr(getSubBots());

  if "full list sub bots"
    ret slackSnippet(structureLines(getSubBots()));

  if "list sub bots" {
    new L<S> notLoaded;
    L<Bot> bots = getSubBots();
    for (Bot bot : bots)
      if (!classes.containsKey(bot.id))
        notLoaded.add(bot.id);
    S a = "Enabled: " + structure(collectField(filterByField(bots, "enabled", true), "id")) + ". Disabled: " + structure(collectField(filterByField(bots, "enabled", false), "id"));
    if (!empty(notLoaded))
      a += ". Not loaded: " + structure(notLoaded);
    ret a;
  }
  
  if "bot prios" {
    new MultiMap<Double, S> map;
    for (Bot bot : bots)
      map.put(bot.prio, bot.id);
    map.remove(0.0);
    ret slackSnippet("Listing all but prio 0:\n"+ structureLines(map.data));
  }
    
  if "is * a sub bot?"
    ret findSubBot(m.unq(0)) != null ? "yes": "no";
    
  if (master()) {
  
    if "add sub bots *" {
      L<S> bots = (L) safeUnstructure(m.unq(0));
      new L<S> out;
      for (S id : bots) pcall {
        S q = format("add sub bot *", id);
        out.add(q + " => ");
        appendToLast(out, askSelf(q));
      }
      ret slackSnippet(fromLines(out));
    }
    if "add sub bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bots.remove(bot);
        bots.add(0, bot);
        save("bots");
        ret "OK, bumped.";
      }
      bots.add(0, bot = new Bot(id, true));
      save("bots");
      loadBot(bot);
      ret format("OK, * loaded & added to top.", id);
    }
    
    if "enable sub bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bot.enabled = true;
        save("bots");
        ret "OK, enabled.";
      }
      ret "woot";
    }
    
    if "disable sub bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bot.enabled = false;
        save("bots");
        ret "OK, disabled.";
      }
      ret "woot";
    }
    
    // an "always bot" is one that should read all msgs
    
    if "enable always bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bot.always = true;
        save("bots");
        ret "OK, has status 'always' now.";
      }
      ret "woot";
    }
    
    if "disable always bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bot.always = false;
        save("bots");
        ret "OK, lost status 'always'.";
      }
      ret "woot";
    }
    
    if "prio bot * *" {
      S id = m.fsi(0);
      double newPrio = parseDouble(m.unq(1));
      Bot bot = findSubBot(id);
      if (bot != null) {
        bot.prio = newPrio;
        save("bots");
        ret format("OK, prio changed to *", newPrio);
      }
      ret "woot";
    }
    
    if "list bot *"
      ret structure(findSubBot(m.unq(0)));

    if "remove sub bot *" {
      S id = m.fsi(0);
      Bot bot = findSubBot(id);
      if (bot != null) {
        bots.remove(bot);
        save("bots");
        
        cleanUp(classes.get(id));
        classes.remove(id);
        ret "OK, removed.";
      }
      ret "woot not there anyway";
    }
    
    if (match("reload sub bot *", s, m) || match("reload sub *", s, m)) {
      S id = m.fsi(0);
      long time = sysNow();
      Bot bot = findSubBot(id);
      if (bot != null) {
        gracePeriods.add(id);
        temp tempAdd(reloading, id);
        cleanUp(classes.get(id));
        classes.remove(id);
        loadBot(bot);
        ret "OK, reloaded in " + renderElapsedTimePleasantly_100ms(elapsedMS(time));
      }
      ret "woot not found";
    }
  }
  
  
 }
 
  // dispatch to sub bots
  
  O randomChecker = getBot("#1003005");

  L<Bot> dehbots = getSubBots();

  sendingAnswer.set(null);
  answers.set(new L);
  boolean showMultiResponse = main.showMultiResponse || tb();
  for (Bot bot : dehbots) pcall {
    if (!bot.enabled) continue;
    Class c = classes.get(bot.id);
    if (c != null) {
      //print("Dispatching to " + bot.id);
      S a = callStaticAnswerMethod(c, s);
      if (!empty(a)) {
        sendingAnswer.set(a);
        answers.get().add(new Answer(bot.id, a));
        whoSaidThat = bot.id;
        if (!showMultiResponse) {
          informAlwaysBots(subList(dehbots, dehbots.indexOf(bot)+1), s);
          ret sendingAnswer.get();
        }
      }
    }
  }
  
  if (showMultiResponse) {
    new L<Answer> nonrand;
    new L<Answer> rand;
    for (Answer a : answers.get())
      (isRandomBot(randomChecker, a.bot) ? rand : nonrand).add(a);
      
    // only show random if there is no non-random response
    if (empty(nonrand)) nonrand.addAll(rand);
    
    L<Answer> l = nonrand;
    new L<S> list;
    if (empty(l)) ret null;
    if (l(l) == 1) ret first(l).text;
    for (Answer a : l)
      setAdd(list, "[" + a.bot + "] " + a.text);
    ret fromLines(list);
  }
} catch (Throwable e) { printStackTrace(e); ret str(e); }
}

static synchronized void cleanMeUp() {
  print("Cleaning up " + l(classes) + " sub-bots");
  for (Class c : classes.values())
    cleanUp(c);
  classes.clear();
  save("ticks");
}

static void informAlwaysBots(L<Bot> bots, S s) {
  for (Bot bot : bots)
    if (bot.always) pcall {
      Class c = classes.get(bot.id);
      if (c != null) {
        S a = callStaticAnswerMethod(c, s);
        if (!empty(a))
          print("Always bot " + bot.id + " said quietly: " + quote(a));
      }
    }
}

static synchronized L<S> getSubBotIDs() {
  ret collectField(getSubBots(), "id");
}

static synchronized L<Bot> getSubBots() {
  ret reversedList(sortedByField(bots, "prio"));
  /*ret concatLists(
    filterByField(bots, "lowPrio", false),
    filterByField(bots, "lowPrio", true));*/
}

static Class getClassOfSubBot(S id) {
  ret classes.get(id);
}

// loaded / total
static int[] numLoaded() {
  ret new int[] {l(classes), l(bots) };
}

static void addSeedBot(S id) {
  Bot bot = findSubBot(id);
  if (bot != null) {
    printF("Seed bot * already there.", id);
    ret;
  }
  bots.add(0, bot = new Bot(id, true));
  save("bots");
  loadBot(bot);
  printF("OK, seed bot * loaded & added to top.", id);
}

static void startTicking() {
  thread "Ticker" {
    while true {
      if (tickActionsEnabled) pcall {
        tick();
      }
      ++ticks;
      sleep(250);
    }
  }
}

static void tick() {
  L<Bot> dehbots = getSubBots();

  for (Bot bot : dehbots) pcall {
    if (!bot.enabled) continue;
    Class c = classes.get(bot.id);
    if (c != null)
      callOpt(c, "tick");
  }
}

static S getSendingAnswer() {
  ret sendingAnswer.get();
}

static void overwriteAnswer(S a) {
  sendingAnswer.set(a);
}

static boolean isRandomBot(O randomChecker, S id) {
  if (randomChecker == null) ret false;
  pcall {
    ret (bool) call(randomChecker, "isRandomBot", id);
  }
  ret false;
}

sbool master() { ret webAuthed() || isTrue(dispatcherAuth!); }

sbool isReloading(S botID) {
  ret contains(reloading, fsIOpt(botID));
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002317
Snippet name: Sub-Bot Dispatcher (LIVE)
Eternal ID of this version: #1002317/11
Text MD5: 1a71ed3d3aee53c43e8567595393d558
Transpilation MD5: 219ac1c415febc55983caf144d5b276e
Author: stefan
Category: eleu
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-05-21 17:50:29
Source code size: 9379 bytes / 398 lines
Pitched / IR pitched: No / No
Views / Downloads: 1059 / 8478
Version history: 10 change(s)
Referenced in: [show references]