Author Topic: Programming Advice  (Read 10183 times)

0 Members and 1 Guest are viewing this topic.

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #15 on: October 13, 2010, 12:29:46 AM »
2)  If you want something that's close to an array of objects, then List<T> is the container you want.  This is a simple container that can be iterated through using a foreach block, and allows multiple inclusions of the same object.  Dictionary<TKey, TValue> is what I usually hear referred to as an "associative array" - it allows keyed access.  Note that (IIRC) a Dictionary is implemented as something close to a hash table, in other words you can find an element in it without doing an O(N) search.  Also note that the key values in a dictionary need to be unique.

As well as looping through the list I also need to be able to access a specific item based on its key, such as ShipID. I was going to ensure that all objects have a unique identifier wthin the game, not just within a specific type of object. Does that type of keyed access mean the Dictionary is still the way to go?

Steve
 

Offline sloanjh

  • Global Moderator
  • Admiral of the Fleet
  • *****
  • Posts: 2805
  • Thanked: 112 times
  • 2020 Supporter 2020 Supporter : Donate for 2020
    2021 Supporter 2021 Supporter : Donate for 2021
Re: Programming Advice
« Reply #16 on: October 13, 2010, 12:32:34 AM »
My hope was that I could setup Dictionary to add MapObjects, fill it with derived objects and then override various base class functions to ensure that the container class would call functions appropriate to the complexity of the derived object. For example, if I create an UpdateCourseSpeed function, which will handle changes to course and speed based on changes in thrust, facing and external forces such a gravity, that would require code for missiles, more complex code for ships and different code for something like an asteroid, which would perhaps be a SystemBody object, derived from MapObject. The base UpdateCourseSpeed function would be in MapObject. Missile, Ship and SystemBody would have their own version of the same function. I would like to be able to run a single for each loop for every MapObject and have the code take the appropriate action for each object, although using the overriden function rather than checking the type of each object first. This is straighforward in C++. Is that what you mean above for C#, or will I need a separate Dictionary class to hold collections of Missile, Ship and SystemBody objects? Or am I just way out of date in terms of thinking and there is a better way to handle this?

I think my big post discussed this.  The bottom line is that you want your collection to be of IMapObjects (interfaces which the concrete objects implement) - the code in the loop calls the IMapObject methods, while the concrete type gives the polymorphism.  Let me know if you want more example code - I think what I put in probably addresses what you're after....

John
 

Offline sloanjh

  • Global Moderator
  • Admiral of the Fleet
  • *****
  • Posts: 2805
  • Thanked: 112 times
  • 2020 Supporter 2020 Supporter : Donate for 2020
    2021 Supporter 2021 Supporter : Donate for 2021
Re: Programming Advice
« Reply #17 on: October 13, 2010, 12:33:39 AM »
As well as looping through the list I also need to be able to access a specific item based on its key, such as ShipID. I was going to ensure that all objects have a unique identifier wthin the game, not just within a specific type of object. Does that type of keyed access mean the Dictionary is still the way to go?
Yep.  If you want keyed access, then Dictionary is a better choice.
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #18 on: October 13, 2010, 12:35:16 AM »
Are you sure it's not throwing in the GetDataByGame(1) call?  Note that by default Visual Studio doesn't turn on most exceptions - you have to go into Debug/Exceptions (or something like that) and click the appropriate checkbox.

Yes, that is the problem. There is a runtime error on that line once I click the Thrown checkboxes. It can't find the database file at runtime for some reason, even though it can see it during design. I'll try and figure out what the new problem is - thanks!

Steve
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #19 on: October 13, 2010, 12:37:04 AM »
I think my big post discussed this.  The bottom line is that you want your collection to be of IMapObjects (interfaces which the concrete objects implement) - the code in the loop calls the IMapObject methods, while the concrete type gives the polymorphism.  Let me know if you want more example code - I think what I put in probably addresses what you're after....

I need to start reading up on interfaces as this is something I didn't use much (or have forgotten about) and then go through your code properly. It will probably be tomorrow before I can reply intelligently :)

Steve
 

Offline sloanjh

  • Global Moderator
  • Admiral of the Fleet
  • *****
  • Posts: 2805
  • Thanked: 112 times
  • 2020 Supporter 2020 Supporter : Donate for 2020
    2021 Supporter 2021 Supporter : Donate for 2021
Re: Programming Advice
« Reply #20 on: October 13, 2010, 12:42:27 AM »
Yes, that is the problem. There is a runtime error on that line once I click the Thrown checkboxes. It can't find the database file at runtime for some reason, even though it can see it during design. I'll try and figure out what the new problem is - thanks!

