<class name="Executor">
    <relationships>
        <association name="parent" class="MvKController" min="1" max="1"/>
    </relationships>
    <constructor>
        <body>
            <![CDATA[
            self.mvs = ModelverseState("../../bootstrap/bootstrap.m.gz")
            self.request_queue = [("", "", "load_primitives", [], None, False)]
            self.mvs.GC = True
            self.mvk = ModelverseKernel(self.mvs.read_root()[0])
            self.first = True
            self.mvs_response = None
            
            self.mvs_operations = {
                    "CN": self.mvs.create_node,
                    "CE": self.mvs.create_edge,
                    "CNV": self.mvs.create_nodevalue,
                    "CD": self.mvs.create_dict,

                    "RV": self.mvs.read_value,
                    "RO": self.mvs.read_outgoing,
                    "RI": self.mvs.read_incoming,
                    "RE": self.mvs.read_edge,
                    "RD": self.mvs.read_dict,
                    "RDN": self.mvs.read_dict_node,
                    "RDNE": self.mvs.read_dict_node_edge,
                    "RDE": self.mvs.read_dict_edge,
                    "RRD": self.mvs.read_reverse_dict,
                    "RR": self.mvs.read_root,
                    "RDK": self.mvs.read_dict_keys,

                    "DE": self.mvs.delete_edge,
                    "DN": self.mvs.delete_node,
                }

            ]]>
        </body>
    </constructor>

    <scxml initial="init">
        <parallel id="init">
            <state id="raw_exec">
                <state id="raw_exec">
                    <transition event="raw_exec" target=".">
                        <parameter name="operations"/>
                        <parameter name="source"/>
                        <script>
                            reply = [self.mvs_operations[command[0]](*command[1]) for command in operations]
                        </script>
                        <raise event="raw_exec_reply" scope="narrow" target="source">
                            <parameter expr="reply"/>
                        </raise>
                    </transition>
                    <transition event="get_mvk" target=".">
                        <parameter name="source"/>
                        <raise event="get_mvk_reply" scope="narrow" target="source">
                            <parameter expr="self.mvk"/>
                        </raise>
                    </transition>
                </state>
            </state>

            <state id="queue">
                <state id="queue">
                    <transition event="execute" target=".">
                        <parameter name="returnpath"/>
                        <parameter name="taskname"/>
                        <parameter name="operation"/>
                        <parameter name="params"/>
                        <parameter name="request_id"/>
                        <script>
                            self.request_queue.append((("/" + returnpath) if returnpath is not None else None, taskname, operation, params, request_id, True))
                        </script>
                    </transition>
                    <transition event="execute_debug" target=".">
                        <parameter name="returnpath"/>
                        <parameter name="taskname"/>
                        <parameter name="operation"/>
                        <parameter name="params"/>
                        <parameter name="request_id"/>
                        <script>
                            self.request_queue.append((("/" + returnpath) if returnpath is not None else None, taskname, operation, params, request_id, False))
                        </script>
                    </transition>
                </state>
            </state>

            <state id="execute" initial="idle">
                <state id="idle">
                    <transition cond="self.request_queue" target="../execution"/>
                </state>

                <state id="execution">
                    <onentry>
                        <script>
                            self.mvk.returnvalue = None
                            self.mvk.success = True
                            self.first = True

                            self.returnpath, taskname, operation, params, self.request_id, self.mvk.allow_compiled = self.request_queue.pop(0)
                            reply = None
                            commands = []
                            while 1:
                                commands = self.mvk.execute_yields(taskname, operation, params, reply)
                                if commands is None:
                                    break
                                reply = [self.mvs_operations[command[0]](*(command[1]))[0] for command in commands]
                        </script>
                    </onentry>

                    <transition cond="self.returnpath is not None" target="../idle">
                        <raise event="executed" scope="narrow" target="'parent' + self.returnpath">
                            <parameter expr="self.mvk.returnvalue"/>
                            <parameter expr="self.mvk.success"/>
                            <parameter expr="self.request_id"/>
                        </raise>
                    </transition>
                    <transition cond="self.returnpath is None" target="../idle"/>
                </state>
            </state>
        </parallel>
    </scxml>
</class>
