I'm writing an application where I need to simulate the distribution of a resource such as electricity or gas among a large network of objects connected to each other in arbitrary ways. No physics need to be simulated. Just the flow of the units of resources when objects ask for them.
Consider the below diagram:
ObjA <---> ObjB <---> PwrA <---> ObjF
/\ ObjG
ObjE<---/ \---> PwrB
The Pwr objects can provide resource electricity when asked by the Obj objects. What I need to simulate here is that if ObjA needs 50 electricity it should send a message to all connected peers without caring who it goes to and should get the resource back only from peers it is connected to directly or indirectly.
I'm not simulating latency here or anything so transmission will be instant. From a programming point of view this is all entirely local within the application (No real networking or anything like that).
My challenge here is trying to program this in a modular and clean way. I'd like to avoid giant lists of locally connected nodes and large ifelse statements about how to deal with messages if possible.
I want to both achieve my goal and also learn something new. I've been reading articles and books and programming concepts for a few weeks now and one that I think might be a fantastic solution is C# Delegates.
I've done some prototyping and managed to setup objects with a MessageOut Delegate that other connected objects can subscribe to and listen for outgoing messages to deal with.
This works quite well but I have the following short-comings due to my in-experience with the concept:
- I don't know how to deal with circular references with message passing between connected objects: In the above diagram if ObjB broadcasts a message for electricity ObjA, PwrA, PwrB, ObjE will be notified, which will in turn all process and then notify ObjB. Which will in turn notify...etc. The way networking deals with this is to simply broadcast out all ports (Objects listening to a delegate) except the port that received it. How can I implement this with delegates? A flat broadcast won't work.
- Listening to a delegate effectively creates one-way communication. To implement two-way communication I'd need to have objects listen to outgoing messages for each other. But without a above to the above its another circular reference surely?