tox 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9b379392361313b80d9b376b8f4367cc9298954
4
- data.tar.gz: 8b76e5c44863f518b384b016900029a88f127f57
3
+ metadata.gz: 1ab3125d380817a144ee66674764101ec8e86754
4
+ data.tar.gz: 2b4f4c0e20c4bec09f30a15db7414926a9eff90e
5
5
  SHA512:
6
- metadata.gz: 3cf31a4fc75645d1600897f353a82d3332884475f3d89014af12876be2d7df6282340973435658a6c07cf09069c88abac04f9d8de6deb42c36eb18806f2c0c31
7
- data.tar.gz: 6133a29001c3ba3ad110f00d3ed37eb7968aeb9459f55ee043496b782623eb5a63689b3ddd21e6d67afbad90661963f523e82d95c5c56bcb0dfb8d91b2d1848d
6
+ metadata.gz: 560228cc65e59acace9c3e56b36582124ca7372719ecb7b68fadee22eaf7869a88abebb51e0eb459a94066609ddb1ec802a1cc60d96c9d72c319104bdb6c93f7
7
+ data.tar.gz: 7d441fa2149a92729b072c7716ed3cec8a33968c92550c12caf715ee0b1a714efa5985c3ef348cf1e8869713726d31f82a079111f3bf4ade1d65ac5ec6c02d6d
@@ -3,33 +3,32 @@ AllCops:
3
3
  DisplayCopNames: true
4
4
 
5
5
  Exclude:
6
- - vendor/**/*
6
+ - 'vendor/**/*'
7
7
 
8
8
  Layout/AccessModifierIndentation:
9
9
  EnforcedStyle: outdent
10
10
 
11
11
  Layout/MultilineOperationIndentation:
12
12
  Exclude:
13
- - ext/**/*
13
+ - 'ext/**/*'
14
+
15
+ Lint/InheritException:
16
+ Enabled: false
14
17
 
15
18
  Metrics/BlockLength:
16
19
  Exclude:
17
20
  - '**/*.gemspec'
18
- - spec/**/*
19
-
20
- Metrics/LineLength:
21
- Max: 120
21
+ - 'spec/**/*'
22
22
 
23
23
  Style/AndOr:
24
- Exclude:
25
- - ext/**/*
24
+ EnforcedStyle: conditionals
26
25
 
27
26
  Style/DoubleNegation:
28
27
  Enabled: false
29
28
 
30
29
  Style/GlobalVars:
31
30
  Exclude:
32
- - ext/**/*
31
+ - 'ext/**/*'
33
32
 
34
33
  Style/TrailingCommaInArguments:
35
34
  EnforcedStyleForMultiline: comma
@@ -6,7 +6,7 @@
6
6
  # filename as the script argument it can restore private key from this file so
7
7
  # it's address will not change between restarts.
8
8
  #
9
- # Based on implementation in C: https://github.com/braiden-vasco/ToxEcho
9
+ # Based on implementation in C: https://github.com/toxon/ToxEcho
10
10
 
11
11
  require 'bundler/setup'
12
12
 
@@ -27,11 +27,13 @@ end
27
27
  tox_client = Tox::Client.new tox_options
28
28
 
29
29
  tox_client.name = NAME
30
+ tox_client.status = Tox::UserStatus::NONE
30
31
  tox_client.status_message = STATUS_MESSAGE
31
32
 
32
33
  puts
33
34
  puts "Address: #{tox_client.address.to_hex}"
34
35
  puts "Name: #{tox_client.name}"
36
+ puts "Status: #{tox_client.status}"
35
37
  puts "Status message: #{tox_client.status_message}"
36
38
  puts
37
39
 
@@ -39,16 +41,29 @@ puts 'Connecting to the nodes from official list...'
39
41
  tox_client.bootstrap_official
40
42
 
41
43
  tox_client.on_friend_request do |public_key|
42
- puts "Got friend request with public key #{public_key.to_hex}. Adding to contacts..."
44
+ puts "Got friend request with public key #{public_key.to_hex}. " \
45
+ 'Adding to contacts...'
46
+ puts
47
+
43
48
  tox_client.friend_add_norequest public_key
44
49
  end
45
50
 
