Replies: 10 comments
-
Home page
Welcome to the Molecule wiki! Introduction Molecule provides a way to describe a software application as a component group. Molecule is a Light-weight implementation of the Corba Component Model (LCCM). It allows for the specification of components as in the Corba standard: provided and used services, produced and consumed events. However, Molecule components are only specified and instantiated locally. They are not exchanged nor shared through a standard object bus. Molecule supports completely transparent class augmentation into component (not necessary to add code manually), based on Traits. Installation Metacello new
baseline: 'Molecule';
repository: 'github://OpenSmock/Molecule';
load. Deprecated version of Molecule (1.1.x) for Pharo 6 and 7 is also available here. Principles Similarly to the LCCM, a component’s business contract is exposed through its component Type. The Type specifies what a component has to offer to other components (namely, provided services and produced events) and what that component requires from other components (namely, used services and consumed events). Thus, the main role of the Type is to implement the services that the component provides (Provided Services) and that are callable by other components. Other components use this interface through their Used Services interface. Produced Events represent the receivable events interface of the component. Other components listen to this interface through their Consumed Events interface. They subscribe and unsubscribe to their event interface to start and stop receiving notifications. Parameters are used to control the component’s state. Parameters can only be used once at the component’s initialization. The light-weight CCM model does not define Parameters, but instead allows direct access to public attributes. We introduced the Provided Parameters as an interface to explicitly define how the state of a component can be initialized. Other components use this interface through their Used Parameters interface. A Molecule component definition is based on Traits. The Type, as well as the services, the events and the parameters are all defined as Traits. A Molecule component is an instance of a standard class which uses Molecule traits. Two ways to implement a Component The direct benefit of this approach is that it's possible for any existing class to become a component. This existing class is then turned as (or augmented as) a component, and becomes usable in a Molecule component application while remaining fully compatible with non-component applications. Run-time management of Components Components' life-cycle and states The activity of a component depends on contextual constraints such as the availability of a resource, the physical state of hardware elements, etc. To manage consumed resources accordingly, the life-cycle of a component has four possible states: Initialized, Activated, Passivated and Removed. After its initialization, a component can switch from an Activated state to a Passivated state and conversely. When the life-cycle of a component is over, then it switches to the Removed state. Let us detail every state of a component's life-cycle. When a component is switched to the Initialized state, it's configured through its provided parameters. If a component depends on another component through its interfaces (used services, consumed events or used parameters), these components are associated during this state. The Activated state is the nominal state of a component. When a component is switched to this state, it subscribes to each consumed event that is produced by the components that have been associated with it during the Initialized state. After this subscription step, the component is able to receive and react accordingly to any of its consumed events. When a component is paused, it switches to the Passivated state. Then, the component unsubscribes to its subscribed events and all its required resources are set in waiting mode. As an example, a hardware can be set in its sleeping mode, it can also be asked to free its Graphics Processing Unit memory. The idea behind this state is to avoid consuming resources if not needed, and to be able to switch back as quickly as possible to the Activated state. The terminal state of a component is the Removed state. When a component switches to this state, all of its resources are released. The ComponentManager removes that component from its list of alive components. Let us illustrate the use of these states with the example of a GUI window handled as a component. First, the window is instantiated by the component. Then the component state switches to Initialized. When the window is displayed on the desktop, the component’s state switches to Activated. When the window is reduced and its icon is stored into a task-bar, then the component switches to the Passivated state. As the window is only reduced, it can be re-opened very quickly. Finally, when the user closes the window, the component is first switched to Passivated, then to the Removed state. Tutorials section External links |
Beta Was this translation helpful? Give feedback.
-
Create a new Molecule Component
There are two ways to create a new Molecule Component :
Create a new Component from scratch Re-using an existing Class into a Component With Molecule, we reuse any existing Class by augmenting that Class with Component behavior. This Class becomes seamlessly usable as a Component in a Molecule architecture. We must use the Molecule Component interface Adding Component contract with a Component Type The component type implements the component contract (used/provided services, consumed/produced events, used/provided parameters). The type is implemented through a Trait. Instantiating a Component
It's also possible to create a component with a name by using the following syntax: add img |
Beta Was this translation helpful? Give feedback.
-
New tutorials start here (order isn't definitive) |
Beta Was this translation helpful? Give feedback.
-
Creating Services To link Services to a component, you first need to place yourself in the class side of a Type Trait then look for the methods that make its contract.
Once you're in these methods, add between the already present curly brackets Since services are not directly linked to a variable, you can edit their name independently from the variables (and execute operations on them). The global syntax to get a Service's value is add img |
Beta Was this translation helpful? Give feedback.
-
Creating Events To link Events to a component, you first need to place yourself in the class side of a Type Trait then look for the methods that make its contract.
In the case of multiple events, you just need to separate the different Event Traits by a dot. For Events in particular, you will need to subscribe to the class specified in Notifiers will be needed to trigger an event and are explained in this Creating Notifiers tutorial. add img |
Beta Was this translation helpful? Give feedback.
-
Connecting two components In the first component's contract, you will need to specify which events and services are respectively produced and provided. In the second component's contract, you will need to specify which events and services are respectively consumed and used. For listening to a component for events, see the last part of Creating Events tutorial. A component can receive events/services and emit other events/services by specifying them for a component without any conflict, since they're different parts of its contract. add img |
Beta Was this translation helpful? Give feedback.
-
Creating Parameters to complete add img |
Beta Was this translation helpful? Give feedback.
-
Creating Notifiers To trigger an event, the syntax follows this template: add img |
Beta Was this translation helpful? Give feedback.
-
Creating Producers For multiple Producers (multiple named launched components of the same Type), the syntax is to review, not enough detail add img |
Beta Was this translation helpful? Give feedback.
-
Facilitating tests A script could look like You also need to verify the order of components starting since a component that listens to another needs to be started before the latter one. Otherwise, the event will be sent wthout any component listening to it, rendering it meaningless. This test space can be useful for switching components on the fly, stopping a component to start another having a different Type (make sure that they have a different name or that the current launched component is stopped before the other of the same Type is launched). To call another script, you simply have to call it like a regular function with |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
All reactions