123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <class name="MvKController">
- <relationships>
- <association name="to_mvs" class="HTTPClient" min="1" max="1"/>
- <association name="to_mvi" class="Server" min="1" max="1"/>
- <association name="users" class="UserStatechart"/>
- <association name="executor" class="Executor" min="1" max="1"/>
- </relationships>
- <constructor>
- <parameter name="params"/>
- <body>
- <![CDATA[
- self.users = []
- self.user_statecharts = {"__hierarchy": None}
- self.input_queue = []
- self.user_queue = {}
- self.source = None
- self.root = None
- self.params = params
- ]]>
- </body>
- </constructor>
- <scxml initial="init_server">
- <state id="init_server">
- <onentry>
- <raise scope="cd" event="create_instance">
- <parameter expr="'to_mvi'"/>
- <parameter expr="'Server'"/>
- <parameter expr="''"/>
- <parameter expr="8001"/>
- </raise>
- </onentry>
- <transition event="instance_created" target="../init_executor">
- <parameter name="instancename"/>
- <raise scope="cd" event="start_instance">
- <parameter expr="instancename"/>
- </raise>
- </transition>
- </state>
- <state id="init_executor">
- <onentry>
- <raise scope="cd" event="create_instance">
- <parameter expr="'executor'"/>
- <parameter expr="'Executor'"/>
- </raise>
- </onentry>
- <transition event="instance_created" target="../read_root">
- <parameter name="instancename"/>
- <raise scope="cd" event="start_instance">
- <parameter expr="instancename"/>
- </raise>
- </transition>
- </state>
- <state id="read_root">
- <onentry>
- <raise event="raw_exec" scope="narrow" target="'executor'">
- <parameter expr="[['RR', []]]"/>
- <parameter expr="'parent'"/>
- </raise>
- </onentry>
- <transition event="raw_exec_reply" target="../running">
- <parameter name="data"/>
- <script>
- self.root = data[0][0]
- </script>
- </transition>
- </state>
- <parallel id="running">
- <state id="wait_for_requests">
- <state id="wait">
- <transition event="from_mvi" target=".">
- <parameter name="source"/>
- <parameter name="data"/>
- <script>
- # No JSON encoding necessary, as it is not complex
- try:
- print 'from_mvi %s' % data
- args = None
- if data["op"] == "set_input":
- if "value" in data:
- value = [json.loads(data["value"])]
- else:
- value = json.loads(data["data"])
- args = value
- self.input_queue.append((source, data["op"], args, data["username"]))
- except ValueError:
- print("Error when deserializing request: " + str(data))
- raise
- </script>
- </transition>
- </state>
- </state>
- <state id="push" initial="wait">
- <state id="wait">
- <transition cond="self.input_queue and self.input_queue[0][3] in self.user_statecharts" target="../process"/>
- <!-- User is not yet detected, so stall this message -->
- <transition cond="self.input_queue and self.input_queue[0][3] not in self.user_statecharts" target=".">
- <!-- Move it to the back of the list, so we can process other users first -->
- <script>
- self.user_queue.setdefault(self.input_queue[0][3], []).append(self.input_queue.pop(0))
- </script>
- <!-- Force a refresh too -->
- <raise event="force_user_refresh"/>
- </transition>
- </state>
- <state id="process">
- <transition cond="self.input_queue[0][1] == 'set_input'" target="../wait">
- <script>
- source, op, args, username = self.input_queue.pop(0)
- </script>
- <raise event="set_input" scope="narrow" target="self.user_statecharts[username]">
- <parameter expr="source"/>
- <parameter expr="args"/>
- </raise>
- </transition>
- <transition cond="self.input_queue[0][1] == 'get_output'" target="../wait">
- <script>
- source, op, args, username = self.input_queue.pop(0)
- </script>
- <raise event="get_output" scope="narrow" target="self.user_statecharts[username]">
- <parameter expr="source"/>
- <parameter expr="args"/>
- </raise>
- </transition>
- </state>
- </state>
- <state id="find_users" initial="get_all_links">
- <state id="get_all_links">
- <onentry>
- <raise event="raw_exec" scope="narrow" target="'executor'">
- <parameter expr="[['RDK', [self.root]]]"/>
- <parameter expr="'parent'"/>
- </raise>
- </onentry>
- <transition event="raw_exec_reply" target="../retrieve_users">
- <parameter name="data"/>
- <script>
- print("Root: " + str(self.root))
- print("Users: " + str(data))
- self.users = data[0][0]
- </script>
- </transition>
- </state>
- <state id="retrieve_users">
- <transition cond="self.users" target="../got_usernames">
- <raise event="raw_exec" scope="narrow" target="'executor'">
- <parameter expr="[['RV', [user]] for user in self.users]"/>
- <parameter expr="'parent'"/>
- </raise>
- </transition>
- <transition cond="not self.users" target="../wait"/>
- </state>
- <state id="got_usernames">
- <transition event="raw_exec_reply" target="../process_users">
- <parameter name="data"/>
- <script>
- self.users = [v[0] for v in data if v[0] not in self.user_statecharts]
- print("EXPANDED Users: " + str(data))
- </script>
- </transition>
- </state>
- <state id="process_users">
- <transition cond="not self.users" target="../wait"/>
- <transition cond="self.users" target="../creating_user">
- <raise event="create_instance" scope="cd">
- <parameter expr="'users'"/>
- <parameter expr="'UserStatechart'"/>
- <parameter expr="self.users[0]"/>
- </raise>
- </transition>
- </state>
- <state id="creating_user">
- <transition event="instance_created" target="../retrieve_users">
- <parameter name="instancename"/>
- <raise scope="cd" event="start_instance">
- <parameter expr="instancename"/>
- </raise>
- <raise scope="narrow" target="instancename" event="set_returnpath">
- <parameter expr="instancename"/>
- </raise>
- <script>
- print self.users[0]
- self.user_statecharts[self.users[0]] = instancename
- # Repush all this user's messages in the input queue
- self.input_queue.extend(self.user_queue.pop(self.users[0], []))
- self.users.pop(0)
- </script>
- </transition>
- </state>
- <state id="wait">
- <transition after="1.0" target="../get_all_links"/>
- <transition event="force_user_refresh" target="../get_all_links"/>
- </state>
- </state>
- </parallel>
- </scxml>
- </class>
|