46
51
  tox_client.on_friend_message do |friend, text|
47
- puts "Got message from friend number #{friend.number} with text #{text.inspect}. Sending it back..."
52
+ puts 'Message from friend'
53
+ puts "Number: #{friend.number}"
54
+ puts "Name: #{friend.name}"
55
+ puts "Public key: #{friend.public_key.to_hex}"
56
+ puts "Status: #{friend.status}"
57
+ puts "Status message: #{friend.status_message}"
58
+ puts text.inspect
59
+ puts
60
+
48
61
  friend.send_message text
49
62
  end
50
63
 
51
- puts 'Running. Send me friend request, I\'ll accept it immediately. Then send me a message.'
64
+ puts 'Running. Send me friend request, I\'ll accept it immediately. ' \
65
+ 'Then send me a message.'
66
+
52
67
  begin
53
68
  puts
54
69
  tox_client.run
@@ -17,22 +17,16 @@
17
17
  */
18
18
 
19
19
  #include "tox.h"
20
- #include "client.h"
21
- #include "options.h"
22
- #include "node.h"
23
- #include "friend.h"
24
20
 
25
21
  #include <time.h>
26
22
 
27
- // Instance
28
- VALUE mTox_cClient;
29
-
30
23
  // Memory management
31
24
  static VALUE mTox_cClient_alloc(VALUE klass);
32
25
  static void mTox_cClient_free(mTox_cClient_CDATA *free_cdata);
33
26
 
34
27
  // Public methods
35
28
 
29
+ static VALUE mTox_cClient_public_key(VALUE self);
36
30
  static VALUE mTox_cClient_address(VALUE self);
37
31
  static VALUE mTox_cClient_savedata(VALUE self);
38
32
 
@@ -41,9 +35,14 @@ static VALUE mTox_cClient_bootstrap(VALUE self, VALUE node);
41
35
  static VALUE mTox_cClient_name(VALUE self);
42
36
  static VALUE mTox_cClient_name_EQUALS(VALUE self, VALUE name);
43
37
 
38
+ static VALUE mTox_cClient_status(VALUE self);
39
+ static VALUE mTox_cClient_status_EQUALS(VALUE self, VALUE status);
40
+
44
41
  static VALUE mTox_cClient_status_message(VALUE self);
45
42
  static VALUE mTox_cClient_status_message_EQUALS(VALUE self, VALUE status_message);
46
43
 
44
+ static VALUE mTox_cClient_friend_numbers(VALUE self);
45
+
47
46
  static VALUE mTox_cClient_friend_add_norequest(VALUE self, VALUE public_key);
48
47
 
49
48
  // Private methods
@@ -70,31 +69,57 @@ static void on_friend_message(
70
69
  VALUE self
71
70
  );
72
71
 
72
+ static void on_friend_name_change(
73
+ Tox *tox,
74
+ uint32_t friend_number,
75
+ const uint8_t *name,
76
+ size_t length,
77
+ VALUE self
78
+ );
79
+
80
+ static void on_friend_status_message_change(
81
+ Tox *tox,
82
+ uint32_t friend_number,
83
+ const uint8_t *status_message,
84
+ size_t length,
85
+ VALUE self
86
+ );
87
+
88
+ static void on_friend_status_change(
89
+ Tox *tox,
90
+ uint32_t friend_number,
91
+ TOX_USER_STATUS status,
92
+ VALUE self
93
+ );
94
+
73
95
  /*************************************************************
74
96
  * Initialization
75
97
  *************************************************************/
76
98
 
77
99
  void mTox_cClient_INIT()
