from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
from pypdevs.simulator import Simulator
from pypdevs.infinity import INFINITY

class MyAtomicDSModel(AtomicDEVS):
    def __init__(self, my_id):
        AtomicDEVS.__init__(self, "MyAtomicDSModel[%s]" % my_id)
        self.my_id = my_id
        self.ctr = 0
        self.remaining = 1
        self.out_port = self.addOutPort("out_port")
        self.in_port = self.addInPort("in_port")
    
    def set_sim(self, sim):
        self.sim = sim

    def timeAdvance(self):
        return self.remaining
    
    def outputFnc(self):
        print 'MyAtomicDSModel(%s) outputFnc' % id(self)
        return {self.out_port: "MyMessage"}
        
    def intTransition(self):
        self.ctr += 1
        self.remaining = 1
        print 'MyAtomicDSModel(%s:%s) intTransition' % (id(self), self.ctr)
        
    def extTransition(self, inputs):
        self.remaining -= self.elapsed
        print 'MyAtomicDSModel(%s) extTransition' % id(self)
        self.ctr += 1
    
    def modelTransition(self, state):
        print 'MyAtomicDSModel(%s) modelTransition %s' % (id(self), self.ctr)
        if self.ctr % 2 == 0:
            state[self.my_id] = "present"
            return True
        else:
            return False

class MyDSModel(CoupledDEVS):
    def __init__(self):
        CoupledDEVS.__init__(self, "CoupledDEVS")
        
        self.amodel = self.addSubModel(MyAtomicDSModel(0))
        self.bmodel = self.addSubModel(MyAtomicDSModel(1))
        self.connectPorts(self.amodel.out_port, self.bmodel.in_port)
        self.connectPorts(self.bmodel.out_port, self.amodel.in_port)
        
    def modelTransition(self, state):
        print 'MyDSModel modelTransition %s' % state

model = MyDSModel()
sim = Simulator(model)
model.amodel.set_sim(sim)
model.bmodel.set_sim(sim)
sim.setTerminationTime(10)
sim.setDSDEVS(True)
sim.setClassicDEVS(True)
sim.simulate()