Skip to content

Commit

Permalink
Merge pull request #16 from onera/13-components-services
Browse files Browse the repository at this point in the history
Support non load/store components
  • Loading branch information
kevin-delmas authored Apr 12, 2024
2 parents 9112754 + 4d80ed0 commit fb96ea5
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,45 +82,63 @@ trait BaseHardwareNodeBuilder[T <: Hardware] extends PMLNodeBuilder[T] {
* (the name of the value enclosing the object)
* @example {{{
* val mySimpleTransporter = SimpleTransporter()
* }}}
* @param basics the set of basic services provided, if empty a default store and load services are added
* @param implicitName implicitly retrieved name from the declaration context
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* }}}
* @param basics the set of basic services provided, if empty a default store and load services are added
* @param withDefaultServices add default Load/Store services on creation
* @param implicitName implicitly retrieved name from the declaration context
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* @return the physical component
* @group publicConstructor
*/
def apply(basics: Set[Service] = Set.empty)(implicit implicitName: Name,
p: ProvideRelation[Hardware, Service],
owner: Owner): T =
apply(Symbol(implicitName.value), basics)
def apply(basics: Set[Service] = Set.empty, withDefaultServices: Boolean = true)(implicit implicitName: Name,
p: ProvideRelation[Hardware, Service],
owner: Owner): T =
apply(Symbol(implicitName.value), basics, withDefaultServices)

/**
* A physical component can be defined by its name and the basic services it provides
* A transporter is only defined by its name, so if the transporter already exists it will
* simply add the services provided by basics
*
* @param name the physical component name
* @param basics the set of basic services provided, if empty a default store and load services are added
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* @param name the physical component name
* @param basics the set of basic services provided, if empty a default store and load services are added
* @param withDefaultServices add default Load/Store services on creation
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* @return the physical component
* @group publicConstructor
*/
def apply(name: Symbol, basics: Set[Service])(implicit
p: ProvideRelation[Hardware, Service],
owner: Owner): T = {
def apply(name: Symbol, basics: Set[Service], withDefaultServices: Boolean)(implicit
p: ProvideRelation[Hardware, Service],
owner: Owner): T = {
val formattedName = formatName(name, owner)
val result = _memo.getOrElseUpdate((owner.s, formattedName), builder(formattedName))
val mutableBasic = collection.mutable.Set(basics.toSeq: _*)
if (!basics.exists(_.isInstanceOf[Load]))
if (withDefaultServices && !basics.exists(_.isInstanceOf[Load]))
mutableBasic += Load(Symbol(s"${formattedName.name}_load"))
if (!basics.exists(_.isInstanceOf[Store]))
if (withDefaultServices && !basics.exists(_.isInstanceOf[Store]))
mutableBasic += Store(Symbol(s"${formattedName.name}_store"))
p.add(result, mutableBasic)
result
}

/**
* A physical component can be defined by its name and the basic services it provides
*
* @param name the physical component name
* @param basics the set of basic services provided, if empty a default store and load services are added
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* @return the physical component
* @group publicConstructor
*/
def apply(name: Symbol, basics: Set[Service])(implicit
p: ProvideRelation[Hardware, Service],
owner: Owner): T = {
apply(name, basics, true)
}

/**
* A physical component can be defined only its name, the services will be defined by default
* @group publicConstructor
Expand All @@ -131,5 +149,20 @@ trait BaseHardwareNodeBuilder[T <: Hardware] extends PMLNodeBuilder[T] {
*/
def apply(name: Symbol)(implicit p: ProvideRelation[Hardware, Service],
owner: Owner): T =
apply(name, Set.empty)
apply(name, Set.empty, true)


/**
* A physical component can be defined only its name, the services will be defined by default
*
* @group publicConstructor
* @param name the physical component name
* @param withDefaultServices add default Load/Store services on creation
* @param p implicitly retrieved relation linking components to their provided services
* @param owner implicitly retrieved name of the platform
* @return the physical component
*/
def apply(name: Symbol, withDefaultServices: Boolean)(implicit p: ProvideRelation[Hardware, Service],
owner: Owner): T =
apply(name, Set.empty, withDefaultServices)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package onera.pmlanalyzer.pml.model.hardware

import onera.pmlanalyzer.pml.model.hardware.*
import onera.pmlanalyzer.pml.model.service.{Load, Store}
import onera.pmlanalyzer.pml.operators.*
import sourcecode.Name
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should

class HardwareTest extends AnyFlatSpec with should.Matchers {

/* Create a default platform to act as a container for components. */
object PlatformFixture extends Platform(Symbol("fixture"))

import PlatformFixture.*

"A Hardware" should "have default services" in {
val t: Target = Target()
val s: SimpleTransporter = SimpleTransporter()
val i: Initiator = Initiator()
val v: Virtualizer = Virtualizer()

for (h <- List(t, s, i, v)) {
exactly(1, h.services) shouldBe a [Load]
exactly(1, h.services) shouldBe a [Store]
h.services.size shouldBe 2
}
}

it should "have no services when specified" in {
val t: Target = Target(withDefaultServices = false)
val s: SimpleTransporter = SimpleTransporter(withDefaultServices = false)
val i: Initiator = Initiator(withDefaultServices = false)
val v: Virtualizer = Virtualizer(withDefaultServices = false)

for (h <- List(t, s, i, v)) {
h.services shouldBe empty
}
}

it should "have only specified services when specified" in {
val t: Target = Target(Set(Load("a"), Load("b")), withDefaultServices = false)
t.services.size shouldEqual 2
exactly(2, t.services) shouldBe a [Load]

val s = Target(Set(Store("a")), withDefaultServices = false)
s.services.size shouldEqual 1
exactly(1, s.services) shouldBe a[Store]

val i = Target(Set.empty, withDefaultServices = false)
i.services.size shouldEqual 0

val j = Target(Symbol("j"), withDefaultServices = false)
j.services.size shouldEqual 0
}

}

0 comments on commit fb96ea5

Please sign in to comment.