list of dots Digital Research Alliance of Canada logo  NSERC logo  University of Ottawa logo / UniversitĂ© d'Ottawa

User Manual    [Previous]   [Next]   

State-Dependent Methods

A state-dependent method is a partial method body declared within a state machine. Each of these partial definitions are subsequently aggregated into a single function within the Umple class as switch cases.

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.

Example

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.
// @@@skipcppcompile

      

Load the above code into UmpleOnline

 

Another Example

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.
// @@@skipcppcompile

      

Load the above code into UmpleOnline

 

Syntax


// Methods: The code in concrete methods is passed to the base language
// See user manual page MethodDefinition
concreteMethodDeclaration : [=modifier:public|protected|private]? [=static]? [=synchronized]? [=queued]? [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? [[methodBody]]
    | [=modifier:public|protected]? [=abstract] [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? ;