Skip to content

Commit 7271e3a

Browse files
Merge pull request #4 from HammerMaximilian/development
development --> master 3.0.0
2 parents 8d610eb + b856b32 commit 7271e3a

File tree

797 files changed

+131779
-894
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

797 files changed

+131779
-894
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<img src="logo.png" width="300"/>
22

3-
# fUML Reference Implementation for *C++*
4-
This software is an open source reference implementation of the *Semantics of a Foundational Subset for Executable UML Models* (fUML)
5-
specification by the *Object Management Group* (OMG) (see [here](https://www.omg.org/spec/FUML/1.5/About-FUML)). This implementation is based on the Java fUML reference implementation developed by
3+
# fUML/PSCS Reference Implementation for *C++*
4+
This software is an open source reference implementation of the *Semantics of a Foundational Subset for Executable UML Models* (fUML) and *Precise Semantics of UML Composite Structures* (PSCS) specifications by the *Object Management Group* (OMG) (see [fUML](https://www.omg.org/spec/FUML/1.5/About-FUML) and [PSCS](https://www.omg.org/spec/PSCS/1.2/About-PSCS)). The fUML implementation of this software is based on the Java fUML reference implementation developed by
65
*Model Driven Solutions* (see [https://github.com/ModelDriven/fUML-Reference-Implementation](https://github.com/ModelDriven/fUML-Reference-Implementation))
76

87
## Licensing
@@ -45,7 +44,7 @@ For detailed information, please see the [User Guide](fUML-C++_User_Guide.pdf) s
4544
* The *usersrc* directory may contain arbitrary nested subdirectories
4645
* Add include directories for uml and fuml to your project
4746
* Add uml and fuml binaries to the linker options of your projects
48-
* Create a `<model-name>Environment` class by deriving from class `fuml::environment::Environment`
47+
* Create a `<model-name>Environment` class by deriving from class `fuml::environment::Environment` (or `pscs::environment::Environment` for PSCS-compatibility)
4948
* Create a `<model-name>Model` class by deriving from class `uml::environment::InMemoryModel` (this class will contain all of your model elements)
5049
* Create a class containing a main method and call `<model-name>Environment::Instance()->execute("<behavior-name>");` for each behavior you want to execute in subsequent order
5150
* Build project and run executable

fUML-CPP/examples/helloworld/.cproject

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/uml/src}&quot;"/>
8787
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/fuml/src}&quot;"/>
8888
</option>
89+
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.1404843445" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
90+
<listOptionValue builtIn="false" value="NDEBUG"/>
91+
</option>
8992
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1680379945" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
9093
</tool>
9194
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release.2122231047" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release">
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* CustomActivityExecution.cpp
3+
*
4+
* Created on: 07.05.2024
5+
* Author: Maximilian
6+
*/
7+
8+
#include <fuml/extensions/activities/CustomActivityExecution.h>
9+
10+
#include <fuml/semantics/commonbehavior/ExecutionQueue.h>
11+
12+
using namespace fuml::extensions::activities;
13+
14+
void CustomActivityExecution::execute()
15+
{
16+
// Custom addition to method ActivityExecution::execute.
17+
// This is used to always start ExecutionQueue if it is not started yet.
18+
19+
if(ExecutionQueue::notStarted())
20+
{
21+
ExecutionQueue::start(this->thisActivityExecutionPtr.lock());
22+
}
23+
else
24+
{
25+
ActivityExecution::execute();
26+
}
27+
28+
} // execute
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* CustomActivityExecution.h
3+
*
4+
* Created on: 07.05.2024
5+
* Author: Maximilian
6+
*/
7+
8+
#ifndef FUML_EXTENSIONS_ACTIVITIES_CUSTOMACTIVITYEXECUTION_H_
9+
#define FUML_EXTENSIONS_ACTIVITIES_CUSTOMACTIVITYEXECUTION_H_
10+
11+
#include <fuml/semantics/activities/ActivityExecution.h>
12+
13+
namespace fuml::extensions::activities
14+
{
15+
class CustomActivityExecution : public ActivityExecution
16+
{
17+
public:
18+
virtual ~CustomActivityExecution() = default;
19+
20+
virtual void execute() override;
21+
};
22+
} // CustomActivityExecution
23+
24+
#endif /* FUML_EXTENSIONS_ACTIVITIES_CUSTOMACTIVITYEXECUTION_H_ */

fUML-CPP/fuml/src/fuml/extensions/structuredclassifiers/SignatureBasedDispatchStrategy.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ BehaviorPtr SignatureBasedDispatchStrategy::getMethod(const Class_Ptr& type, con
9595
unsigned int sizeOfGeneral = general->size();
9696
while(method == nullptr && i <= sizeOfGeneral)
9797
{
98-
if(Class_Ptr baseClass = std::dynamic_pointer_cast<Class_>(general->at(i - 1)))
98+
if(Class_Ptr baseClass = AS(Class_, general->at(i - 1)))
9999
{
100100
method = this->getMethod(baseClass, operation);
101101
}
@@ -133,8 +133,8 @@ bool SignatureBasedDispatchStrategy::operationsMatch(const OperationPtr& ownedOp
133133
// NOTE: In this implementation, return types may be covariant classifiers.
134134
if (ownedParameter->type != baseParameter->type)
135135
{
136-
ClassifierPtr ownedOperationReturnType = std::dynamic_pointer_cast<Classifier>(ownedParameter->type);
137-
ClassifierPtr baseOperationReturnType = std::dynamic_pointer_cast<Classifier>(baseParameter->type);
136+
ClassifierPtr ownedOperationReturnType = AS(Classifier, ownedParameter->type);
137+
ClassifierPtr baseOperationReturnType = AS(Classifier, baseParameter->type);
138138

139139
matches = ownedOperationReturnType &&
140140
baseOperationReturnType &&
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* UMLConformingDispatchStrategy.cpp
3+
*
4+
* Created on: 07.03.2024
5+
* Author: Maximilian
6+
*/
7+
8+
#include <fuml/extensions/structuredclassifiers/UMLConformingDispatchStrategy.h>
9+
#include <uml/structuredclassifiers/Class_.h>
10+
#include <uml/classification/Operation.h>
11+
#include <uml/classification/Parameter.h>
12+
#include <uml/classification/ParameterDirectionKind.h>
13+
14+
using namespace fuml::extensions::structuredclassifiers;
15+
16+
bool UMLConformingDispatchStrategy::operationsMatch(const OperationPtr& ownedOperation, const OperationPtr& baseOperation)
17+
{
18+
// Check if the owned operation is equal to or overrides the base operation.
19+
// In this context, an owned operation overrides a base operation if:
20+
// - base operation is directly or indirectly redefined by owned operation
21+
// - the class that owns base operation is equal to or a base class of the class that owns owned operation
22+
// - they have the same number of owned parameters and for each parameter the following holds:
23+
// - direction, ordering and uniqueness are the same
24+
// - the corresponding types are covariant, contravariant or invariant
25+
// - the multiplicities are compatible depending on the parameter direction
26+
27+
bool matches = RedefinitionBasedDispatchStrategy::operationsMatch(ownedOperation, baseOperation);
28+
if (matches)
29+
{
30+
matches = this->isConsistentWith(ownedOperation, baseOperation);
31+
}
32+
33+
return matches;
34+
} // operationsMatch
35+
36+
bool UMLConformingDispatchStrategy::isConsistentWith(const OperationPtr& ownedOperation, const OperationPtr& baseOperation)
37+
{
38+
bool isConsistentWith = false;
39+
40+
isConsistentWith = this->conformsTo(ownedOperation->class_.lock(), baseOperation->class_.lock());
41+
42+
const ParameterListPtr& ownedOperationParameters = ownedOperation->ownedParameter;
43+
const ParameterListPtr& baseOperationParameters = baseOperation->ownedParameter;
44+
45+
unsigned int ownedOperationParametersSize = ownedOperationParameters->size();
46+
47+
isConsistentWith = isConsistentWith && (baseOperationParameters->size() == ownedOperationParametersSize);
48+
49+
for (unsigned int i = 0; isConsistentWith == true && i < ownedOperationParametersSize; i++)
50+
{
51+
const ParameterPtr& redefiningParameter = ownedOperationParameters->at(i);
52+
const ParameterPtr& redefinedParameter = baseOperationParameters->at(i);
53+
54+
isConsistentWith = isConsistentWith && (redefiningParameter->isUnique == redefinedParameter->isUnique);
55+
isConsistentWith = isConsistentWith && (redefiningParameter->isOrdered == redefinedParameter->isOrdered);
56+
isConsistentWith = isConsistentWith && (redefiningParameter->direction == redefinedParameter->direction);
57+
58+
ClassifierPtr redefiningParameterType = AS(Classifier, redefiningParameter->type);
59+
ClassifierPtr redefinedParameterType = AS(Classifier, redefinedParameter->type);
60+
isConsistentWith = isConsistentWith &&
61+
(
62+
this->conformsTo(redefiningParameterType, redefinedParameterType) ||
63+
this->conformsTo(redefinedParameterType, redefiningParameterType)
64+
);
65+
66+
if(redefinedParameter->direction == ParameterDirectionKind::inout)
67+
{
68+
isConsistentWith = isConsistentWith &&
69+
(
70+
this->compatibleWith(redefiningParameter, redefinedParameter) &&
71+
this->compatibleWith(redefinedParameter, redefiningParameter)
72+
);
73+
}
74+
else if (redefinedParameter->direction == ParameterDirectionKind::in)
75+
{
76+
isConsistentWith = isConsistentWith && this->compatibleWith(redefinedParameter, redefiningParameter);
77+
}
78+
else // i.e. if((redefinedParameter->direction == ParameterDirectionKind::out) || (redefinedParameter->direction == ParameterDirectionKind::return_))
79+
{
80+
isConsistentWith = isConsistentWith && this->compatibleWith(redefiningParameter, redefinedParameter);
81+
}
82+
}
83+
84+
return isConsistentWith;
85+
}
86+
87+
bool UMLConformingDispatchStrategy::conformsTo(const ClassifierPtr& type, const ClassifierPtr& otherType)
88+
{
89+
bool conformsTo = false;
90+
91+
if(type == otherType)
92+
{
93+
conformsTo = true;
94+
}
95+
else
96+
{
97+
unsigned int i = 1,
98+
generalSize = type->general->size();
99+
100+
while(!conformsTo && i <= generalSize)
101+
{
102+
const ClassifierPtr& general = type->general->at(i - 1);
103+
conformsTo = this->conformsTo(general, otherType);
104+
}
105+
}
106+
107+
return conformsTo;
108+
}
109+
110+
bool UMLConformingDispatchStrategy::compatibleWith(const MultiplicityElementPtr& self, const MultiplicityElementPtr& other)
111+
{
112+
bool compatibleWith = (other->lower <= self->lower) && ((other->upper == -1) || (self->upper <= other->upper));
113+
114+
return compatibleWith;
115+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* UMLConformingDispatchStrategy.h
3+
*
4+
* Created on: 07.03.2024
5+
* Author: maha6913
6+
*/
7+
8+
#ifndef FUML_EXTENSIONS_STRUCTUREDCLASSIFIERS_UMLCONFORMINGDISPATCHSTRATEGY_H_
9+
#define FUML_EXTENSIONS_STRUCTUREDCLASSIFIERS_UMLCONFORMINGDISPATCHSTRATEGY_H_
10+
11+
#include <fuml/semantics/structuredclassifiers/RedefinitionBasedDispatchStrategy.h>
12+
13+
namespace fuml::extensions::structuredclassifiers
14+
{
15+
class UMLConformingDispatchStrategy : public RedefinitionBasedDispatchStrategy
16+
{
17+
public:
18+
virtual bool operationsMatch(const OperationPtr&, const OperationPtr&) override;
19+
bool isConsistentWith(const OperationPtr&, const OperationPtr&);
20+
bool conformsTo(const ClassifierPtr&, const ClassifierPtr&);
21+
bool compatibleWith(const MultiplicityElementPtr&, const MultiplicityElementPtr&);
22+
}; // UMLConformingDispatchStrategy
23+
}
24+
25+
#endif /* FUML_EXTENSIONS_STRUCTUREDCLASSIFIERS_UMLCONFORMINGDISPATCHSTRATEGY_H_ */

fUML-CPP/fuml/src/fuml/semantics/actions/AcceptCallActionActivation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ void AcceptCallActionActivation::accept(const EventOccurrencePtr& eventOccurrenc
2020
// output pin. Then complete the acceptance of the event occurrence
2121
// as usual.
2222

23-
AcceptCallActionPtr action = std::dynamic_pointer_cast<AcceptCallAction>(this->node);
23+
AcceptCallActionPtr action = AS(AcceptCallAction, this->node);
2424
const OutputPinPtr& returnInformationPin = action->returnInformation;
2525

2626
ReturnInformationPtr returnInformation(new ReturnInformation());
27-
returnInformation->callEventOccurrence = std::dynamic_pointer_cast<CallEventOccurrence>(eventOccurrence);
27+
returnInformation->callEventOccurrence = AS(CallEventOccurrence, eventOccurrence);
2828

2929
this->putToken(returnInformationPin, returnInformation);
3030

fUML-CPP/fuml/src/fuml/semantics/actions/AcceptEventActionActivation.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void AcceptEventActionActivation::accept(const EventOccurrencePtr& eventOccurren
9797
// If there are no incoming edges, then re-register this accept event
9898
// action execution with the context object.
9999

100-
AcceptEventActionPtr action = std::dynamic_pointer_cast<AcceptEventAction>(this->node);
100+
AcceptEventActionPtr action = AS(AcceptEventAction, this->node);
101101
const OutputPinListPtr& resultPins = action->result;
102102

103103
fuml::Debug::println(
@@ -107,8 +107,7 @@ void AcceptEventActionActivation::accept(const EventOccurrencePtr& eventOccurren
107107
{
108108
if (!action->isUnmarshall)
109109
{
110-
SignalEventOccurrencePtr signalEventOccurrence = std::dynamic_pointer_cast<SignalEventOccurrence>(
111-
eventOccurrence);
110+
SignalEventOccurrencePtr signalEventOccurrence = AS(SignalEventOccurrence, eventOccurrence);
112111
if (signalEventOccurrence)
113112
{
114113
SignalInstancePtr signalInstance = signalEventOccurrence->signalInstance;
@@ -150,7 +149,7 @@ bool AcceptEventActionActivation::match(const EventOccurrencePtr& eventOccurrenc
150149
// Return true if the given event occurrence matches a trigger of the
151150
// accept event action of this activation.
152151

153-
AcceptEventActionPtr action = std::dynamic_pointer_cast<AcceptEventAction>(this->node);
152+
AcceptEventActionPtr action = AS(AcceptEventAction, this->node);
154153
const TriggerListPtr& triggers = action->trigger;
155154

156155
return eventOccurrence->matchAny(triggers);

0 commit comments

Comments
 (0)