Status of aggregate root dependent on the status of children - c#

I am new to using DDD and need some advice. I have an aggregate root that contains a collection of children. The status of the root (IsFinished) depends on the children. Let's say I absolutely need the aggregate root to have a field '_someField', while there can be an unlimited number of aggregate roots with the same field value '_someField' and at the same time this field must be a string. According to this field, I need to find all aggregate roots that have some specific value (e.g. 'Test') and are in !IsFinished state. I am using EF6 and the search is quite slow. How would one generally go about solving something like this?
public class MyAggregateRoot: AggregateRoot
{
private IList<Item> _items;
private string _someField;
public bool IsFinished => _items.All(i => i.Status == ItemStatus.Finished);
public MyAggregateRoot()
{
_items = new List<Item>();
}
...
}
For example, I was thinking of having a status variable inside the aggregate root that would be set to IsFinished the moment the last item is set to ItemStatus.Finished, but in that case it could happen for example that I have the status of the root set to Finished for some reason but some Item will not be in the finished state and therefore the data will be in an inconsistent state.
EDIT:
So let me ask it a little differently. What bothers me is whether it's good to always go through the collection to find some state, or for example some total - for example if I have a cart with some items, each item has a price and I want to calculate the total price.
One option would be to go through the collection of all items and add up their price. The other option would be to have a totalPrice variable in the Aggregare root (cart) and always recalculate that price appropriately when adding an item to the cart. I think the first solution is better from DDD point of view, but it will be worse from performance point of view.
Another example I can think of is some todo-list that contains individual tasks. Each task has a status not-completed or completed, and the todo-list has a status that is completed when all the todo-list's tasks are completed. If I had a really large number of todo-lists and I wanted to display all completed todo-lists, for example, I would also have to go through the tasks for all todo-lists and determine the todo-list status based on the status of all the tasks.
I'd like to get advice from an experienced developer who could, for example, explain to me when it's better to use the first solution and when to use the second (or a completely different one). Or tell me if, for example, the second solution somehow violates the DDD.