NP.  The amusing thing is that I've been contemplating the project you're doing (3D Newtonian Space War) as a toy project to play with C# at home, just to be doing something.  Another possibility was to start to code up the Harpoon rules (which is how I learned C 25 years ago or so).

Before you go too far down your route, you should take a look at the LINQ stuff - it basically lets you write SQL syntax rather than C++ syntax for filters etc.  Since your code is usually so DB-centric, you might find it simplifies your life.  Also, the F1 key is very useful - if you put your cursor on any code element and hit F1, it takes you to MSDN help for that code element, which includes sample code in the various .NET languages.  Like I said elsewhere - they really did a good job with the language and programming environment.

Bedtime for me :-)

John
 

Offline sloanjh

  • Global Moderator
  • Admiral of the Fleet
  • *****
  • Posts: 2805
  • Thanked: 112 times
  • 2020 Supporter 2020 Supporter : Donate for 2020
    2021 Supporter 2021 Supporter : Donate for 2021
Re: Programming Advice
« Reply #21 on: October 13, 2010, 12:47:39 AM »
I need to start reading up on interfaces as this is something I didn't use much (or have forgotten about) and then go through your code properly. It will probably be tomorrow before I can reply intelligently :)

They basically define a contract (set of services) that any class that implements the interface is required to provide.  That means that any object which implements the contract can be passed to a function that only uses the contract.  The analogue in C++ is abstract base classes in a multiple-inheritance environment.

They also participate in generics (similar to C++ templates) - when specifying a template argument, you can say "it must implement interface IFoo", then the template code can utilize the methods of IFoo.  You've probably already figured out by now that Dictionary<TKey, TObject> is doubly generic over key and object types.

Have fun mulling :-)

John
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #22 on: October 13, 2010, 01:02:04 AM »
Based on my brief read up on interfaces, my own interpretation is that they are a template for the function calls that an object should be able to handle, even if they handle the implementation of those function calls differently. So as long as you know a particular class has the correct interface, you can call those functions and not worry about it. As a single class can handle multiple templates, it could potentially be used within a variety of different collections that have different purposes as long as all the classes assigned to the same collection have the same interface, which effectively creates a many to many relationship between classes and collections as long as you implement the relevant interfaces correctly. Also, if you inherit a template within a base class, you can implement the same interface differently within derived classes, which as you say has the same effect as virtual functions.

Was that understandable or did I just talk a lot of rubbish? :)

Steve
 

Offline sloanjh

  • Global Moderator
  • Admiral of the Fleet
  • *****
  • Posts: 2805
  • Thanked: 112 times
  • 2020 Supporter 2020 Supporter : Donate for 2020
    2021 Supporter 2021 Supporter : Donate for 2021
Re: Programming Advice
« Reply #23 on: October 13, 2010, 01:37:04 AM »
Based on my brief read up on interfaces, my own interpretation is that they are a template for the function calls that an object should be able to handle, even if they handle the implementation of those function calls differently. So as long as you know a particular class has the correct interface, you can call those functions and not worry about it. As a single class can handle multiple templates, it could potentially be used within a variety of different collections that have different purposes as long as all the classes assigned to the same collection have the same interface, which effectively creates a many to many relationship between classes and collections as long as you implement the relevant interfaces correctly. Also, if you inherit a template within a base class, you can implement the same interface differently within derived classes, which as you say has the same effect as virtual functions.

Was that understandable or did I just talk a lot of rubbish? :)
Yep - that's pretty much it.  Your "template" is what I called "contract".  A slight difference at the end - if a base class implements an interface, then you have to (IIRC) provide all the methods of the interface in the base class.  You can however (using the abstract or virtual Impl trick I discussed) put a polymorphic implementation behind those methods.


Ok - really logging off now :-)

John
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #24 on: October 13, 2010, 09:57:45 AM »
Next problem :)

When I originally setup the data source, the wizard asked if I wanted to include the database in the program files. I said no, as I wasn't really sure what that would entail. I placed the mbd file in the project directory instead from where I edit it using Access. The IDE can see the database because it can retrieve both structure and data. However, when the program runs it throws an error because for some reaon it is looking for the database file in /bin/debug. So 2 questions:

1) Should I be including the database file in the program files, and if so how do I go back and change that?

2) If not, how do get the IDE and the program to look in the same place for the DB file?

Steve
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #25 on: October 13, 2010, 10:01:10 AM »
I want to be able to run through the objects and perform various functions on them, or select a particular object by key and modify it. Can I add my own functions to the Dictionary class, such as the UpdateCourseSpeed I mentioned in my previous answer? I suppose what I am asking is should I use inherit my own version of Diictionary class with additional functions to manipulate the MapObjects, or should I just use Dictionary to hold the objects and wrap a class around that Dictionary with the functions I need? Or I am totally misunderstanding the Dictionary class?

