diff --git a/src/runtime2/component/component.rs b/src/runtime2/component/component.rs index 73ee7e4cc4ce5f8a272539990fa31a4ae357d8b0..0937682ed8884505429fe1e2ac2ef4671afe234f 100644 --- a/src/runtime2/component/component.rs +++ b/src/runtime2/component/component.rs @@ -1,6 +1,7 @@ -use crate::protocol::eval::EvalError; +use crate::protocol::eval::*; +use crate::protocol::*; use crate::runtime2::*; -use super::CompCtx; +use super::{CompCtx, CompPDL}; pub enum CompScheduling { Immediate, @@ -22,4 +23,30 @@ pub(crate) trait Component { /// Called if the component's routine should be executed. The return value /// can be used to indicate when the routine should be run again. fn run(&mut self, sched_ctx: &mut SchedulerCtx, comp_ctx: &mut CompCtx) -> Result; +} + +/// Creates a new component based on its definition. Meaning that if it is a +/// user-defined component then we set up the PDL code state. Otherwise we +/// construct a custom component. This does NOT take care of port and message +/// management. +pub(crate) fn create_component( + protocol: &ProtocolDescription, + definition_id: ProcedureDefinitionId, type_id: TypeId, + arguments: ValueGroup, num_ports: usize +) -> Box { + let definition = &protocol.heap[definition_id]; + debug_assert!(definition.kind == ProcedureKind::Primitive || definition.kind == ProcedureKind::Composite); + + if definition.source.is_builtin() { + // Builtin component + todo!("implement") + } else { + // User-defined component + let prompt = Prompt::new( + &protocol.types, &protocol.heap, + definition_id, type_id, arguments + ); + let component = CompPDL::new(prompt, num_ports); + return Box::new(component); + } } \ No newline at end of file