0

here is a callback that is triggered every time a webrtc channel is opened

it is wrapped inside an impl named Peer.This contain a member variable of type i16 named num_channel_opened setted to a default of 0.

#[wasm_bindgen]
#[derive(Clone)]
struct Peer {
  num_channel_opened:i16
}

#[wasm_bindgen]
impl Peer {
  /* ... */
  fn new() {
    /* ... */
  }

  fn on_channel_opened () {
    /* ... */
  }
  /* ... */
}

here is my listener function

  fn on_channel_opened ( &self ) -> Closure<dyn FnMut(Event)>{
    let mut selfCell = Rc::new(RefCell::new( self.clone() ) );
    Closure::wrap( Box::new( move |ev: Event |  {
        let mut selfClone = selfCell.clone();
        (*selfClone).borrow_mut().num_channels_opened += 1;
        console_warn!("number of channel opened {:?}", ( *selfClone ).borrow().num_channels_opened );
        }
    }) as Box<dyn FnMut(Event)> )
  }

I have three channels and I was hoping that the variable would get incremented on each channel opening. Instead of that I always get 1 the previous value is not persistent. How can I make this value persistent. The equivalent in javascript would be

class Peer {
  num_channels_opened = 0;
  peer;

  constructor () {
    this.peer = new RTCPeerConnection();
    //create channels
    //wait to receive remote channels
    //attach on_channel_opened to received remote channels
        //this would look like
        //channel.onopen = this.on_channel_opened;
  }

  on_channel_opened = () => {
    this.num_channel_opened++;
    console.log( this.num_channel_opened ) // 1, 2, 3...N channels
  }
}
JSmith
  • 4,519
  • 4
  • 29
  • 45

1 Answers1

1

You're cloning self in on_channel_opened and then modifying the clone instead of the original. In order to behave like javascript, you should use Rc everywhere, e.g.:

struct Peer {
   num_channel_opened: i16,
}

impl Peer {
   
   fn new() -> Rc<RefCell<Peer>> {
      Rc::new(RefCell::new (Peer { num_channel_opened: 1, }))
   }

   fn on_channel_opened ( self, this: Rc<RefCell<Self>>) -> Closure<dyn FnMut(Event)> {
      let that = Rc::clone (&this);
      Closure::wrap (Box::new (move |ev: Event|  {
         that.borrow_mut().num_channels_opened += 1;
         console_warn!("number of channel opened {:?}", that.borrow().num_channels_opened);
      }
   }) as Box<dyn FnMut(Event)>)
}
JSmith
  • 4,519
  • 4
  • 29
  • 45
Jmb
  • 18,893
  • 2
  • 28
  • 55
  • I will try that and get back to you. Thank you for your answer. – JSmith Apr 23 '23 at 05:31
  • @cafce25 Thank you fro the precision.The overall idea of the current answer seems appealing but I'm having trouble to convert the returned `Rc:RefCell` to a wasm_bindgen compatible value.any ideas.I'll make an edit on the question to add the macro.Thank you in advance. – JSmith Apr 23 '23 at 05:57
  • How can I reference self to a `Rc` without passing it as an external argument. I guess I'll always need to do something like `on_channel_opened(rc_self)`?!Am I right? – JSmith Apr 23 '23 at 06:27
  • you've pointed me in the good direction.Can I edit your answer to mark it as answered? – JSmith Apr 23 '23 at 06:46
  • @JSmith sure, go ahead – Jmb Apr 23 '23 at 07:23
  • @Jmb just another question real quick.Do you have any clues How I could retrieve the result in javascript, looks like I cannot retrieve a Rc or RefCell so my states are unsynced between js and Rust?Thanks for your time – JSmith Apr 23 '23 at 07:56