~ehmry/nim_tox

6ca4d354c9b87655831d860c58afdceb945bd00d — Emery Hemingway 1 year, 11 months ago 285d5e0
Configure options via callback

The options object requires manual memory management, so use a callback
to set options on a managed temporary object during newTox().
3 files changed, 36 insertions(+), 52 deletions(-)

M src/toxcore.nim
M tests/node.nim
M tests/test1.nim
M src/toxcore.nim => src/toxcore.nim +25 -28
@@ 332,10 332,10 @@ proc `savedata_type=`*(options: Options; `type`: TOX_SAVEDATA_TYPE) {.
proc savedata_data*(options: Options): ptr uint8 {.ctox_options_get.}
proc savedata_length*(options: Options): csize {.ctox_options_get.}

proc `saveData=`*(options: Options; data: var string) =
proc `saveData=`*(options: Options; data: string) =
  proc options_set_savedata_data(options: Options; data: ptr char; length: csize) {.ctoxProc.}
  # proc options_set_savedata_length(options: Options; length: csize) {.ctoxProc.}
  options.options_set_savedata_data(addr data[0], data.len)
  options.options_set_savedata_data(unsafeAddr data[0], data.len)

proc log_callback*(options: Options): tox_log_cb {.ctox_options_get.}
proc `log_callback=`*(options: Options; callback: tox_log_cb) {.


@@ 349,25 349,10 @@ proc `log_user_data=`*(options: Options; user_data: pointer) {.
  importc: "tox_options_set_log_user_data".}
  ## Set state object passed to logging callback.

proc default*(options: Options) {.ctox_options.}
  ## Initialize `options` with default values.

type
  Tox_Err_Options_New = enum
    TOX_ERR_OPTIONS_NEW_OK,
    TOX_ERR_OPTIONS_NEW_MALLOC

proc newOptions*(): Options =
  ## Create a new `Options` object.
  proc options_new(error: ptr TOX_ERR_OPTIONS_NEW): Options {.ctoxProc.}
  var err: TOX_ERR_OPTIONS_NEW
  result = options_new(addr err)
  ctoxAssert(TOX_ERR_OPTIONS_NEW_OK, err)

proc options_free*(options: Options) {.ctoxProc.}
  ## Free an `Options` object.

type
  Tox_Err_New = enum
    TOX_ERR_NEW_OK,
    TOX_ERR_NEW_NULL,


@@ 380,24 365,33 @@ type
    TOX_ERR_NEW_LOAD_ENCRYPTED,
    TOX_ERR_NEW_LOAD_BAD_FORMAT

proc new(options: Options; error: ptr TOX_ERR_NEW): Core {.ctoxProc.}

proc newTox*(options: Options): Tox =
proc newTox*(configure: proc (opt: Options)): Tox =
  ## Create a new Tox instance.
  ##
  ## .. code-block:: nim
  ##   let opt = newOptions()
  ##   default(options)
  ##   let tox = newTox(opt)
  ##   freeOptions(opt)
  ##   let tox = newTox do (opts: Options):
  ##     opts.localDiscoveryEnabled = true
  ##     opts.holePunchingEnabled = false
  ##  tox.iterate()
  ##
  proc options_new(error: ptr TOX_ERR_OPTIONS_NEW): Options {.ctoxProc.}
  proc options_default(options: Options) {.ctoxProc.}
  proc options_free(options: Options) {.ctoxProc.}
  proc new(options: Options; error: ptr TOX_ERR_NEW): Core {.ctoxProc.}
  var err: TOX_ERR_NEW
  result = Tox(core: new(options, addr err))
  ctoxAssert(TOX_ERR_NEW_OK, err)
  var err: TOX_ERR_OPTIONS_NEW
  let opt = options_new(addr err)
  ctoxAssert(TOX_ERR_OPTIONS_NEW_OK, err)
  defer: options_free(opt)
  options_default(opt)
  configure(opt)
  block:
    var err: TOX_ERR_NEW
    result = Tox(core: new(opt, addr err))
    ctoxAssert(TOX_ERR_NEW_OK, err)

proc newTox*(): Tox =
  ## Create a new Tox instance.
  proc new(options: Options; error: ptr TOX_ERR_NEW): Core {.ctoxProc.}
  var err: TOX_ERR_NEW
  result = Tox(core: new(nil, addr err))
  ctoxAssert(TOX_ERR_NEW_OK, err)


@@ 430,7 424,10 @@ type
    TOX_ERR_BOOTSTRAP_BAD_HOST,
    TOX_ERR_BOOTSTRAP_BAD_PORT

proc bootstrap*(tox: Tox; host: string; key: PublicKey; port = 33445'u16) {.tags: [IOEffect].} =
const
  defaultPort* = 33445'u16

proc bootstrap*(tox: Tox; host: string; key: PublicKey; port = defaultPort) {.tags: [IOEffect].} =
  ## Bootstap the `tox` DHT state.
  proc bootstrap(
    core: Core; host: cstring; port: uint16;

M tests/node.nim => tests/node.nim +10 -21
@@ 9,10 9,6 @@ onSignal(SIGINT, SIGTERM):
  writeFile("tox.save", gTox.saveData)
  quit(0)

const
  PORT_RANGE_START = 33445
  PORT_RANGE_END = 34445

proc logCb(
    core: Core; level: TOX_LOG_LEVEL; file: cstring; line: uint32;
    `func`: cstring; message: cstring; user_data: pointer) {.cdecl.} =


@@ 47,25 43,17 @@ proc friendMessage(friend: Friend; msg: string; kind: TOX_MESSAGE_TYPE) =
  echo "friend sends ", kind, " message: ", msg

proc createTox(): Tox =
  var
    saveData = ""
    options = newOptions()
  var saveData = ""
  try: saveData = readFile("tox.save")
  except: discard
  default options
  options.logCallback = logCb
  options.ipv6Enabled = false
  options.localDiscoveryEnabled = true
  options.startPort = PORT_RANGE_START
  options.endPort = PORT_RANGE_END
  if saveData != "":
    options.saveData = saveData
    options.saveDataType = TOX_SAVEDATA_TYPE_TOX_SAVE

  # if (savedata_filename) {

  result = newTox(options)
  options_free options
  result = newTox do (options: Options):
    options.logCallback = logCb
    options.ipv6Enabled = false
    options.holePunchingEnabled = false
    options.localDiscoveryEnabled = true
    if saveData != "":
      options.saveData = saveData
      options.saveDataType = TOX_SAVEDATA_TYPE_TOX_SAVE

proc initFriends(tox: Tox) =



@@ 131,6 119,7 @@ proc main() =
  except:
    discard

  echo "DHT: ", tox.dhtId
  echo "UDP: ", tox.udpPort
  #echo "TCP: ", tox.tcpPort
  echo "--- polling Tox ---"

M tests/test1.nim => tests/test1.nim +1 -3
@@ 3,8 3,6 @@ import unittest
import toxcore

test "basic":
  var options = newOptions()
  default(options)
  let tox = newTox(options)
  let tox = newTox()
  check(tox.address.isValid)
  close tox