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

106
LINES

< > BotCompany Repo | #1002210 // 1st Level Dialog Engine with example script, multi-user, WORKS

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

Libraryless. Click here for Pure Java version (2185L/15K/47K).

!752

static L<S> thescript = toLinesFullTrim([[
  match("Hi Eleutheria");
  say("Hi there!");
  match("Hi Eleutheria");
  say("You have said that before :)");
]]);

static class PerUser {
  S dialogID;
  long position;
}

static new Map<S, PerUser> perUserMap;
static new ThreadLocal<PerUser> puCurrent;

static O mainBot;
  
p {
  load("perUserMap");
  makeBot("A Dialog Bot");
  printList(thescript);
}

// does not increase the index
static FC parseFunctionCall() {
  ret parseFunctionCall(currentScriptLine());
}

static S currentScriptLine() {
  int idx = (int) (u().position % l(thescript));
  ret thescript.get(idx);
}

synchronized answer {
  S dialogID = cast call(mainBot, "getDialogID");
  if (dialogID == null) ret null; // need a dialog id now
  PerUser pu = perUserMap.get(dialogID);
  if (pu == null) {
    pu = new PerUser;
    pu.dialogID = dialogID;
    printFormat("Created new dialog: *", dialogID);
    perUserMap.put(dialogID, pu);
  }
  puCurrent.set(pu);
  
  int safety = 0;
  while (safety++ < 1000) try {
    FC fc = parseFunctionCall();
    S f = fc.f;
    if (eq(f, "match")) {
      S pat = getString(fc.args, 0);
      if (!match(pat, s, m)) {
        softFail("I only understand: *", pat);
        null;
      }
      nextPosition(); // only after match succeeds, otherwise stay at that point
    } else if (eq(f, "say")) {
      nextPosition();
      S answer = getString(fc.args, 0);
      ret answer;
    } else
      throw fail("Unknown function in script: *", fc.f);
  } catch (Throwable e) {
    printFormat("Was parsing: *", currentScriptLine());
    throw asRuntimeException(e);
  }
  fail("hard limit reached - 1000 script lines at once - possible endless loop?");
}

// a parsed function call
static class FC {
  int idx; // index of next token
  S f;
  new L args;
}

static FC parseFunctionCall(S s) {
  L<S> tok = javaTok(s);
  new FC fc;
  fc.f = assertIsIdentifier(tok.get(1));
  int i = 5;
  assertEquals("(", tok.get(3));
  while (i < l(tok) && !eq(tok.get(i), ")")) {
    fc.args.add(unquote(tok.get(i)));
    i += 2;
    if (tok.get(i).equals(",")) // otherwise it's kinda mangled, eh. well! we just keep on parsing...
      i += 2;
  }
  if (eq(tok.get(i), ")")) // we even allow a missing closing bracket!
    i += 2;
  fc.idx = i; // save index so some other parser can continue parsing
  ret fc;
}

static void nextPosition() {
  ++u().position;
  save("perUserMap");
  print("Position in script now: " + u().position % l(thescript));
}

// get per-user data for current thread
static PerUser u() {
  ret puCurrent.get();
}

Author comment

Began life as a copy of #1002205

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: #1002210
Snippet name: 1st Level Dialog Engine with example script, multi-user, WORKS
Eternal ID of this version: #1002210/1
Text MD5: 09188794f9f70b487f9919646daf9c48
Transpilation MD5: 4618ccc1994bf0a20709314b2d003825
Author: stefan
Category: javax
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-12-27 18:46:52
Source code size: 2684 bytes / 106 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 669 / 695
Referenced in: [show references]