Experimental "peer to peer" modular programming concept

new topic     » topic index » view thread      » older message » newer message

Working on large GUI applications over the years, i have always been frustrated with how difficult it can be to organize all the parts of an application, especially since there is usually special data processing mixed with user interface code and various states or views the application may switch to. Usually, i end up with a small main file and 2 or 3 huge files, with GUI and data processing code mixed together, and a few lower-level libraries that perform specific generic functions. It is difficult to define clear "modules" or some sort of hierarchy when different parts of the program need to communicate with other parts, so i end up with a make-shift message queue system that is difficult to maintain across different parts of 2 or 3 large files. Part of the problem is the way include files work assumes that an included file is somehow lower in the hierarchy, and there is no clear way to make different parts of the program "peers" or independent "modules" without some other library to include them and control them.

Does anyone else have this problem?

Possible solution: I have created an experimental "sync.e" library that allows any include file in a program to send messages without being aware of where they get received. Each file has to include "sync.e and subscribe to a "sync group", specifying a routine_id that will process sync messages. If any subscriber of the group calls sync:send(), all other subscribers' handler routines will be called by the sync.e library. Each library can then process incoming messages without a queue or tasks required.

No processing queue or controlling hierarchy is required. A main file can include many small .e files and not have to do anything with them once everything is initialized. Each .e file can be independent of the others, handling it's little part of the whole program. For example, if i create a file browser application, separate .e files could handle their own parts of a GUI: a folder tree, a location bar, a file list, etc. If any part of the gui is changed by the user, a message is sent out, and the other files process what they need to and update their part of the gui. Another file that is responsible for manipulating files could receive a message to do something with a specified file (open, delete, copy, move, rename, etc.) This makes the program very modular and easier to add or remove features later.

This is still experimental and theoretical, but i am currently rewriting all the source code of RedyCode to test this concept.

Here's the experimental sync.e library. Any thoughts? Let's discuss.

sequence 
gNames = {}, 
gSubscriberNames = {}, 
gSubscriberRids = {} 
 
atom debugRid = 0 
 
 
public procedure send(sequence groupname, sequence subscribername, sequence msgname, object msgdata) 
--sync data with other subscribers in group 
    atom idx = find(groupname, gNames) 
    if idx > 0 then 
        for s = 1 to length(gSubscriberNames[idx]) do 
            if not equal(gSubscriberNames[idx][s], subscribername) then 
                if gSubscriberRids[idx][s] > 0 then 
                    call_proc(gSubscriberRids[idx][s], {groupname, subscribername, msgname, msgdata}) 
                end if 
            end if  
        end for 
    end if 
    if debugRid > 0 then 
        call_proc(debugRid, {groupname, subscribername, msgname, msgdata}) 
    end if 
end procedure 
 
 
public procedure subscribe(sequence groupname, sequence subscribername, atom msghandlerid) 
--subscribe to a sync group to receive sync updates 
    atom idx = find(groupname, gNames) 
    if idx > 0 then 
        gSubscriberNames[idx] &= {subscribername} 
        gSubscriberRids[idx] &= {msghandlerid} 
    else 
        gNames &= {groupname} 
        gSubscriberNames &= {{subscribername}} 
        gSubscriberRids &= {{msghandlerid}} 
    end if 
end procedure 
 
 
public procedure unsubscribe(sequence groupname, sequence subscribername) 
--unsubscribe from a sync group 
    atom idx = find(groupname, gNames) 
    if idx > 0 then 
        gNames = remove(gNames, idx) 
        gSubscriberNames = remove(gSubscriberNames, idx) 
        gSubscriberRids = remove(gSubscriberRids, idx) 
    end if 
end procedure 
 
 
public function list_groups() 
--list all sync groups 
    return gNames 
end function 
 
 
public function list_subscribers(sequence groupname) 
--list all subscribers in a specified sync group 
    atom idx = find(groupname, gNames) 
    if idx > 0 then 
        return gSubscriberNames[idx] 
    else 
        return 0 
    end if 
end function 
 
 
public procedure debug(atom debughandlerid) 
--register a routine to be called for debug messages 
    debugRid = debughandlerid 
end procedure 
new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu