# cPy - demonstrating cooperative multitasking with self made scheduler
# Provided by Anthony Vogelaar, Perth Scotland
# rev 0.10  2024-06-03  initial release

import  os;             os.system('clear')
import  time

# ============================== No tasks =============================

def demo1():
    t1 = time.time()
    t2 = time.time()
    t3 = time.time()
    while True:
        if time.time() - t1 >= 1:                # print '*' at 1 sec
            t1 = time.time() + 1
            print('*', end='', flush=True)
        if time.time() - t2 >= 2:                # print '.' at 2 sec
            t2 = time.time() + 2
            print('.', end='', flush=True)
        if time.time() - t3 >= 4:                # print '!' at 4 sec
            t3 = time.time() + 4
            print('!', end='', flush=True)

# ========================= Simple scheduler ==========================

# Seperating a large program into tasks
def demo2():

    # task 1, print '*' at 1 sec
    def task1(_local={}):
        if not 't_next' in _local or time.time() > _local['t_next']:
            _local['t_next'] = time.time() + 1
            print('*', end='', flush=True)


    # task 2, print '.' at 2 sec
    def task2(_local={}):
        if not 't_next' in _local or time.time() > _local['t_next']:
            _local['t_next'] = time.time() + 2
            print('.', end='', flush=True)


    # task 3, print '!' at 4 sec
    def task3(_local={}):
        if not 't_next' in _local or time.time() > _local['t_next']:
            _local['t_next'] = time.time() + 4
            print('!', end='', flush=True)


    def scheduler():
        tasks = [task1, task2, task3]
        while True:
            for task in tasks:
                task()


    scheduler()

# ============================ Scheduler ==============================

# Grouping tasks into classes
def demo3():

    # task, print ch at delay sec
    class Task:

        def __init__(self, ch, delay):
            self.ch     = ch
            self.delay  = delay
            self.t_next = time.time()


        def exe(self):
            if time.time() > self.t_next:
                self.t_next += self.delay
                print(self.ch, end='', flush=True)



    class Scheduler:

        def __init__(self):
            self.tasks = []


        def createTask(self, task):
            self.tasks.append(task)


        def exe(self):
            for task in self.tasks:
                task.exe()


    sched = Scheduler()
    sched.createTask(Task('*', 1))
    sched.createTask(Task('.', 2))
    sched.createTask(Task('!', 4))
    while True:
        sched.exe()
        time.sleep(0)

# ============================== Main =================================
            
# demo1()
# demo2()
demo3()

# =============================== End =================================