78
100
  {
79
- // Instance
80
- mTox_cClient = rb_define_class_under(mTox, "Client", rb_cObject);
81
-
82
101
  // Memory management
83
102
  rb_define_alloc_func(mTox_cClient, mTox_cClient_alloc);
84
103
 
85
104
  // Public methods
86
105
 
87
- rb_define_method(mTox_cClient, "address", mTox_cClient_address, 0);
88
- rb_define_method(mTox_cClient, "savedata", mTox_cClient_savedata, 0);
106
+ rb_define_method(mTox_cClient, "public_key", mTox_cClient_public_key, 0);
107
+ rb_define_method(mTox_cClient, "address", mTox_cClient_address, 0);
108
+ rb_define_method(mTox_cClient, "savedata", mTox_cClient_savedata, 0);
89
109
 
90
110
  rb_define_method(mTox_cClient, "bootstrap", mTox_cClient_bootstrap, 1);
91
111
 
92
112
  rb_define_method(mTox_cClient, "name", mTox_cClient_name, 0);
93
113
  rb_define_method(mTox_cClient, "name=", mTox_cClient_name_EQUALS, 1);
94
114
 
115
+ rb_define_method(mTox_cClient, "status", mTox_cClient_status, 0);
116
+ rb_define_method(mTox_cClient, "status=", mTox_cClient_status_EQUALS, 1);
117
+
95
118
  rb_define_method(mTox_cClient, "status_message", mTox_cClient_status_message, 0);
96
119
  rb_define_method(mTox_cClient, "status_message=", mTox_cClient_status_message_EQUALS, 1);
97
120
 
121
+ rb_define_method(mTox_cClient, "friend_numbers", mTox_cClient_friend_numbers, 0);
122
+
98
123
  rb_define_method(mTox_cClient, "friend_add_norequest", mTox_cClient_friend_add_norequest, 1);
99
124
 
100
125
  // Private methods
@@ -129,6 +154,25 @@ void mTox_cClient_free(mTox_cClient_CDATA *const free_cdata)
129
154
  * Public methods
130
155
  *************************************************************/
131
156
 
157
+ // Tox::Client#public_key
158
+ VALUE mTox_cClient_public_key(const VALUE self)
159
+ {
160
+ mTox_cClient_CDATA *self_cdata;
161
+
162
+ Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
163
+
164
+ char public_key[TOX_PUBLIC_KEY_SIZE];
165
+
166
+ tox_self_get_public_key(self_cdata->tox, (uint8_t*)public_key);
167
+
168
+ return rb_funcall(
169
+ mTox_cPublicKey,
170
+ rb_intern("new"),
171
+ 1,
172
+ rb_str_new(public_key, TOX_PUBLIC_KEY_SIZE)
173
+ );
174
+ }
175
+
132
176
  // Tox::Client#address
133
177
  VALUE mTox_cClient_address(const VALUE self)
134
178
  {
@@ -141,7 +185,7 @@ VALUE mTox_cClient_address(const VALUE self)
141
185
  tox_self_get_address(self_cdata->tox, (uint8_t*)address);
142
186
 
143
187
  return rb_funcall(
144
- rb_const_get(mTox, rb_intern("Address")),
188
+ mTox_cAddress,
145
189
  rb_intern("new"),
146
190
  1,
147
191
  rb_str_new(address, TOX_ADDRESS_SIZE)
@@ -188,6 +232,12 @@ VALUE mTox_cClient_bootstrap(const VALUE self, const VALUE node)
188
232
  switch (error) {
189
233
  case TOX_ERR_BOOTSTRAP_OK:
190
234
  return Qtrue;
235
+ case TOX_ERR_BOOTSTRAP_NULL:
236
+ return Qfalse;
237
+ case TOX_ERR_BOOTSTRAP_BAD_HOST:
238
+ return Qfalse;
239
+ case TOX_ERR_BOOTSTRAP_BAD_PORT:
240
+ return Qfalse;
191
241
  default:
192
242
  return Qfalse;
193
243
  }
@@ -232,13 +282,65 @@ VALUE mTox_cClient_name_EQUALS(const VALUE self, const VALUE name)
232
282
  switch (error) {
233
283
  case TOX_ERR_SET_INFO_OK:
234
284
  break;
285
+ case TOX_ERR_SET_INFO_NULL:
286
+ rb_raise(mTox_eNullError, "tox_self_set_name() failed with TOX_ERR_SET_INFO_NULL");
287
+ case TOX_ERR_SET_INFO_TOO_LONG:
288
+ rb_raise(rb_eRuntimeError, "tox_self_set_name() failed with TOX_ERR_SET_INFO_TOO_LONG");
235
289
  default:
236
- rb_raise(rb_eRuntimeError, "tox_self_set_name() failed");
290
+ rb_raise(mTox_eUnknownError, "tox_self_set_name() failed");
291
+ }
292
+
293
+ if (!result) {
294
+ rb_raise(mTox_eUnknownError, "tox_self_set_name() failed");
237
295
  }
238
296
 
239
297
  return name;
240
298
  }
241
299
 
300
+ // Tox::Client#status
301
+ VALUE mTox_cClient_status(const VALUE self)
302
+ {
303
+ mTox_cClient_CDATA *self_cdata;
304
+
305
+ Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
306
+
307
+ const TOX_USER_STATUS result = tox_self_get_status(self_cdata->tox);
308
+
309
+ switch (result) {
310
+ case TOX_USER_STATUS_NONE:
311
+ return mTox_mUserStatus_NONE;
312
+ case TOX_USER_STATUS_AWAY:
313
+ return mTox_mUserStatus_AWAY;
314
+ case TOX_USER_STATUS_BUSY:
315
+ return mTox_mUserStatus_BUSY;
316
+ default:
317
+ rb_raise(rb_eNotImpError, "Tox::Client#status has unknown value");
318
+ }
319
+ }
320
+
321
+ // Tox::Client#status=
322
+ VALUE mTox_cClient_status_EQUALS(const VALUE self, const VALUE status)
323
+ {
324
+ mTox_cClient_CDATA *self_cdata;
325
+
326
+ Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
327
+
328
+ if (rb_funcall(mTox_mUserStatus_NONE, rb_intern("=="), 1, status)) {
329
+ tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_NONE);
330
+ }
331
+ else if (rb_funcall(mTox_mUserStatus_AWAY, rb_intern("=="), 1, status)) {
332
+ tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_AWAY);
333
+ }
334
+ else if (rb_funcall(mTox_mUserStatus_BUSY, rb_intern("=="), 1, status)) {
335
+ tox_self_set_status(self_cdata->tox, TOX_USER_STATUS_BUSY);
336
+ }
337
+ else {
338
+ rb_raise(rb_eArgError, "invalid value for Tox::Client#status=");
339
+ }
340
+
341
+ return status;
342
+ }
343
+
242
344
  // Tox::Client#status_message
