Skip to content
Permalink
Browse files

Merge pull request #1398 from umple/issue_1351

State-dependent methods manual page and minor fix
  • Loading branch information...
TimLethbridge committed Oct 23, 2018
2 parents b846d76 + bb71d8a commit ff3f1073c4c1c49ae8ddadff1aa0ef20a0d0b7ae
@@ -75,7 +75,7 @@ class UmpleToJava {
customPostconditionCode = customPostconditionCode==null?"":customPostconditionCode;
if (customBeforeInjectionCode != null) {
addUncaughtExceptionVariables(realSb.toString().split("\\n").length,customBeforeInjectionCode,method.getName());
append(realSb, "\n{0}\n\n",GeneratorHelper.doIndent(customBeforeInjectionCode, " "));
append(realSb, "\n{0}\n",GeneratorHelper.doIndent(customBeforeInjectionCode, " "));
}
for (StateMachine sm : uniqueStateMachines)
{
@@ -221,6 +221,7 @@ class UmpleToJava {
for (Integer line : injectedLineNumbers) {
addUncaughtExceptionVariables(javaLength + line,customAfterInjectionCode, method.getName());
}
realSb.append("\n");
}
realSb.append(result);
append(realSb, "\n }\n");
@@ -274,15 +275,23 @@ class UmpleToJava {
if (body != null) {
append(builder, "\n{0} case {1}:", spacing, state.getName());
append(builder, "\n{0} {1}", spacing, body.getCodeblock().getCode());

// Implicit return for void
if (method.getType().equals("void")) {
append(builder, "\n{0} return;", spacing);
}
}
foundMethod = foundMethod || body != null;
}
}

String defaultTypeValue = gen.translate(method.getType());

// Output the default value and close brace
String defaultValue = (defaultBody == null) ?
String.format("return %s;", gen.translate(method.getType()))
: defaultBody;
defaultTypeValue.isEmpty() ?
"return;" : String.format("return %s;", defaultTypeValue) :
defaultBody;

append(builder, "\n{0} default:", spacing);
append(builder, "\n{0} {1}", spacing, defaultValue);
@@ -0,0 +1,21 @@
State-Dependent Methods
Methods
noreferences

@@description

<p>A state-dependent method is a partial method body declared within a <a href="BasicStateMachines.html">state machine<a>. Each of these partial definitions are subsequently aggregated into a single function within the Umple class as switch cases.</p>

<p>Note that while it is possible to define state-dependent methods across several state machines, the switched cases must be disjoint as the order within the cases is non-deterministic. Additionally, if a method of the same name and parameter set is provided in the same class then it is used as the default body for the function.</p>

@@syntax
[[concreteMethodDeclaration]]

@@example
@@source manualexamples/StateDependentMethods1.ump
@@endexample


@@example
@@source manualexamples/StateDependentMethods2.ump
@@endexample
@@ -44,9 +44,17 @@ public class X
switch(sm)
{
case init:
System.out.println("init");
System.out.println("init");
// line 30 "../stateDependentMethodDeclaration_2.ump"
System.out.println("...");
// END OF UMPLE AFTER INJECTION
return;
case going:
System.out.println("going");
System.out.println("going");
// line 30 "../stateDependentMethodDeclaration_2.ump"
System.out.println("...");
// END OF UMPLE AFTER INJECTION
return;
default:
System.out.println("not in a state");
}
@@ -0,0 +1,54 @@
class Mario {
Modifiers {
Small {
Normal {
void onHit() {
Die();
}
}

Invulnerable {
void onHit() {
// took no damage
}
}

void render() {
// draw small mario
}

EatMushroom -> Large;
Star -> Small.Invulnerable;
Die -> Dead;
}

Large {
Normal {
void onHit() {
Shrink();
}
}

Invulnerable {
void onHit() {
// took no damage
}
}

void render() {
// draw large mario
}

Shrink -> Small;
Star -> Large.Invulnerable;
}

Dead {
void render() {
// draw dying animation
}
}
}
}

// @@@skipphpcompile - See #1351. State-dependent methods are exclusive to Java generation.
@@ -0,0 +1,135 @@
external Thread {};

class Philosopher {

isA Thread;

Fork leftFork;
Fork rightFork;
String fname;
boolean isLeftHanded;

ForksInHand {
NoForks {
LookingForForks {
void eat(){
if (isLeftHanded) {
if (leftFork.take()) {
System.out.println(fname + " picked up first fork (left)");
LeftForkAcquired();
}
}
else if (rightFork.take()) {
System.out.println(fname + " picked up first fork (right)");
RightForkAcquired();
}
}
AteFood -> Idling;
}
Idling {
BellyGrumble -> LookingForForks;
}
LeftForkAcquired -> ForkInLeft;
RightForkAcquired -> ForkInRight;
}
ForkInLeft {
void eat() {
if (rightFork.take()) {
System.out.println(fname + " picked up second fork (right)");
RightForkAcquired();
}
}
RightForkAcquired -> ForkInBoth;
}

ForkInRight {
void eat() {
if (leftFork.take()) {
System.out.println(fname + " picked up second fork (left)");
LeftForkAcquired();
}
}
LeftForkAcquired -> ForkInBoth;
}

ForkInBoth {
void eat() {
System.out.println(fname + " is eating.");
try {
sleep(1000);
} catch (InterruptedException ex) { }
AteFood();
leftFork.putDown();
rightFork.putDown();
}
AteFood -> NoForks;
}
}

Belly {
IsHungry {
boolean isHungry() {
return true;
}
AteFood -> IsFull;
}
IsFull {
void think() {
System.out.println(fname + " is full. Now thinking...");
try {
sleep(1000);
} catch (InterruptedException ex) { }
BellyGrumble();
}
BellyGrumble -> IsHungry;
}
}

public void run() {
while (true) {
if (isHungry()) {
eat();
} else {
think();
}
}
}
}

class Fork {
depend java.util.concurrent.*;
Semaphore fork = new Semaphore(1);

boolean take() {
try {
Thread.sleep(100);
} catch (InterruptedException ex) { }
return fork.tryAcquire();
}

void putDown() {
fork.release();
}
}

class Main {
public static void main(String[] args){
String[] names = {"Plato", "Aristotle", "Cicero", "Confucius", "Eratosthenes"};
int k = names.length;
Philosopher[] philosophers = new Philosopher[k];
Fork[] forks = new Fork[k];

for (int i = 0; i < k; ++i) {
forks[i] = new Fork();
}

for (int i = 0; i< k; ++ i) {
Fork leftFork = forks[i];
Fork rightFork = forks[(i + 1) % forks.length];
philosophers[i] = new Philosopher(leftFork, rightFork, names[i], i == k - 1);
philosophers[i].start();
}
}
}

// @@@skipphpcompile - See #1351. State-dependent methods are exclusive to Java generation.

0 comments on commit ff3f107

Please sign in to comment.
You can’t perform that action at this time.