It depends on the use case.
If the use case states that there may be a large or unlimited number of children, it is technically not practical to put the children into the aggregate root.
On the other hand a small set of children in the parent may be handled by the ORM mapper (hint: I'm a Java developer, in my case it would be Hibernate) without performance problems.
Had a similar issue: My Process parent could have an unlimited number of Activity children. I decided to implement Process as an entity (being the aggregate root) and Activity as an value object with a reference to its Process. Changes to an Activity causing changes to its parent are propagated by events and handled asynchronously (so eventual consistency comes into play).
Vaughn Vernon discusses such design decisions in its "red book", that helped me a lot to come to a decision for implementation.

Related

Rx.NET 'Distinct' to get the lastest value?

I'm new to Rx and I'm trying to make a GUI to display stock market data. The concept is a bit like ReactiveTrader, but I'll need to display the whole "depth", i.e., all prices and their buy/sell quantities in the market instead of only the "top level" of the market buy/sells, sorting by price.
The data structure for each "price level" is like this:
public class MarketDepthLevel
{
public int MarketBidQuantity { get; set; }
public decimal Price { get; set; }
public int MarketAskQuantity { get; set; }
}
And underneath the GUI, a socket listens to network updates and return them as an Observable:
IObservable<MarketDepthLevel> MarketPriceLevelStream;
Which after transformed into a ReactiveList, eventually bound to a DataGrid.
The transformation would basically choose the latest updates of each price level, and sort them by price. So I come up with something like this:
public IReactiveDerivedList<MarketDepthLevel> MarketDepthStream
{
get
{
return MarketDepthLevelStream
.Distinct(x => x.Price)
.CreateCollection()
.CreateDerivedCollection(x => x, orderer: (x, y) => y.Price.CompareTo(x.Price));
}
}
But there are problems:
When 'Distinct' sees a same price as appeared before, it discards the new one, but I need the new one to replace the old ones (as they contain the lasted MarketBidQuantity/MarketAskQuantity)
It seems a bit clumsy to CreateCollection/CreateDerivedColleciton
Any thoughts on solving these (especially the 1st problem)?
Thanks
Just group the items and then project each group to be the last item in the group:
return MarketDepthLevelStream
.GroupBy(x => x.Price, (key, items) => items.Last());
If I understand you correctly, you want to project a stream of MarketDepthLevel updates in a list of the latest bid/ask quantities for each level (in finance parlance, this is a type of ladder). The ladder is held as a ReactiveList bound the UI. (ObserveOn may be required, although ReactiveList handles this in most cases I believe)
Here's an example ladder snapped from http://ratesetter.com, where the "Price" is expressed as a percentage (Rate), and the bid/ask sizes by the amount lenders want and borrowers need at each price level:
At this point, I begin to get slightly lost. I'm confused as to why you need any further Rx operators, since you could simply Subscribe to the update stream as is and have the handler update a fixed list data-bound to a UI. Doesn't each new event simply need to be added to the ReactiveList if it's a new price, or replace an existing entry with a matching price? Imperative code to do this is fine if it's the last step in the chain to the UI.
There is only value in doing this in the Rx stream itself if you need to convert the MarketDepthLevelStream into a stream of ladders. That could be useful, but you don't mention this need.
Such a need could be driven by either the desire to multicast the stream to many subscribers, and/or because you have further transformations or projections you need to make on the ladders.
Bear in mind, if the ladder is large, then working with whole ladder updates in the UI might give you performance issues - in many cases, individual updates into a mutable structure like a ReactiveList are a practical way to go.
If working with a stream of ladders is a requirement, then look to Observable.Scan. This is the work-horse operator in Rx that maintains local state. It is used for any form of running aggregate - such as a running total, average etc., or in this case, a ladder.
Now if all you need is the static list described above, I am potentially off on a massive detour here, but it's a useful discussion so...
You'll want to think carefully about the type used for the ladder aggregate - you need to be concious of how down-stream events would be consumed. It's likely to need an immutable collection type so that things don't get weird for subscribers (each event should be in effect a static snapshot of the ladder). With immutable collections, it may be important to think about memory efficiency.
Here's a simple example of how a ladder stream might work, using an immutable collection from nuget pre-release package System.Collections.Immutable:
public static class ObservableExtensions
{
public static IObservable<ImmutableSortedDictionary<decimal, MarketDepthLevel>>
ToLadder(this IObservable<MarketDepthLevel> source)
{
return source.Scan(ImmutableSortedDictionary<decimal, MarketDepthLevel>.Empty,
(lastLadder, depthLevel) =>
lastLadder.SetItem(depthLevel.Price, depthLevel));
}
}
The ToLadder extension method creates an empty immutable ladder as the seed aggregate, and each successive MarketDepthLevel event produces a new update ladder. You may want to see if ImmutableSortedSet is sufficient.
You would probably want to wrap/project this into your own type, but hopefully you get the idea.
Ultimately, this still leaves you with the challenge of updating a UI - and as mentioned before now you are stuck with the whole ladder, meaning you have to bind a whole ladder every time, or convert it back to a stream of individual updates - and it's getting way to off topic to tackle that here...!

asp.net shopping cart inventory management in case of multi user environment

is there any need to handle locks in terms of threading in any inventory application.
like as i think asp.net is not thread safe.
lets say that there is a product available and its quantity available is 1 and number of user partially trying to book that particular product are 40. so which is going to get that product. or what happens.
not sure even if the question is reliable or not.
http://blogs.msdn.com/b/benchr/archive/2008/09/03/does-asp-net-magically-handle-thread-safety-for-you.aspx
i am not sure on this please help.
Well, technically, you're not even talking about ASP.NET here, but rather Entity Framework or whatever else you're using to communicate with SQL Server or whatever else persistent data store you're using. Relational databases will typically row-lock, so that as one client is updating the row, the row cannot be read by another client, but you can still run into concurrency issues.
You can handle this situation one of two ways: pessimistic concurrency or optimistic concurrency. With pessimistic concurrency you create locks and any other thread trying to read/write the same data is simply turned away in the mean time. In a multi-threaded environment, it's far more common to use optimistic concurrency, since this allows a bit of play room for failover.
With optimistic concurrency, you version the data. As a simplistic example, let's say that I'm looking for the current stock of widgets in my dbo.Widgets table. I'd have a column like Version which might initially be set to "1" and 100 widgets in my Stock column. Client one wants to buy a widget, so I read the row and note the version, 1. Now, I want to update the column so I do an update to set Stock to 99 and Version to 2, but I include in my where clause Version = 1. But, between the time the row was initially read and the update was sent, another client bought a widget and updated the version of the row to 2. The first client's update fails, because Version is no longer 1. So the application then reads the row fresh and tries to update it again, subtracting 1 from Stock and incrementing Version by 1. Rinse and repeat. Generally, you'll want to have some upward limit of attempts before you'll just give up and return an error to the user, but in most scenarios, you might have one collision and then the next one goes through fine. Your server would have to be getting slammed with people eagerly trying to buy widgets before it would be a real problem.
Now of course, this is a highly simplistic approach, and honestly, not something you really have to manage yourself. Entity Framework, for example, will handle concurrency for you automatically as long as you have a rowversion column:
[Timestamp]
public byte[] RowVersion { get; set; }
See http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application for the full guide to setting it up.
ASP.NET certainly is not Thread Safe. The article you link too is fine as a start, but doesn't tell all the story by a long way. In your case, you likely load the Product List into memory at first request for it, or at Application Startup or some other trigger.
When a Request wants to work with a product you grab the appropriate member of this preloaded list. (Believe me this is better than having every request loading the product or product list from the database.) However, now if you have 40 simultaneous requests for the same product they will all be accessing the same object, and new nasty things can happen, like ending up with -39 stock.
You can address this in a many ways ways, but they boild down to two:
Protect the data somehow
Do what Amazon does
Protect the data
There are numerous ways of doing this. One would be to use a critical section via the Lock keyword on C#. For an example, something like this in the Product Class:
private object lockableThing; // Created in the ctor
public bool ReduceStockLevelForSale(int qtySold)
{
bool success = false;
if (this.quantityOnHand >= qtySold)
{
lock (lockableThing)
{
if (this.quantityOnHand >= qtySold)
{
this.quantityOnHand -= qtySold;
success = true;
}
}
}
return success;
}
The double check on the quantity on hand is deliberate and required. There are any number of ways of doing the equivalent. Books have been written about this sort of thing.
Do what Amazon does
As long as at some point in the Order Taking sequence, Amazon thinks it has enough on hand (or maybe even any) it will let you place the order. It doesn't reduce the stock level while the order is being confirmed. Once the order has been confirmed, it has a back-end process (i.e. NOT run by the Web Site) which checks order by order that the order can be fulfilled, and only reduces the On Hand level if it can. If it can't be, they put the order on hold and send you an email saying 'Sorry! We don't have enough of Product X!' and giving you some options.
Discussion
Amazon's is the best way, because if you decrement the stock from the Web Site at what point do you do it? Probably not until the order is confirmed. If the stock has gone, what do you then do? Also, you are going to have to have some functionality to send the 'Sorry!' email: what happens when the last one (or two or three) items of that product can't be found, don't physically exist or are broken? You send a 'Sorry!' email.
However, this does assume that you are in control of the full order to dispatch cycle which is not always the case. If you aren't in control of the full cycle, you need to adjust to what you are in control of, and then pick a method.

Does the need to make the code simpler justify the use of wrong abstractions?

Suppose we have a CommandRunner class that runs Commands, when a Command is created it's kept in the processingQueue for proccessing, if the execution of the Command finishes with errors the Command is moved to the faultedQueue for later processing but when everything is OK the Command is moved to the archiveQueue, the archiveQueue is not going to be processed in any way
the CommandRunner is something like this
class CommandRunner
{
public CommandRunner(IQueue<Command> processingQueue,
IQueue<Command> faultedQueue,
IQueue<Command> archiveQueue)
{
this.processingQueue = processingQueue;
this.faultedQueue= faultedQueue;
this.archiveQueue= archiveQueue;
}
public void RunCommands()
{
while(processingQueue.HasItems)
{
var current = processingQueue.Dequeue();
var result = current.Run();
if(result.HasError)
curent.MoveTo(faultedQueue);
else
curent.MoveTo(archiveQueue);
...
}
}
}
The CommandeRunner recives the three dependecies as a PersistentQueue the PersistentQueue is responsible for the long term storage of the Commands and so we free the CommandRunner from handling this
And the only purpose of the archiveQueue is to keep the design homogenous, to keep the CommandRunner persistence ignorant and with few dependencies
for example we can imagine a Property like this
IEnumerable<Command> AllCommands
{
get
{
return Enumerate(archiveQueue).Union(processingQueue).Union(faultedQueue);
}
}
many portions of the class need to do so(handle the Archive as a Queue to make the code simpler as shown above)
Does it make sense to use a Queue even if it's not the best abstraction, or do I have to use another abstraction for the archive concept.
what are other alternatives to meet these requirement?
Keep in mind that code, especially running code usually gets tangled and messy as time pass. To combat this, good names, good design, and meaningful comments come into play.
If you don't going to process the archiveQueue, and it's just a storage for messages that has been successfully processed, you can always store it as a different type (list, collection, set, whatever suits your needs), and then choose one of the following two:
Keep the name archiveQueue and change the underlying type. I would leave a comment where it's defined (or injected) saying : Notice that this might not be an actual queue. Name is for consistency reasons only.
Change the name to archiveRepository or something similar, while keeping the queue type. Obviously, since it's still a queue, you'll leave a comment saying: Notice, this is actually a queue.
Another thing to keep in mind, is that if you have n people working on your code base, you'll probably get n+1 different perferences about which way it shoud be done :)
Queue is a useful structure when you need to take care about the order of items inside it. If you need in your command post process, take care about the orders commands ran, then the queue can be a good choice.
If you don't need info about the order or commands, maybe you can use a List (on System.Collections namespace).
I think your choice are good, in the same case, I'll use a queues, we have a good example with OS design principles, inside OS (on Kernel) the process are queued for execution, clearly the OS queues are more complicated because they have other variables in mind like priority, and CPU utilization, but we can learn about the use of queues like data structures in process management.

Coding interactions in a text adventure

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.

using ThreadPools to search through object lists

I have these container objects (let's call them Container) in a list. Each of these Container objects in turn has a DataItem (or a derivate) in a list. In a typical scenario a user will have 15-20 Container objects with 1000-5000 DataItems each. Then there are some DataMatcher objects that can be used for different types of searches. These work mostly fine (since I have several hundred unit tests on them), but in order to make my WPF application feel snappy and responsive, I decided that I should use the ThreadPool for this task. Thus I have a DataItemCommandRunner which runs on a Container object, and basically performs each delegate in a list it takes as a parameter on each DataItem in turn; I use the ThreadPool to queue up one thread for each Container, so that the search in theory should be as efficient as possible on multi-core computers etc.
This is basically done in a DataItemUpdater class that looks something like this:
public class DataItemUpdater
{
private Container ch;
private IEnumerable<DataItemCommand> cmds;
public DataItemUpdater(Container container, IEnumerable<DataItemCommand> commandList)
{
ch = container;
cmds = commandList;
}
public void RunCommandsOnContainer(object useless)
{
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
foreach (DataItem di in ch.ItemList)
{
foreach (var cmd in cmds)
{
cmd(sh);
}
}
//Console.WriteLine("Done running for {0}", ch.DisplayName);
}
}
(The useless object parameter for RunCommandsOnContainer is because I am experimenting with this with and without using threads, and one of them requires some parameter. Also, setting the priority to AboveNormal is just an experiment as well.)
This works fine for all but one scenario - when I use the AllWordsMatcher object type that will look for DataItem objects containing all words being searched for (as opposed to any words, exact phrase or regular expression for instance).
This is a pretty simple somestring.Contains(eachWord) based object, backed by unit tests. But herein lies some hairy strangeness.
When the RunCommandsOnContainer runs using ThreadPool threads, it will return insane results. Say I have a string like this:
var someString = "123123123 - just some numbers";
And I run this:
var res = someString.Contains("data");
When it runs, this will actually return true quite a lot - I have debugging information that shows it returning true for empty strings and other strings that simply do not contain the data. Also, it will some times return false even when the string actually contains the data being looked for.
The kicker in all this? Why do I suspect the ThreadPool and not my own code?
When I run the RunCommandsOnContainer() command for each Container in my main thread (i.e. locking the UI and everything), it works 100% correctly - every time! It never finds anything it shouldn't, and it never skips anything it should have found.
However, as soon as I use the ThreadPool, it starts finding a lot of items it shouldn't, while some times not finding items it should.
I realize this is a complex problem (it is painful trying to debug, that's for sure!), but any insight into why and how to fix this would be greatly appreciated!
Thanks!
Rune
It's a bit hard to see from the fragment you're posting, but judging by the symptoms I would look at the AllWordsMatcher (look for static state). If AllWordsMatcher is stateful you should also check that you're creating a new instance for each thread.
More generally I'd look at all the instances involved in the matching/searching process, specifically at the working objects being used when multithreaded. From past experience, the problem usually lies there. (It's easy to look too much at the object graph representing your business data Container/DataItem in this case)

Categories

Resources