<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Great! thanks for your explanation. Makes sense to send messages
    instead of calling the state functions.<br>
    But what about style? Would you consider a solution as you describe
    good style? I didn't see it in other projects used this way.<br>
    <br>
    (Weird thing that good style is becoming such an issue to me since I
    started coding Erlang.)<br>
    <br>
    /Frans<br>
    <br>
    <div class="moz-cite-prefix">On 11/29/2015 02:59 PM, Jesper Louis
      Andersen wrote:<br>
    </div>
    <blockquote
cite="mid:CAGrdgiXhSY-PefaNydsHYwV4WqWBVeGG23phJ1Tor1UzTfzy6w@mail.gmail.com"
      type="cite">
      <div dir="ltr">One possible way is to message yourself. The
        following needs some help because it never loops over the
        unpacking, which it should. But surely you get the idea. The
        unpack function is now tasked with returning a list of decoded
        packets, not just the first one:
        <div><br>
        </div>
        <div><span style="font-size:12.8px">handle_info({tcp, Socket,
            RawData}, State_name, #state{buffer_state = BufState} =
            State) -></span></div>
        <div><span style="font-size:12.8px">    inet:setopts(Socket,
            [{active, once}]),</span></div>
        <div>    case unpack(BufState, RawData) of</div>
        <div>        {ok, Datas, BufState2} -></div>
        <div>            [gen_fsm:send_event(self(), {packet, D}) || D
          <- Datas],</div>
        <div>            {next_state, State_name, State#state {
          buffer_state = BufState2 }};</div>
        <div>        {more, BufState2} -></div>
        <div>            {next_state, State_name, State#state {
          buffer_state = BufState2 }}</div>
        <div>    end;</div>
        <div><br>
        </div>
        <div>Now, you can build two variants of the unpack/2 function.
          Rather than returning {more, State} you can simply return {ok,
          [], State} which eliminates the need for a separate
          'more-variant'. But some times, it is clever to return {more,
          NeededBytes, State} or something such in order to tell the
          layer how many bytes it needs before it can produce a new
          packet. In active mode, this allows you to expect the right
          number of bytes directly, which sometimes helps since you can
          move more or the load into the Erlang runtime.</div>
        <div><br>
        </div>
        <div>Now, the beauty is that the messages will sit in your own
          mailbox, and in order. So you just handle them as any other
          messages and move the state accordingly. And when you get new
          stuff in, your decode it in your handle_info block and inject
          it into the mailbox. It is a fairly modular solution as well:
          you effectively decoupled the TCP state from the rest of your
          code, so you can now freely move it out of the FSM should you
          prefer doing so. Vice versa, it also decouples the protocol
          decoding from your FSM state, so it can worry about the
          semantic impact of the protocol rather than the syntactic
          impact.</div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Sun, Nov 29, 2015 at 2:27 PM, Frans
          Schneider <span dir="ltr"><<a moz-do-not-send="true"
              href="mailto:schneider@xs4all.nl" target="_blank">schneider@xs4all.nl</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Dear list,<br>
            <br>
            I have a gen_fsm representing the tcp connection to a remote
            server with 6 states defined. Tcp data is handled by
            handle_info with active = once.Tcp packets can contain more
            than one commands/data items.<br>
            I would like to feed the data into the different FSM states
            in the same manner as with send_event() and not handle the
            different states in separate handle_info clauses for the
            different states or a massive handle_info clause with a huge
            case statement.<br>
            Question is, can I call the state clauses like this or do I
            brake OTP behavior?This is a client and blocking incoming
            data is not an issue.<br>
            <br>
            handle_info({tcp, Socket, Raw_data}, State_name,
            #state{buffer = Buffer} = State) -><br>
                {Datas, Buffer1} = unpack(<<Buffer/binary,
            Raw_data/binary>>),<br>
                lists:foldl(fun(Data, {StateName_in, State_in}) -><br>
                                    {next_state, StateName_out,
            State_out} = ?MODULE:StateName_in({recv, Data}, State_in),<br>
                        {StateName_out, State_out}<br>
                    end, {State_name, State}, Datas),<br>
                inet:setopts(Socket, [{active, once}]),<br>
                {next_state, active, State#state{buffer = Buffer1}};<br>
            <br>
            I can of course use a seperate process for handling the tcp
            stuff which makes the gen_fsm calls, but was just wondering
            if this could work as well.<br>
            <br>
            Thanks,<br>
            <br>
            /Frans<br>
            _______________________________________________<br>
            erlang-questions mailing list<br>
            <a moz-do-not-send="true"
              href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
            <a moz-do-not-send="true"
              href="http://erlang.org/mailman/listinfo/erlang-questions"
              rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
          </blockquote>
        </div>
        <br>
        <br clear="all">
        <div><br>
        </div>
        -- <br>
        <div class="gmail_signature">J.</div>
      </div>
    </blockquote>
    <br>
  </body>
</html>