Yep, you can create a MapObjects collection (of any type, really, even an old style array), insert objects that inherit from MapObjects into it, and then call their functions and have the subclass-specific implementations get run properly.

Here's a not-quite-fully implemented example.

Code: [Select]
using System.Collections.Generic;

namespace MyNamespace
{
    public abstract class MapObject
    {
        public virtual void UpdateCourseSpeed(int newSpeed)
        {
            _speed = newSpeed;
        }

        protected int _speed;
    }

    public class Missile : MapObject
    {
        public override void UpdateCourseSpeed(int newSpeed)
        {
            _speed = newSpeed > maxSpeed ? maxSpeed : newSpeed;
        }

        private int maxSpeed = 100;
    }

    public class MapObjectHolder
    {
        private readonly Dictionary<int, MapObject> _mapObjectDictionary;

        public MapObjectHolder()
        {
            _mapObjectDictionary = new Dictionary<int, MapObject>();
        }

        public void AdjustSpeed(int mapObjectId, int newSpeed)
        {
            if(_mapObjectDictionary.ContainsKey(mapObjectId))
            {
                _mapObjectDictionary[mapObjectId].UpdateCourseSpeed(newSpeed);
            }
        }
    }
}
« Last Edit: October 13, 2010, 10:07:33 AM by ndkid »
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #26 on: October 13, 2010, 10:14:57 AM »
Next problem :)

When I originally setup the data source, the wizard asked if I wanted to include the database in the program files. I said no, as I wasn't really sure what that would entail. I placed the mbd file in the project directory instead from where I edit it using Access. The IDE can see the database because it can retrieve both structure and data. However, when the program runs it throws an error because for some reaon it is looking for the database file in /bin/debug. So 2 questions:

1) Should I be including the database file in the program files, and if so how do I go back and change that?

2) If not, how do get the IDE and the program to look in the same place for the DB file?

Steve
My first guess, not having a lot of details of how you set up your project: go to server explorer and add a reference to the location of the file. See: http://msdn.microsoft.com/en-us/library/bb384568.aspx
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #27 on: October 13, 2010, 10:31:51 AM »
My first guess, not having a lot of details of how you set up your project: go to server explorer and add a reference to the location of the file. See: http://msdn.microsoft.com/en-us/library/bb384568.aspx

I can't find that option on the View menu. I am using Visual C# Express though so it may not be there. I have temporarily resolved the problem by placing a copy of the database file in the bin/debug directory. It also occurred to me to simply point the IDE at that location as well but I can find no way to do that and no way to just delete the data source and start again. Just unfamiliarity with the IDE I imagine but its very frustrating. So at the moment I have two copies of the database and I will have to remember to copy the master database to the copy database location when I make changes, although I suppose that creates an inherent backup if anything goes seriously wrong :)

Steve
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #28 on: October 13, 2010, 11:14:48 AM »
I can't find that option on the View menu. I am using Visual C# Express though so it may not be there. I have temporarily resolved the problem by placing a copy of the database file in the bin/debug directory. It also occurred to me to simply point the IDE at that location as well but I can find no way to do that and no way to just delete the data source and start again. Just unfamiliarity with the IDE I imagine but its very frustrating. So at the moment I have two copies of the database and I will have to remember to copy the master database to the copy database location when I make changes, although I suppose that creates an inherent backup if anything goes seriously wrong :)

Alright, my second guess: the app.config (if you're generating foo.exe, it'll probably be called foo.exe.config) may have the db data. It may just have the file name, thus looking for it in the same location as the .exe/path. If I'm right, that's where you could change it.
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11649
  • Thanked: 20350 times
Re: Programming Advice
« Reply #29 on: October 13, 2010, 11:32:45 AM »
Alright, my second guess: the app.config (if you're generating foo.exe, it'll probably be called foo.exe.config) may have the db data. It may just have the file name, thus looking for it in the same location as the .exe/path. If I'm right, that's where you could change it.

Found it, although it just has the DB set up as the root directory, which the program thinks is bin\debug. I assume that C# programs are setup by default to run in \ProjectDirectory\bin\debug and that is where it expects to find the DB. I could possibly have a DB in a sub-directory but not in a higher directory. What I really need to be able to do is change the datasource from the DB in \ProjectDirectory to the DB in the \ProjectDirectory\bin\debug directory so I don't end up maintaining two versions of the same DB. At the moment though I can't work out how to do that :)

Steve