243
345
  VALUE mTox_cClient_status_message(const VALUE self)
244
346
  {
@@ -278,13 +380,47 @@ VALUE mTox_cClient_status_message_EQUALS(const VALUE self, const VALUE status_me
278
380
  switch (error) {
279
381
  case TOX_ERR_SET_INFO_OK:
280
382
  break;
383
+ case TOX_ERR_SET_INFO_NULL:
384
+ rb_raise(mTox_eNullError, "tox_self_set_status_message() failed with TOX_ERR_SET_INFO_NULL");
385
+ case TOX_ERR_SET_INFO_TOO_LONG:
386
+ rb_raise(rb_eRuntimeError, "tox_self_set_status_message() failed with TOX_ERR_SET_INFO_TOO_LONG");
281
387
  default:
282
- rb_raise(rb_eRuntimeError, "tox_self_set_status_message() failed");
388
+ rb_raise(mTox_eUnknownError, "tox_self_set_status_message() failed");
389
+ }
390
+
391
+ if (!result) {
392
+ rb_raise(mTox_eUnknownError, "tox_self_set_status_message() failed");
283
393
  }
284
394
 
285
395
  return status_message;
286
396
  }
287
397
 
398
+ // Tox::Client#friend_numbers
399
+ VALUE mTox_cClient_friend_numbers(const VALUE self)
400
+ {
401
+ mTox_cClient_CDATA *self_cdata;
402
+
403
+ Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
404
+
405
+ const size_t friend_numbers_size = tox_self_get_friend_list_size(self_cdata->tox);
406
+
407
+ if (friend_numbers_size == 0) {
408
+ return rb_ary_new();
409
+ }
410
+
411
+ uint32_t friend_numbers[friend_numbers_size];
412
+
413
+ tox_self_get_friend_list(self_cdata->tox, friend_numbers);
414
+
415
+ VALUE friend_number_values[friend_numbers_size];
416
+
417
+ for (unsigned long i = 0; i < friend_numbers_size; ++i) {
418
+ friend_number_values[i] = LONG2NUM(friend_numbers[i]);
419
+ }
420
+
421
+ return rb_ary_new4(friend_numbers_size, friend_number_values);
422
+ }
423
+
288
424
  // Tox::Client#friend_add_norequest
289
425
  VALUE mTox_cClient_friend_add_norequest(const VALUE self, const VALUE public_key)
290
426
  {
@@ -294,7 +430,18 @@ VALUE mTox_cClient_friend_add_norequest(const VALUE self, const VALUE public_key
294
430
 
295
431
  Data_Get_Struct(self, mTox_cClient_CDATA, self_cdata);
296
432
 
297
- return LONG2FIX(tox_friend_add_norequest(self_cdata->tox, (uint8_t*)RSTRING_PTR(public_key), NULL));
433
+ const VALUE friend_number = LONG2FIX(tox_friend_add_norequest(
434
+ self_cdata->tox,
435
+ (uint8_t*)RSTRING_PTR(public_key),
436
+ NULL
437
+ ));
438
+
439
+ return rb_funcall(
440
+ self,
441
+ rb_intern("friend"),
442
+ 1,
443
+ friend_number
444
+ );
298
445
  }
299
446
 
300
447
  /*************************************************************
@@ -321,16 +468,33 @@ VALUE mTox_cClient_initialize_with(const VALUE self, const VALUE options)
321
468
  switch (error) {
322
469
  case TOX_ERR_NEW_OK:
323
470
  break;
471
+ case TOX_ERR_NEW_NULL:
472
+ rb_raise(mTox_eNullError, "tox_new() failed with TOX_ERR_NEW_NULL");
324
473
  case TOX_ERR_NEW_MALLOC:
325
- rb_raise(rb_eNoMemError, "tox_new() returned TOX_ERR_NEW_MALLOC");
474
+ rb_raise(rb_eNoMemError, "tox_new() failed with TOX_ERR_NEW_MALLOC");
475
+ case TOX_ERR_NEW_PORT_ALLOC:
476
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PORT_ALLOC");
477
+ case TOX_ERR_NEW_PROXY_BAD_TYPE:
478
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_TYPE");
479
+ case TOX_ERR_NEW_PROXY_BAD_HOST:
480
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_HOST");
481
+ case TOX_ERR_NEW_PROXY_BAD_PORT:
482
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_BAD_PORT");
483
+ case TOX_ERR_NEW_PROXY_NOT_FOUND:
484
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_PROXY_NOT_FOUND");
485
+ case TOX_ERR_NEW_LOAD_ENCRYPTED:
486
+ rb_raise(rb_eRuntimeError, "tox_new() failed with TOX_ERR_NEW_LOAD_ENCRYPTED");
326
487
  case TOX_ERR_NEW_LOAD_BAD_FORMAT:
327
- rb_raise(rb_const_get(mTox_cClient, rb_intern("BadSavedataError")), "savedata format is invalid");
488
+ rb_raise(mTox_cClient_eBadSavedataError, "tox_new() failed with TOX_ERR_NEW_LOAD_BAD_FORMAT");
328
489
  default:
329
- rb_raise(rb_eRuntimeError, "tox_new() failed");
490
+ rb_raise(mTox_eUnknownError, "tox_new() failed");
330
491
  }
331
492
 
332
- tox_callback_friend_request(self_cdata->tox, on_friend_request);
333
- tox_callback_friend_message(self_cdata->tox, on_friend_message);
493
+ tox_callback_friend_request (self_cdata->tox, on_friend_request);
494
+ tox_callback_friend_message (self_cdata->tox, on_friend_message);
495
+ tox_callback_friend_name (self_cdata->tox, on_friend_name_change);
496
+ tox_callback_friend_status_message(self_cdata->tox, on_friend_status_message_change);
497
+ tox_callback_friend_status (self_cdata->tox, on_friend_status_change);
334
498
 
335
499
  return self;
336
500
  }
@@ -346,11 +510,17 @@ VALUE mTox_cClient_run_loop(const VALUE self)
346
510
 
347
511
  delay.tv_sec = 0;
348
512
 
513
+ const VALUE ivar_on_iteration = rb_iv_get(self, "@on_iteration");
514
+
349
515
  while (rb_funcall(self, rb_intern("running?"), 0)) {
350
516
  delay.tv_nsec = tox_iteration_interval(self_cdata->tox) * 1000000;
351
517
  nanosleep(&delay, NULL);
352
518
 
353
519
  tox_iterate(self_cdata->tox, self);
520
+
521
+ if (Qnil != ivar_on_iteration) {
522
+ rb_funcall(ivar_on_iteration, rb_intern("call"), 0);
523
+ }
354
524
  }
355
525
 
356
526
  return self;
@@ -379,7 +549,7 @@ void on_friend_request(
379
549
  rb_intern("call"),
380
550
  2,
381
551
  rb_funcall(
382
- rb_const_get(mTox, rb_intern("PublicKey")),
552
+ mTox_cPublicKey,
383
553
  rb_intern("new"),
384
554
  1,
385
555
  rb_str_new(public_key, TOX_PUBLIC_KEY_SIZE)
@@ -417,3 +587,105 @@ void on_friend_message(
417
587
  rb_str_new((char*)text, length)
418
588
  );
419
589
  }
590
+
591
+ void on_friend_name_change(
592
+ Tox *const tox,
593
+ const uint32_t friend_number,
594
+ const uint8_t *const name,
595
+ const size_t length,
596
+ const VALUE self
597
+ )
598
+ {
599
+ const VALUE ivar_on_friend_name_change = rb_iv_get(self, "@on_friend_name_change");
600
+
601
+ if (Qnil == ivar_on_friend_name_change) {
602
+ return;
603
+ }
604
+
605
+ rb_funcall(
606
+ ivar_on_friend_name_change,
607
+ rb_intern("call"),
608
+ 2,
609
+ rb_funcall(
610
+ mTox_cFriend,
611
+ rb_intern("new"),
612
+ 2,
613
+ self,
614
+ LONG2FIX(friend_number)
615
+ ),
616
+ rb_str_new(name, length)
617
+ );
618
+ }
619
+
620
+ void on_friend_status_message_change(
621
+ Tox *const tox,
622
+ const uint32_t friend_number,
623
+ const uint8_t *const status_message,
624
+ size_t length,
625
+ const VALUE self
626
+ )
627
+ {
628
+ const VALUE ivar_on_friend_status_message_change = rb_iv_get(self, "@on_friend_status_message_change");
629
+
630
+ if (Qnil == ivar_on_friend_status_message_change) {
631
+ return;
632
+ }
633
+
634
+ rb_funcall(
635
+ ivar_on_friend_status_message_change,
636
+ rb_intern("call"),
637
+ 2,
638
+ rb_funcall(
639
+ mTox_cFriend,
640
+ rb_intern("new"),
641
+ 2,
642
+ self,
643
+ LONG2FIX(friend_number)
644
+ ),
645
+ rb_str_new(status_message, length)
646
+ );
647
+ }
648
+
649
+ void on_friend_status_change(
650
+ Tox *const tox,
651
+ const uint32_t friend_number,
652
+ const TOX_USER_STATUS status,
653
+ const VALUE self
654
+ )
655
+ {
656
+ const VALUE ivar_on_friend_status_change = rb_iv_get(self, "@on_friend_status_change");
657
+
658
+ if (Qnil == ivar_on_friend_status_change) {
659
+ return;
660
+ }
661
+
662
+ VALUE status_value;
663
+
664
+ switch (status) {
665
+ case TOX_USER_STATUS_NONE:
666
+ status_value = mTox_mUserStatus_NONE;
667
+ break;
668
+ case TOX_USER_STATUS_AWAY:
669
+ status_value = mTox_mUserStatus_AWAY;
670
+ break;
671
+ case TOX_USER_STATUS_BUSY:
672
+ status_value = mTox_mUserStatus_BUSY;
673
+ break;
674
+ default:
675
+ return;
676
+ }
677
+
678
+ rb_funcall(
679
+ ivar_on_friend_status_change,
680
+ rb_intern("call"),
681
+ 2,
682
+ rb_funcall(
683
+ mTox_cFriend,
684
+ rb_intern("new"),
685
+ 2,
686
+ self,
687
+ LONG2FIX(friend_number)
688
+ ),
689
+ status_value
690
+ );
691
+ }