EDIT: If you can't be bothered to read this mammoth question, I've put a summary at the bottom.
I'm currently working on a sort of "framework" for a text adventure I am going to make in C#, as a coding excercise. In this framework, possible actions are defined by an "Interaction" class.
The potential "Actionable" objects are Inventory Items (stick, gun, sword), Environmental Items (wall, door, window) and Characters (people, animals). Each of these has a property which is a List of Interactions. At the moment, an Interaction is basically an "action/response" name value pair. When you type "smash window", it looks through all possible actionable items that the Player has available and matches the subject (in this case, "Window"). It then works out that the action is "Smash" and looks up in the List of Interactions on the Window (Environmental Item) to get a response for the Smash action and then writes it to the console.
That is all done, but here is the point that I am stuck:
An action has any number of potential consequences, which differs by each potential interaction. These are:
- Returns a response describing the result of the action by looking it up on the interaction, possibly with a second subject
EITHER
- The subject of the action (inventory item, environmental item or character) changes it's description
EG. "punch wall" could change the wall's description to describe a dent in the wall
OR
- The subject of the action is replaced by another item
EG. "smash bottle" results in "bottle" changing to "broken bottle" or "kill John" results in the character John being replaced by environmental item "John's corpse".
- Returns a response describing the preceeding change
EG. "The broken pieces of the bottle are scattered across the floor."
- An area's description is changed.
EG. "smash lightbulb" results in the room's description changing to describe a pitch black room
- Items are added/removed from the inventory or the environment
EG. "pick up bottle". You now have a bottle in your inventory, and the bottle is removed from the environment.
- The directions available for movement and the areas which they lead to are changed
EG. "unlock door with key" allows you to move East into another room
- The player is moved to a new area
EG. "go north" takes you to another area.
I need to somehow determine in a generic way which of these consequences a particular Interaction should invoke, and invoke them. An action could potentially use a number of these consequences, or just one.
For example, if the item is a Bottle:
"fill bottle with water" would first return a response describing that you have filled the bottle with water. It would then replace the "bottle" item with a "bottle of water" item.
That is two consequences, returning a response and replacing an item.
Say you were then to do "throw bottle of water at window". This is more complex. It would first return a response describing the events that take place, the bottle and the window would both smash and water would go everywhere. The bottle would be removed from the Player's inventory.
Next, the "bottle of water" would be replaced by the "broken bottle" and the "Window" would be replaced with "Broken window". The area description would also change to reflect this.
That is five consequences, returning a response, removing an item from inventory, replacing two items and updating the description of the current area.
As you can see, I need a generic way of being able to define on a per "Interaction" basis, what the consequences of that action will be and update other objects such as Item, Player (for inventory) and Area appropriately.
I'm sorry if this is unclear, and I will do my best to clarify if anyone has any questions.
EDIT: Is there a way for me to define a method on an Interaction that I can pass a number of methods to call (and their parameters) into? The initial response returned would be the default, mandatory consequence, and then there could be extra ones if specified.
For example, in the examples above, for the first interaction, "fill with water", I would tell it to return a response ("You have filled the bottle with water") and also to call a ReplaceItem method that would replace the "bottle" subject with a "bottle of water".
For the second interaction I would tell it to return a response ("The bottle hurtles through the air into..."), call RemoveFromInventory on the subject of the action, call UpdateStatus on the bottle ("the bottle is smashed") and the window ("the window is smashed") and call UpdateAreaDescription to change the current area's description ("You are standing in a room with a single window, the glass smashed to pieces").
Does that sound feasible? I'm trying to keep this as generic as possible, for the sake of all the different possible interactions.
EDIT 2: To clarify further, and to attempt to summarize the problem:
In my game, there are Actionable objects (a bottle, a wall, John). Each Actionable object has a list of
Interaction objects which describe how a player can interact with them. At the moment, an Interaction has a
"Name" property ("throw", "hit", "break") and returns a Response ("You throw the ").
The issue that I am trying to resolve is that an Interaction also needs to do a number of other things, varying
by each particular Interaction. Let's take the example of a glass bottle.
"throw glass bottle"
- A response is returned ("You threw the glass bottle.")
- The "Bottle", is removed from the Player's inventory.
- The is replaced with a new to reflect the change. ("Bottle" replaced with "Broken bottle").
- A second response is returned ("The pieces of the glass bottle are scattered on the floor").
"throw glass bottle at window"
- A response is returned ("You threw the glass bottle at the window.")
- The object "Bottle", is removed from the Player's inventory.
- The object is replaced with a new object to reflect the change. ("Bottle" replaced with "Broken bottle").
- A second, optional object is replaced with a new to reflect the change. ("Window" replaced with "Broken window").
- The "Description" property of the current Area is updated. ("You are standing in a room, with a single broken window.").
When I create the Interactions, how can I vary the additional actions that they perform, such as status changes
to the subject, or changes to the current Area's description?
If you need more examples of actions as above, let me know and I'll do a few more.
I think you should decide on a set number of verbs you will recognize, and then for each object decide which of those verbs it is capable of responding to.
Lock Object Recognized Verbs
Look
UseItemOn(Key001, LockPicks, Sledgehammer, ...)
Punch
That way you can generically handle verbs it doesn't recognize with a response like "You can't <verb> the <object>, and handle verbs it does recognize with events or whatever.
Edit
As per your comment I obviously just scanned your question (too long for me). Still, I don't see the difference, really. The point is, an object participates in an event. From the Bottle's perspective, it gets hit by a wall. From the Wall's perspective, it gets hit by a Bottle. Both objects will have a list of verbs to which they will respond in a certain way.
So if you plan for the wall to be responsive to ANY thrown object, then you'll need to add a Collide verb to its list. You'll want to specify which objects it should care about colliding with, and maybe for each of those, how it should respond to particular magnitudes of force, etc.
But the principle is the same. For any event there are a number of participants, and each participant will have certain stimuli it cares about, and for those stimuli it will have certain stimulus origin objects it cares about. If it's a verb it cares about but its origin is not an object it cares about, then it will effectively ignore it - or respond in some vanilla fashion.
The Bottle participates in a Collision with the Wall. The Bottle has in its Verbs list the Collide interaction type. It may have a single object with which it cares about colliding, or it may have a value of Any, or AnySolid, or whatever. There's a million ways to architect that. In any case, the Wall also participates and may also have in its Verbs list the Collide interaction type. But it only cares about colliding with the Sledgehammer object - or maybe AnySolid that has a Mass of 10 or greater...
You could also do this with interfaces. You can have an LootableObject that implements ICollidible interface, or whatever. When any ICollidible (say, a bottle) executes its Collide method it will need certain parameters: how fragile it is, how much force it received, whether the colliding object is something it cares about, etc.
It may be full of liquid so it would implement an IContainer interface which has a Spill method, and also an IConsumeable interface which has a Drink method. It may be a lock which implements an ILockable interface which has an Unlock(obj Key) method and a Pick(int PickSkill) method. Each of these methods can produce certain changes in state to the object and the other particpant(s) in the interaction. You can do this with Events if you like.
Basically you need to decide what level of (un)predictability you want and then compose a matrix of interactions (not necessarily physics, but any kind of interaction you plan to operate on - a lockpicking event, a collision event, a drinking event) that involve certain predictable properties.
All actions you have described consist of the following:
A verb (for example "throw")
an object (for example "bottle")
an optional additional parameter describing the action further (for example "at window")
How about modelling each actionable object as a class derived from a common ancestor and have that class handle the action itself. Something like
public interface IObjectBase
{
bool HandleAction(string verb,string [] params)
}
public class Bottle: IObjectBase
{
bool HandleAction(string verb,string [] params)
{
//analyze verb and params to look for appropriate actions
//handle action and return true if a match has been found
}
}
You've got two things: the player and the environment (you might also have other players).
Pass them both to each interaction:
interaction.ActOn(environment, player);
//eg:
smash.ActOn(currentRoom, hero);
Then let each interaction work out what to do:
environment.ReplaceObject("window", new Window("This window is broken. Watch out for the glass!");
player.Inventory.RemoveObject("bottle");
player.Hears("The window smashes. There is glass all over the floor! If only John McLane were here...").
With the usual checks to make sure that the environment actually has a window, the player has the bottle, etc.
player.Inventory.ReplaceObject("bottle", new BottleOfWater());
Interaction then becomes a common interface which you can attach to anything in the system, be it an environment, player, bottle, etc. You can probably work out some particular types of interaction which you can use to remove duplication, but I'd start simple and go from there.
See also Double Dispatch.
Hah, I'm working on something similar too.
I'm wondering if your framework ends up becoming a text-adventure creator which is what my project is.
My approach is to have a sort of API that consists of methods that represent all the most basic actions in the game. Then use 'scripts', which are basically methods containing a combination of these basic actions.
These basic actions may involve:
Print a message
Change an object's/room's description
"Lock" or "unlock" an object. This means that "examine belt" will say "You don't seen any belt here" UNTIL "examine corpse" has been performed to learn that "The corpse has a shiny belt around its waist".
Lock or unlock exits from a room
Move the player to some room
Add/Remove something from the player's inventory
Set/Change some game variable eg. "movedGlowingRock = true" or "numBedroomVisits = 13" etc.
and so on... This is what I currently have in mind.
These are all methods in maybe an API class and take various parameters as necessary.
Now, there are rooms. Rooms have objects. Certain commands are valid for each object. One simple way is to have each room object hold a Dictionary of allowed commands. Script is a delegate that points to your action script. Ponder this:
delegate void Script();
class GameObject
{
public Dictionary<string, Script> Scripts {get; set;}
public string Name {get; set;}
//etc...
}
And your scripts, stored in the relevant Room instance:
//In my project, I plan to have such an abstract class, and since it is a game _creator_, the app will generate a C# file that contains derived types containing info that users will specify using a GUI Editor.
abstract class Room
{
protected Dictionary<string, GameObject> objects;
public GameObject GetObject(string objName) {...//get relevant object from dictionary}
}
class FrontYard : Room
{
public FrontYard()
{
GameObject bottle;
bottle.Name = "Bottle";
bottle.Scripts["FillWithWater"] = Room1_Fill_Bottle_With_Water;
bottle.Scripts["ThrowAtWindow"] = Room1_Throw_Bottle_At_Window;
//etc...
}
void void Room1_Fill_Bottle_With_Water()
{
API.Print("You fill the bottle with water from the pond");
API.SetVar("bottleFull", "true");
}
void Room1_Throw_Bottle_At_Window()
{
API.Print("With all your might, you hurl the bottle at the house's window");
API.RemoveFromInventory("bottle");
API.UnlockExit("north");
API.SetVar("windowBroken", "true");
//etc...
}
}
All this is sort of a skeleton view of what I have in mind (there are many subtleties I have noted, but this is good enough for an example). Sadly I haven't even coded a single word for my project, hehe. Everything on paper.
So...all this might give you some ideas to tinker with for your own project. If something is unclear, ask. Hope I haven't strayed from your question or something.
I think I spent too much time typing all this >_>
EDIT:
PS: My skeleton example doesn't exactly show how to manage commands involving multiple game objects (This is just one of the many subtleties I hinted at). For stuff like "throw bottle at window", you need to think up how to manage such syntax, eg. a taste of my solution to this is to parse and discover what command is being issued... "throw GO at GO". Find out what the game objects are, then see if the current room has them. etc etc.
More importantly, this also prevents you from holding scripts inside a game object instance, since one command involves more than one game object. Probably better to store the Dictionary in the Room instance now.
(This is sort of where I am with my project.)
Pardon my ramblings... >_>
It seems like your issue is managing propagation of events. Microsoft handles this issue (for less colorful purposes) using the Observer pattern/events.
I think the combining the Observer and Mediator design patterns from Gamma,etc.'s book "Design Patterns" would be very helpful for you. The book has a sample ChangeManager class that might be helpful, but I have attached some other links that should serve you well.
One implementation suggestion I have would be to use a static or singleton class that acts as the mediator and also stores references to all of the actionable objects in active memory as well as all of the invoked actions. This class can process the algorithms to determine all of the responses and the chronological order of the responses from a given action. (If you consider that the collateral-effects of a primary action, A, can affect the consequences of that action, A, prior to the action completing, it would become evident that the proper chronological sequence is necessary, and must update before invoking each collateral action.)
Microsoft's article on the observer pattern: http://msdn.microsoft.com/en-us/library/ee817669.aspx
DoFactory on Mediator pattern (with UML diagrams): http://www.dofactory.com/Patterns/PatternMediator.aspx
DoFactory on Observer pattern (with UML diagrams): http://www.dofactory.com/Patterns/PatternObserver.aspx
IObserver interface documentation in .Net 4,
http://msdn.microsoft.com/en-us/library/dd783449.aspx
another article on the observer pattern. http://www.devx.com/cplus/Article/28013/1954
Interaction can be defined as "Verb + {List of Filters} + {List of Responses}"
For your "fill bottle with water" example, the Interaction would be:
Verb: Fill({"fill", "pour"})
List of Filters: Have(player, "bottle"), Have(currentRoom, "water tap")
List of Responses: Print("You filled the bottle with water"), Remove(player, "bottle"), Add(player, "bottle of water")
alternatively, List of Responses can be: SetAttribute(player.findInventory("bottle"), "fill", "water")
Then if you need to "throw bottle of water at windows":
Verb: Throw({"throw", "smash"})
List of Filters: Have(player, "bottle of water"), Have(currentRoom, "windows")
List of Responses: Print("The bottle smashed with the windows, and both of them are broken"), Remove(player, "bottle of water"), Add(curentRoom, "broken bottle"), Remove(currentRoom, "window"), Add(currentRoom, "broken window"), SetAttribute(currentRoom, "description", "There is water on the floor")
Upon entering a Room, the Framework will query all objects in the room for a list of valid Verbs, and enumerate them. When the player enters a command, the framework searches for a Verb that matches the command; then it will check the list of Filters, and if all of them is True, then iterate through the List of Responses to execute them in order.
The Responses would be a function object which implements the IResponse interface which has some constructors, and a IResponse.do() method. The Filters will be function object which implements the IFilter interface, again with some constructors, and IFilter.check() method returning a boolean. You can even have And(), Or(), and Not() filter to make more complex queries.
You can make things even more readable by having some convenience methods, a Player could have Player.have(Actionable) convenience method so you can write player.have("bottle of water"), which returns not the bottle object itself, but an IFilter object that will check whether the player have "bottle of water" when its .check() method is called. Basically, make the objects lazy.
Alright guys, here's how I handled it. It was the most generic way I could think of and I think it suits what I am trying to achieve.
I added an "Invoke()" method to the Interaction class, a new Interface called IActionResult which defined an "Initiate()" method, and a number of different ActionResult types for each possible consequence. I also added a List of ActionResults to an Interaction. The Invoke method would simply loop through all of the IActionResult objects and call the Initiate() method.
When you define an Interaction on an item, you would pass in a list of verbs for that Interaction and then add a number of ActionResult objects depending on the consequences of that Interaction.
I also added a GlobalActionReference, which would be updated each time an action is performed, and an ActionResult would have appropriate access to the objects it needs to update through this.
I really appreciate all of your suggestions, and I'm sorry if I wasn't clear with my question or my comments (or even this answer). Thanks for your help.
Related
As the question shows,
As we are using string functions like IsNullOrEmpty or IsNullOrWhiteSpace as the name of functions shows , these are doing more than one job , is it not a violation of SRP?
rather should it not be string.isValid(Enum typeofValidation) than using strategey pattern to choose the correct strategey to validate.
or is it perfectly OK to violate SRP in utilities class or static classes.
The SRP says that a function or class should have only one reason to change. What is a reason to change? A reason to change is a user who requests changes. So a class or function should have only one user who requests changes.
Now a function that does some calculations and then some formatting, has two different users that could request a change. One would request changes to the calculations and the other would request changes to the formatting. Since these users have different needs and will make their requests and different times, we'd like them to be served by different functions.
IsNullOrEmpty(String) is not likely to be serving two different users. The user who cares about null is likely the same user who cares about empty, so isNullOrEmpty does not violate the SRP.
In object-oriented programming, the single responsibility principle states that every object should have a single responsibility
You're describing methods: IsNullOrEmpty or IsNullOrWhiteSpace, which are also self-describing in what they do, they're not objects. string has a single responsibility - to be responsible for text strings!
Static helpers can perform many tasks if you choose: the whole point of the Single Responsibility principle is to ultimately make your code more maintainable and readable for future teams and yourself. As a comment says, don't overthink it. You're not designing the framework here but just consuming some parts of it that will clean your strings for you, and validate incoming data.
The SRP applies to classes, not methods. Still, it's a good idea to have methods that do one thing only. But you can't take that to extremes. For example, a console application would be fairly useless if its Main method could contain only one statement (and, if the statement is a method call, that method could also contain only one statement, etc., recursively).
Think about the implementation of IsNullOrEmpty:
static bool IsNullOrEmpty(string s)
{
return ReferenceEquals(s, null) || Equals(s, string.Empty);
}
So, yes, it's doing two things, but they're done in a single expression. If you go to the level of expressions, any boolean expression involving binary boolean operators could be said to be "doing more than one thing" because it is evaluating the truth of more than one condition.
If the names of the methods bother you because they imply too much activity for a single method, wrap them in your own methods with names that imply the evaluation of a single condition. For example:
static bool HasNoVisibleCharacters(string s) { return string.IsNullOrWhitespace(s); }
static bool HasNoCharacters(string s) { return string.IsNullOrEmpty(s); }
In response to your comment:
say I wrote the function like SerilizeAndValidate(ObjectToSerilizeAndValidate) , clearly this method / class , is doing 2 things , Serialize and Validation, clearly a violation , some time methods in a class leads to maintenance nightmare like above example of serialize and validation
Yes, you are right to be concerned about this, but again, you cannot literally have methods that do one thing only. Remember that different methods will deal with different levels of abstraction. You might have a very high-level method that calls SerializeAndValidate as part of a long sequence of actions. At that level of abstraction, it might be very reasonable to think of SerializeAndValidate as a single action.
Imagine writing a set of step-by-step instructions for an experienced user to open a file's "properties" dialogue:
Right-click the file
Choose "Properties"
Now imagine writing the same instructions for someone who's never used a mouse before:
Position the mouse pointer over the file's icon
Press and release the right mouse button
A menu appears. Position the mouse pointer over the word "Properties"
Press and release the left mouse button
When we write computer programs, we need to operate at both levels of abstraction. Or, rather, at any given time, we're operating at one level of abstraction or another, so as not to confuse ourselves. Furthermore, we rely on library code that operates at lower levels of abstraction still.
Methods also allow you to comply with the "do not repeat yourself" principle (often known as "DRY"). If you need to both serialize and validate objects in many parts of your application, you'd want to have a SerializeAndValidate method to reduce duplicative code. You'd be very well advised to implement the method as a simple convenience method:
void SerializeAndValidate(SomeClass obj)
{
Serialize(obj);
Validate(obj);
}
This allows you the convenience of calling one method, while preserving the separation of serialization logic from validation logic, which should make the program easier to maintain.
I don't see this as doing more than one thing. It is just making sure your string passes a required condition.
I need to transfer .NET objects (with hierarchy) over network (multiplayer game). To save bandwidth, I'd like to transfer only fields (and/or properties) that changes, so fields that won't change won't transfer.
I also need some mechanism to match proper objects on the other client side (global object identifier...something like object ID?)
I need some suggestions how to do it.
Would you use reflection? (performance is critical)
I also need mechanism to transfer IList deltas (added objects, removed objects).
How is MMO networking done, do they transfer whole objects?
(maybe my idea of per field transfer is stupid)
EDIT:
To make it clear: I've already got mechanism to track changes (lets say every field has property, setter adds field to some sort of list or dictionary, which contains changes - structure is not final now).
I don't know how to serialize this list and then deserialize it on other client. And mostly how to do it effectively and how to update proper objects.
There's about one hundred of objects, so I'm trying avoid situation when I would write special function for each object. Decorating fields or properties with attributes would be ok (for example to specify serializer, field id or something similar).
More about objects: Each object has 5 fields in average. Some object are inherited from other.
Thank you for all answeres.
Another approach; don't try to serialize complex data changes: instead, send just the actual commands to apply (in a terse form), for example:
move 12432 134, 146
remove 25727
(which would move 1 object and remove another).
You would then apply the commands at the receiver, allowing for a full resync if they get out of sync.
I don't propose you would actually use text for this - that is just to make the example clearer.
One nice thing about this: it also provides "replay" functionality for free.
The cheapest way to track dirty fields is to have it as a key feature of your object model, I.e. with a "fooDirty" field for every data field "foo", that you set to true in the "set" (if the value differs). This could also be twinned with conditional serialization, perhaps the "ShouldSerializeFoo()" pattern observed by a few serializers. I'm not aware of any libraries that match exactly what you describe (unless we include DataTable, but ... think of the kittens!)
Perhaps another issue is the need to track all the objects for merge during deserialization; that by itself doesn't come for free.
All things considered, though, I think you could do something alon the above lines (fooDirty/ShouldSerializeFoo) and use protobuf-net as the serializer, because (importantly) that supports both conditional serialization and merge. I would also suggest an interface like:
ISomeName {
int Key {get;}
bool IsDirty {get;}
}
The IsDrty would allow you to quickly check all your objects for those with changes, then add the key to a stream, then the (conditional) serialization. The caller would read the key, obtain the object needed (or allocate a new one with that key), and then use the merge-enabled deserialize (passing in the existing/new object).
Not a full walk-through, but if it was me, that is the approach I would be looking at. Note: the addition/removal/ordering of objects in child-collections is a tricky area, that might need thought.
I'll just say up front that Marc Gravell's suggestion is really the correct approach. He glosses over some minor details, like conflict resolution (you might want to read up on Leslie Lamport's work. He's basically spent his whole career describing different approaches to dealing with conflict resolution in distributed systems), but the idea is sound.
If you do want to transmit state snapshots, instead of procedural descriptions of state changes, then I suggest you look into building snapshot diffs as prefix trees. The basic idea is that you construct a hierarchy of objects and fields. When you change a group of fields, any common prefix they have is only included once. This might look like:
world -> player 1 -> lives: 1
... -> points: 1337
... -> location -> X: 100
... -> Y: 32
... -> player 2 -> lives: 3
(everything in a "..." is only transmitted once).
It is not logical to transfer only changed fields because you would be wasting your time on detecting which fields changed and which didn't and how to reconstruct on the receiver's side which will add a lot of latency to your game and make it unplayable online.
My proposed solution is for you to decompose your objects to the minimum and sending these small objects which is fast. Also, you can use compression to reduce bandwidth usage.
For the Object ID, you can use a static ID which increases when you construct a new Object.
Hope this answer helps.
You will need to do this by hand. Automatically keeping track of property and instance changes in a hierarchy of objects is going to be very slow compared to anything crafted by hand.
If you decide to try it out anyway, I would try to map your objects to a DataSet and use its built in modification tracking mechanisms.
I still think you should do this by hand, though.
Does anyone have any hard and fast rules about what kind of code the form object should handle as opposed to letting the object itself handle it? For example, if there is a race, should the object that is racing say, horses, handle the race as part of being a horse, or is it better to place that inside the form object? I guess what I'm asking is how one decides what goes into an object like a horse as say a method, and what goes into a form object instead of a horse. Are there any rules you use to figure out where code is best abstracted in this case?
This is called "separation of concerns". Let the form handle the display and user interaction. Let the Racer handle racing.
I try to develop my software so that core functionality that is not UI dependent is abstracted into classes that bear responsibility for their tasks.
Try to think:
How could I write this so I could have both a GUI interface and a console interface without duplicating any code.
The UI should only handle visuals & user interaction. Everything else should be organized based on its role.
Not sure there is absolutely a right answer here. But agreed with John Saunders. A "Form's" job is primarily responsible to display data to the user and accept data input. The closer you keep it to that, and that alone. Think about when there's another place for this type of data to be used, if the code is elsewhere, it can be reused.
Have a "Business Object" or a "Facade" handle the logic of the race, and the form to display it.
Try to represent things the way they are in the real world. Anything that describes the properties or actions of a horse, belongs in a horse object. Anything that describes the properties or actions of a race (including, perhaps, a collection of horse objects), belongs in a race object. A form is not a real world object, but just a gadget for displaying information from horses/races/whatever. So don't store anything with the form except as needed to present the real data on the screen.
Since the form is part of the UI I would apply my UI hard and fast rule:
UI = formating, sorting and displaying data plus accepting and verifying input
Whenever i feel hungry i will publish i am hungry.This will be notified to the service providers say (MealsService,FruitService,JuiceService ).(These service providers know what to serve).
But the serving priority is the concern. Priority here means my first choice is MealsService when there are enough meal is available my need is end with MealsService.To verify the enough meal is availabe the MealsService raises the event "updateMeTheStockStatus" to the "MealsServiceStockUpdateListener" .
The "MealsServiceStockUpdateListener" will only reply back to "MealsService" . No other Service providers ( FruitService,JuiceService ) will be notified by the "MealsServiceStockUpdateListener" .If there is no sufficient stock then only the MealsService passes notification to the JuiceService (as it is the second priority).As usual it checks the stock.If stock is not sufficient it passes message to FruitService,so the flow continues like this.
How can i technically implement this?
Any implemention like priority based delagates and delegate chaining make sense ?
(Somebody! Please reframe it for good readability ).
Update : In this model there is no direct communication between "StackUpdateListener" and "me".Only The "Service Providers" will communicate me.
Like other answerers, I'm not entirely convinced that an event is the way forward, but let's go along with it for the moment.
It seems to me that the business with the MealsServiceStockUpdateListener is a red herring really - you're just trying to execute some event handlers but not others. This sort of thing crops up elsewhere when you have a "BeforeXXX" event which allows cancellation, or perhaps some sort of exception handling event.
Basically you need to get at each of your handlers separately. There are two different ways of doing that - either you can use a normal multicast delegate and call GetInvocationList() or you can change your event declaration to explicitly keep a list of handlers:
private List<EventHandler> handlers = new List<EventHandler>();
public event EventHandler MealRequired
{
add { handlers.Add(value); }
remove
{
int index = handlers.LastIndexOf(value);
if (index != -1)
{
handlers.RemoveAt(index);
}
}
}
These two approaches are not quite equivalent - if you subscribe with a delegate instance which is already a compound delegate, GetInvocationList will flatten it but the List approach won't. I'd probably go with GetInvocationList myself.
Now, the second issue is how to detect when the meal has provided. Again, there are two approaches. The first is to use the normal event handler pattern, making the EventArgs subclass in question mutable. This is the approach that HandledEventArgs takes. The second is to break the normal event pattern, and use a delegate that returns a value which can be used to indicate success or failure (and possibly other information). This is the approach that ResolveEventHandler takes. Either way, you execute the delegates in turn until one of them satistfies your requirements. Here's a short example (not using events per se, but using a compound delegate):
using System;
public class Test
{
static void Main(string[] args)
{
Func<bool> x = FirstProvider;
x += SecondProvider;
x += ThirdProvider;
Execute(x);
}
static void Execute(Func<bool> providers)
{
foreach (Func<bool> provider in providers.GetInvocationList())
{
if (provider())
{
Console.WriteLine("Done!");
return;
}
}
Console.WriteLine("No provider succeeded");
}
static bool FirstProvider()
{
Console.WriteLine("First provider returning false");
return false;
}
static bool SecondProvider()
{
Console.WriteLine("Second provider returning true");
return true;
}
static bool ThirdProvider()
{
Console.WriteLine("Third provider returning false");
return false;
}
}
Rather than publish a message "I'm hungry" to the providers, publish "I need to know current stock available". Then listen until you have enough information to make a request to the correct food service for what you need. This way the logic of what-makes-me-full is not spread amongst the food services... It seems cleaner to me.
Message passing isn't baked into .NET directly, you need to implement your own message forwarding by hand. Fortunately, the "chain of responsiblity design pattern" is designed specifically for the problem you're trying to solve, namely forwarding a message down a chain until someone can handle it.
Useful resources:
Chain of Responsibility on Wikipedia
C# implementation on DoFactory.com
I'm not sure if you really need a priority event. Anyways, let's suppose we want to code that just for fun.
The .NET Framework has no support for such a peculiar construct. Let me show one possible approach to implement it.
The first step would be to create custom store for event delegates (like described here);
Internally, the custom event store could work like a priority queue;
The specific EventArgs used would be HandledEventArgs (or a subclass of it). This would allow the event provider to stop calling handlers after one of them sets the event as Handled;
The next step is the hardest. How to say to tell the event provider what is the priority of the event handler that is being added?
Let me clarify the problem. Usually, the adding of a handler is like this:
eater.GotHungry += mealsService.Someone_GotHungry;
eater.GotHungry += juiceService.Someone_GotHungry;
eater.GotHungry += fruitService.Someone_GotHungry;
The += operator will only receive an delegate. It's not possible to pass a second priority parameter. There might be several possible solutions for this problem. One would be to define the priority in a custom attribute set at the event handler method. A scond approach is discussed in the question.
Compared to the chain of responsibility implementation at dofactory.com, this approach has some advantages. First, the handlers (your food services) do not need to know each other. Also, handlers can be added and remove at any time dynamically. Of course, you could implement a variation of a chain of responsibility that has this advantages too.
I don't think delegates are the proper solution to your problem. Delegates are a low-level service provided by C# for relatively tightly coupled events between components. If I understand your question properly (It is worded a little oddly, so I am not sure I clearly understand your problem), then I think what you need is a mediated consumer/provider.
Rather than having your consumers directly consume the meal, juice, and fruit providers, have them request a food item from a central mediator. The mediator would then be responsible for determining what is available and what should be provided to the consumer. The mediator would be a subscriber to events published by all three services. Whenever stock is added/updated in the Meal, Juice, or Fruit services, they would publish their current stock to all subscribers. The mediator, being a subscriber, would track current stock reductions on its own, and be able to determine for itself whether to send a meal, juice, or fruit to a food consumer when a get food request is made.
For example:
|---------- (GetFoodResponse) ----------------
V |
FoodConsumer ---- (GetFoodRequest) ------> FoodProvider <-----> [ Local Stock Data ]
^
|
|
MealService ---- (PublishStockMessage) ----------|
^
JuiceService --- (PublishStockMessage) ----------|
^
FruitService --- (PublishStockMessage) ----------|
The benefits of such a solution are that you reduce coupling, properly segregate responsibility, and solve your problem. For one, your consumers only need to consume a single service...the FoodProvider. The FoodProvider subscribes to publications from the other three services, and is responsible for determining what food to provide to a consumer. The three food services are not responsible for anything related to the hunger of your food consumers, they are only responsible for providing food and tracking the stock of the food they provide. You also gain the ability to distribute the various components. Your consumers, the food provider, and each of the three food services can all be hosted on different physical machines if required.
However, to achieve the above benefits, your solution becomes more complex. You have more parts, and they need to be connected to each other properly. You have to publish and subscribe to messages, which requires some kind of supporting infrastructure (WCF, MSMQ, some third party ESB, custom solution, etc.) You also have duplication of data, since the food provider tracks stock on its own in addition to each of the food services, which could lead to discontinuity in available stock. This can be mitigated if you manage stock updated properly, but that would also increase complexity.
If you can handle the additional complexity, ultimately, a solution like this would more flexible and adaptable than a more tightly connected solution that uses components and C# events in a local-deployment-only scenario (as in your original example.)
I am having a bit of trouble understanding your analogy here, which sounds like you're obscuring the actual intent of the software, but I think I have done something like what you are describing.
In my case the software was telemarketing software and each of the telemarketers had a calling queue. When that queue raises the event signifying that it is nearing empty, the program will grab a list of available people to call, and then pass them through a chain of responsibility which pushes the available call into the telemarketer's queue like so:
Each element in the chain acts as a priority filter: the first link in the chain will grab all of the people who have never been called before, and if it finishes (ie. went through all of the people who have never been called) without filling up the queue, it will pass the remaining list of people to call to the next link in the chain - which will apply another filter/search. This continues until the last link in the chain which just fires off an e-mail to an administrator indicating that there are no available people to be called and a human needs to intervene quickly before the telemarketers have no work to do.
I am relatively new to game development so I decided I wanted to create a hobby project from scratch for both experience and entertainment. The specific game is similar to poker known as Three Card Brag. The game is played in the movie Lock, Stock and Two Smoking Barrels.
I have been reading up on some of the topics on SO regarding game development, though mostly this question. This has helped revamp the original way I was creating the objects.
One particular problem I am having is defining game state. My initial approach was to separate everything (e.g. keeping chip stacks inside a Player class) but after reading the responses to the question I mentioned previously, it seems as though all possible states of the game should be maintained within a GameState object. What I came up with is essentially this:
abstract class CardGameState
{
protected List<Player> _Players;
protected Player _CurrentPlayer;
protected Dictionary<Player, int> _Chips;
protected Dictionary<Player, Hand> _CurrentHand;
protected Dictionary<Player, PlayerStatuses> _PlayerStatus; // PlayerStatuses.InHand, PlayerStatuses.Folded, PlayerStatuses.SittingOut, etc.
/* etc. */
where each CardGameState is modified by some action:
public interface IAction
{
string Name { get; }
CardGameState Apply(CardGameState state);
bool IsLegal(CardGameState state);
}
Now I'm feeling very strongly that this is defeating the purpose of object-oriented programming, because the data specifically related to the player (in this case, his chip stack, hand, and current status) is not encapsulated by the Player object.
On the other hand, if a player were to raise the bet, I would be creating a RaiseAction that implements IAction, but the IAction interface only accepts the current game state, which I don't believe would be ideal if the chip stacks were stored within the Player class.
Basically, my question is: can I have the best of both worlds such that I can have an exact representation of the game state while simultaneously keeping all data related specifically to an object within the game state inside its given object?
In online-games using the command-pattern (your IAction) is the standard, and proven, way to do it. It's not Object Oriented in the sense of the player, but the actions are Object Oriented, so from a purely theoretical point of view its a solid design pattern, I guess. And in practice thats how every successful online game I've seen implements it, but note that action games normally use very small discreet actions/packets, until it practically becomes a stream of sorts.
Edit:
A long time after I answering this, I came back here and realized another solution to this problem is to implement GameState's Players, Decks, etc... as derived from an IState class with an Apply(IAction action) member. This way objects apply actions on themselves, instead of having the application apply actions on objects, this would map actions and state to a visitor-pattern instead of a command pattern. Either solution will work, where visitor has the larger overhead and more encapsulation, while command is the easier solution with less encapsulation.
Seems like you might be Object-orientizing it for Object-orient's sake...
Seems like Bob Martin's classic bowling game problem.
EDIT: -Summary-
Its a long read, but basically, through TDD and refactoring, a bowling scoring application went from a huge cluster with lots of Classes and polymorphism to 20 or 30 elegant lines of code. Why? Because they didn't really need to be there in the first place