2
\$\begingroup\$

I started creating a small abstract simulation framework and would be happy if someone could take a look at the code and give me feedback on it.

The code can be found here, and it is currently not in a 100% finished and tested state.

It should be (almost) multi threading ready.

This is some sample code on how you can use the framework:

class Program
    {
        static void Main(string[] args)
        {
            Debug.Listeners.Add(new ConsoleTraceListener());

            var system = new SimulationSystem();

            // Add a thread and a simulation engine to the simulation framework
            system.AddSimulationThread(new SimulationThread(new SimulationEngine[] {new TestSimulationEngine() }.ToList()));

            // Add a new simulation group
            system.World.Objects.Add(new SimulationGroup());

            // Add a new object to the group
            ((SimulationGroup)system.World.Objects[0]).Objects.Add(new SimulationObject());
            system.World.Objects.Add(new SimulationObject());

            DateTime loopStart = DateTime.Now;
            DateTime loopEnd = DateTime.Now;

            // Simulates the update loop
            while (true)
            {
                loopStart = DateTime.Now;
                system.Update(loopStart - loopEnd);
                loopEnd = DateTime.Now;

                // Wait for user to press enter to start the next loop
                //Console.ReadLine();
            }
        }
    }

with this TestSimulationEngine class:

public class TestSimulationEngine : SimulationEngine
{
    public override void UpdateWorld(SimulationContext context, TimeSpan step)
    {
        // Do some stuff to the simulation world

        Console.WriteLine("UpdatingWorld with step {0}", step);

        // Add a new object each loop
        context.World.Objects.Add(new SimulationObject());
    }
}

A short introduction to the architecture behind the framework:

There is the class SimulationSystem which you can use to initialise a new simulated world. You can assign SimulationEngines to defined threads. For example a physicsengine to thread 1, a heatsystem to thread 2, ...

Also it holds the SimulationWorld which is a hierarchical system. Inside the World you can add SimulationObjects and SimulationGroups. A SimulationGroup is the same as a SimulationObject but can also have sub-objects.

For example, inside the world you can add a car as a simulation group. Inside the car you have the engine, driver, etc as simulation sub-objects.

You can also set any property you want on the objects using the code object["Property"].

\$\endgroup\$
3
\$\begingroup\$

First, a general consideration about your project. I cannot see any unit test. I'd strongly encourage you to write some, as I think that unit tests can help you coming up with a better design. I haven't looked at the code in details so unfortunately I don't have other comments on that.

Looking at the example main you posted I see you should try to rewrite your code so that you do dependency injection and in a way that you don't have to violate the law of Demeter to setup the simulation.

What about changing the constructor of SimulationSystem to SimulationSystem(IEnumerable<SimulationThread> simulationThreads, IEnumerable<SimulationGroup> simulationGroups)? If you do that you make it clear what you need to run your simulation and you can avoid doing the very ugly operations involving system.World.Objects.

I am not sure what you want to do with all that calls to DateTime.Now, but they don't look quite right to me. I think that the idea of having system.Update take a TimeSpan as a parameter is good, but I would not expect it to be called in that way. What about this:

var currentDateTime = /* compute it somehow */
var endDateTime = /* compute it somehow */
var simulationTimespan = /* compute it somehow */
while(currentDateTime < endDateTime)
{
    system.Update(simulationTimespan);
    currentDateTime = currentDateTime.Add(simulationTimespan);
}
\$\endgroup\$
  • \$\begingroup\$ I'm extremely against unit tests. Especially at the beginning they tend to restrict you from being creative and revolutionary... I recommend writing system/integration tests. This also promotes you to think more about high level API. Recently, Greg Young had a talk with the basic idea of 'just deleting code' which frees you to try something different. I've always done that since ever, and I'm very happy with that. \$\endgroup\$ – Matthias Nov 2 '14 at 16:35
  • \$\begingroup\$ I cannot see how tests could restrict creativity. And regarding the APIs, they give you immediate feedbacks about them. As soon as you write an unit tests for an high level component you see how its clients are supposed to interact with it and you should clearly spot if there is something wrong with that interaction pattern \$\endgroup\$ – mariosangiorgio Nov 2 '14 at 16:50
  • \$\begingroup\$ There is nothing like an unit test for a high level component. \$\endgroup\$ – Matthias Nov 2 '14 at 17:24
  • \$\begingroup\$ Why not? If every component has a single responsibility you should be able to test it as a unit. Probably you're going to need some mock/fakes/whatever to pass in in place of the dependencies the component is going to have in the real system, but that does not mean that you cannot test that your component does what you expect to. \$\endgroup\$ – mariosangiorgio Nov 2 '14 at 17:38
  • \$\begingroup\$ For clarification: AFAIK there are different kinds of tests (for me: Unit/Specs < Integration/Component < System/Acceptance) that go from white to black-box testing. As I said, I'm against Unit testing at an early stage. Especially when you're not sure where things are going. Integration or system tests are a good thing to drive the API.. So maybe are already agreeing on that. But I didn't say that "tests [in general] are restricting creativity". \$\endgroup\$ – Matthias Nov 2 '14 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.