Component index
Section index

Component COROUTINE


Search

	/*
	    Sometime we need to solve two problems at once. One for example manages
	    complex parsing of some inputs and the other, the formatting
	    of the results.
	
	    Using object orientation is often a clean solution but tedious.
	    For example, you may have a PARSER object called once to do
	    some intialisation and later to retrieve one token at a time.
	
	    Then the formatting part is simply a loop processing each token
	    one after the other and performing various formatting (new line,
	    new page).
	
	    While a nice solution, the implementation of the PARSER object may
	    be more complex than needed. The object must remember all the state
	    in the parsing process and resume parsing each time a new token
	    is request.
	
	    The co-routine concept produce an elegant solution. Imagine two
	    sub-routine each performing its tasks using loops inside loops
	    and potentially recursion. Then deep down into some complex loop
	    and if statements, one piece of information is identified, suitable
	    for the other routine to process. The first routine then stops and
	    let the other process the information. Once this is done, the second
	    routine also stop and let the first resumes exactly where it was
	    before it stops.
	
	    This way the two routines are maintaining their complex state while
	    sharing information without needing extra logic to re-enter the
	    state (left when returning a token).
	
	    The TLMP COROUTINE object lets you define a co-routine acting
	    as a provider. The client code just iterate through the various
	    results produced by the co-routine.
	
	    The following example shows a co-routine reading a file and
	    spitting out each words in it. The parent then print the
	    words, 3 per lines.
	*/
	<mod>
	static void sample_coroutine0()
	{
	    glocal SSTRING val;
	
	    // Split a file into words
	    <obj COROUTINE co>();
	    <f run>
	        <call loadfile>("/tmp/file",true);
	        <f oneline>
	            int ret = 0;
	            const char *pt = line;
	            while (ret == 0 && *pt != '\0'){
	                while (isspace(*pt))pt++;
	                const char *start = pt;
	                while (*pt > ' ') pt++;
	                if (pt > start){
	                    glocal.val.setfrom (start,pt-start);
	                    ret = glocal.COROUTINE.yield();
	                }
	            }
	            return ret;
	        </f>
	        </call>
	    </f>
	    </obj>
	    // The main routine just iterate over the result set
	    while (!co.is_done()){
	        for (int i=0; i<3 && co.next(); i++){
	            printf ("  --%s--",glocal.val.get());
	        }
	        printf ("\n");
	    }
	}
	</mod>