Advertisement Jump to content
  • Advertisement

dot

Member
  • Content Count

    115
  • Joined

  • Last visited

Community Reputation

426 Neutral

About dot

  • Rank
    Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Figured it might be interesting to post my serialization related code with some explainations. Documentation/assertions/error checking are removed and replaced with comments if necessary for this snipplet. First the attribute which helps to identify which field to serialize and what name to serialize as. public sealed class SerializeAsAttribute : Attribute { public string NameToUse { get { return name_; } } public SerializeAsAttribute(string name) { name_ = name; } private readonly string name_; } Next up, the helper public sealed class SerializationHelper { internal struct MarkedField { internal FieldInfo field_; internal SerializeAsAttribute attribute_; // stored so that I don't have to do another runtime query on field. } private static MarkedField[] GetSerializableFields(ISerializable o) { List list = new List(); Type t = o.GetType(); FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { object[] attributes = field.GetCustomAttributes(typeof(SerializeAsAttribute), false); if (attributes != null && attributes.Length > 0) { MarkedField marked = new MarkedField(); marked.field_ = field; marked.attribute_ = attributes[0] as SerializeAsAttribute; list.Add(marked); } } return list.ToArray(); } public static void Serialize(SerializationInfo info, ISerializable o) { MarkedField[] fields = GetSerializableFields(o); foreach (MarkedField field in fields) { info.AddValue(field.attribute_.NameToUse, field.field_.GetValue(o)); } } public static void Deserialize(SerializationInfo info, ISerializable o) { MarkedField[] fields = GetSerializableFields(o); foreach (MarkedField field in fields) { field.field_.SetValue(o, info.GetValue(field.attribute_.NameToUse, field.field_.FieldType)); } } } And a sample usage [Serializable] public sealed class TestObject : ISerializable { #region ISerializable Members public TestObject(SerializationInfo info, StreamingContext context) { SerializationHelper.Deserialize(info, this); } public void GetObjectData(SerializationInfo info, StreamingContext context) { SerializationHelper.Serialize(info, this); } #endregion [SerializeAs("Name")] public string Name; [SerializeAs("Number")] public int Number; [SerializeAs("RealNumber")] public float RealNumber; } Now, probably the most interesting point to take note is that, i can set the values of private fields via runtime reflection. Bug/loophole, or feature? I'll leave that for the reader to decide. PS. Reflection rocks!
  2. Since the core application might be abstracted from the presentation layers, most core game objects would have to be serializable to and from a stream. This implies marking an object with SerializableAttribute at the least, so that the member data can be properly serialized. However, this default serialization would mark each piece of data as its variable name, and the variable name could be less than desirable at times. Of course, I could always rename the variable name, but there are times where I probably cannot use my preferred name. I then search around in the framework to see if there's any serialization attribute where I can actually specify the name I want the variable to be serialized as. Surprisely I found none, except for xml serialization. Those attributes can't be carried over to soap nor binary serialization, so I had to forgo those. Not finding such an attribute, I decided to create my own, as well as helpers to serialize all marked variables in a class. Now, I would have to inherit from ISerializable, and implement both the constructor and GetObjectData methods to make a class serializable. I'll explain the reasoning for custom names in my next post...
  3. Logging is another essential tool of every developer. Logging provides the developer with logs of the application flow and state, which are essential information used in solving bugs. One can argue that a debugger is more powerful and useful than logging, and bugs should never make it to deployment. The latter statement is too idealistic, since not all input to the application can be controlled perfectly, and unexpected input or steps might cause unexpected application state. Logging can help us track the steps the users take, allowing us to (hopefully) reproduce the bug, and exterminate it. A program log is also a more friendly way for users to report bug, as compared to asking the user to 'try to remember what they did before the bug occur'. I could create my own logging utility, but I am not so confident that I can invent a better wheel. Instead, I will write a small simple abstraction logging layer over an existing 3rd party logging utility. Why another layer of indirection? Quite simply to decouple the 3rd party logging utility from the application, in the event that I wish to change to another 3rd party logging utility. I searched around, and between the Microsoft Building Block's Logging Framework and log4net, log4net seems more 'interesting'. Granted though, log4net is probably overkilled, when a simple file logging class could do...
  4. Probably a quick description of the development process. I am using Visual Studio 2005 as my development environment and C# as my primary development language, on a Windows XP Pro with IIS 5.1, .Net Framework 2.0 and WinFX SDK Jan CTP installed. I start off with a mind map of the game features, using the tool: Free Mind. The mind map should be sufficient enough to serve as an overview of the game components. Next (which is the current stage), I would outline the application components/architect/flow. This would again, be a high level outline. A short description of each component would be written as well. A simple schedule, or roadmap would be then produced. This will be a form of progress indication for the project. The follow up process would probably be slow and iterative. I would pick a particular component, do a more detail design (in terms of gameplay, application flow, communication, etc). After implementation, I would follow up with a journal entry, and the process would repeat until the game application is complete. Depending on cases, I would employ unit tests/test-driven development on the component. The choice of unit testing tool would most likely be NUnit. Subversion repository would be set up locally (though ideally it should be remote), and check-in performed after each milestone of the component schedule (be it minor or major). At the very least I would have a roll back capability of source code if required. And finally, on the code documentation aspect. With C#, the most logical choice would be the xml commenting feature it supported. I could either externalize the comments of have it within the source. On the issue of externalizing the comments, I might stress that it is NOT a good idea. First, having comments in another file can easily cause inconsistencies. The comment might, at a later date, no longer reflect what the method/field/class do. This is mostly due to neglience, and is pretty common if the comments are just not at the place where you change the code. The xml commenting feature, however good it may sound, might prove excessive in cases. Unless you do wish to generate a help documentation out from code, they are not necessary. In my case, I do not intend to generate the help documentation (or at least not one that is as comphresive), so having the xml comment reiterating what the method does even though the method name is clearly explainatory is... excessive. As such, comments would only be used in places to furthur describe the internal workings of a method (though in such a case, one should always consider renaming the method to be more self-explainatory, or if it gets too long, consider refactoring it into multiple smaller methods). Taking a step furthur, I create addition attributes to furthur help in the commenting. NotNull, ValidString are examples of attributes I can apply on parameters (ideally it would be good if they can be enforced as invariants, but I believe I need to use Spec# for that feature). Additionally, Document, Summary, and ToDo can be applied on classes, methods, events, etc. In this way, the comment are 'embedded' into the code, and even read when the final product is reflectored. Of course, I have to agree that these could be excessive baggage to carry around... I hope I can get around to posting the application outline in my next post.
  5. After almost two years of having a gdnet+ journal, I've finally decided to start writing on it. First off, to justify the WHY of this writing: I needed to start a project to fuel my desire to learn and experiment new technology. A game related project would be more fun, though I am going to try my best to employ enterprise related practice and terminalogy into it (This could act as a demo as well if I am to look for a non-game related job). I want to start a development journal on the project as well, to document and discuss the various technology used. A personal blog site could be easily set up, but it would not have the traffic gamedev current has (not that traffic == good, but more traffic might mean more constructive comments). Next, for a brief description of the project. No, AV does not mean adult video, you dirty minded eechi hentai. It's a code name! And no I'm not saying what it is yet! It will be an online game (notice the omission of multiplayer) using the web browser as the front end. In a vague overview the game would probably feature the player recruit, train and send bands of units on missions (Shameless plug for www.lordsofmidnight.com , which influenced the game idea to some extent, though i MUST stress that the original idea existed before I knew of it), unlock areas, etc. I do have a mind map of all the game features I would like in it, but I'll refrain from revealing it because the primary purpose of this project is still technology first, game second, and posting the game feature list might lead to discussions on the game play instead of the technology. Note, if you do intend to make a game, please, do not do it this way. Get a comprehensive Game Design Document up first before you start development. The choice of a web browser is primarily to experiment with Atlas, Microsoft's Ajax solution (in a way, some might argue it's more than just Ajax). On a later phrase, window clients might be developed which connects to the web services exposed from the server, but that's unconfirmed (and even if I do that, it might be using avalon, xaml, browser control, or whatever's interesting at that time). A main game world application might be running constantly, and highly likely as a window service (I might justify that when I get to develop it). Remoting would be used to talk between the web application and the game world application, and Indigo/Windows Communication Foundation could be used for that task as well. Database software have not been decided yet. I would need to check up on the licensing scheme of SQLExpress. The Web server would be IIS, using ASP.Net 2.0 (please, do not even suggest mono on apache). The time might be long between posts, depending on how busy I am, and what new design decisions/technology discoveries I made.
  6. In the designer window, create a ContextMenu. Assign it to the NotifyIcon.ContextMenu. If you need menu item customizations, override the ContextMenu.Popup
  7. On a glance the code looks ok. You might want to set your browser to prompt for each cookie set to verify that it is sent. If it is sent, it probably would be a cookie timeout issue. I'll attached a code I had working HttpCookie cookie = new HttpCookie(".ASPXAUTH"); cookie.Value = Cryptography.Encrypt(userName); cookie.Expires = DateTime.Now.AddYears(1); Page.Response.Cookies.Add(cookie); Probably the only difference we had are the .Secure. On initial thought I was going to suggest to not care about session timeout and recreating the user IPrincipal with the Application.BeginRequest or AuthenticateRequest, but on second thought that would be a serious security loophole. My question was, why do you need to 'say with confidence that the session has timed out'? If the session does not exist, it is timed out, the Page.User or/and Page.User.Identity would be null. What more gurantees do you need? If you are using Windows Authetication, wouldn't furthur accessing the page prompts the dialog again? (Assuming all your resources are locked with an entry in web.config the allowed roles and users)
  8. You have the right of it. Delegates are quite the c++ function pointers, just more powerful. A delegate requires a method definition, (eg, void delegate ABC()), and can be applied to both static methods, or instance methods, which cannot be said for C++ function pointers. A delegate also, from initial observation, hold a strong reference to the instance it is created from (hence the use of proxy objects to hold additional data to pass to, or perform like a bind to other methods) A delegate, created, also provide asychrnous invokation, via BeginInvoke and EndInvoke (IIRC the method names) On a side note, I would strongly suggest trying the delegate asychrnous invokation to thread creation, since it is much easier to use, and take advantage of the .net threadpool. Interesting, event are essentially a MulticastDelegate. Imagine MulticastDelegate as a list of delegates. You add and remove delegates to it via the += and -= . It also provide a quick way to check if there is any delegate in the list via the != null operation, and quick invokation via EventName(), which will invoke each delegate in the list. Of course, there are more to it, and some synchronization pitfalls to take care of... Even more interesting, however, is that the .net platform, or rather the MSIL code, as of my maybe outdated understanding, does not provide special support nor understanding for Events, except as a flag tagged to the existing delegate, to be interpreted or handled specially by higher level languages. I would highly recommend the book Expert .Net C++ Programming from APress. It would provide a good understanding of the workings of the .Net platform.
  9. How about text-based games? Rpg, adventure, strategy, or simulation, etc. This might save time from fancy graphics development and place emphasis in game development. Not to mention it gives most beginner a chance to take part (if they don't know how to do Console I/O I seriously doubt they can do DirectX/OGL/Win32/SDL/Whatever)
  10. dot

    Books to get, Books to get...

    Quote:Original post by Rixter I have heard Code Complete is a really good book, I plan on getting it, any thoughts on it? I got the first edition. That book, along with Writing Solid Code somehow changed me. I can't recall what the content were, and how it changed me, but for sure I came out a better programmer. My friend recently got the second edition of Code Complete, and the updated version seems better. Another book I would recommend is The Pragmatic Programmer. Back to a slightly heavier game development note, As TRE recommended, Real Time Rendering, and 3D Game Engine Design is definitely interesting. I'm not too sure on the two book you're getting. The first justification, well, I'm sure the DXSDK docs are a better reference (especially since you said you do know it fairly well).
  11. dot

    Templates

    Quote:Original post by civguy Quote:Original post by dot Imagine For loop, While loop, Do-While loop, If, Switch, etc all computed at compile time!I've read MCPPD but not the latter book, and that sounds very basic. Can you give a short example of how those are revolutionary? As stated by CoffeeMug, I wouldn't say they are revolutionary, just an eye opener, or even mind boggling. (And personally, i have yet to find practical reasons to use them yet. But they are simply neat to look at for now) I'll try typing a snippet of how they implement the fibonacci numbers with their for loop construct. template<int n> struct Fib { enum { RET = FOR<1,Less,n,1,FibStat<1,0> >::RET::x }; }; template<int from, class Compare, int to, int by, class Statement> struct FOR { IF<Compare::template Code<from,to>::RET, FOR<from+by,Compare,to,by, typename Statement::Code<from>::Next>, intimate::STOP<typename Statement::Code<from> > >::RET::RET RET; }; struct Less { template<int x, int y> struct Code { enum {RET = x<y }; }; }; template<int x_, int y> struct FibStat { template<int i> struct Code { enum {x = x_ }; typedef FibStat<x+y,x> Next; }; }; namespace intimate { template<class Statement> struct STOP { typedef Statement RET; }; }; template<bool condition, class Then, class Else> struct IF { typedef Then RET; }; template<bool condition, class Then, class Else> struct IF<false, Then, Else> { typedef Else RET; }; I hope I didn't mistype anything above or miss out any constructs.
  12. dot

    Templates

    If you think Modern C++ Design was an eye opener on templates, wait till you read Generative Programming: Methods, Tools, and Applications, Chapter 10, Static Metaprogramming in C++. Imagine For loop, While loop, Do-While loop, If, Switch, etc all computed at compile time!
  13. Quote:Original post by snk_kid this would be impossible to do with java interfaces and i think also with Objective-C protocols. When you talk interfaces, do you mean the actual interface keyword, or the interface that the external world sees this class? If it is, yes it can be done. public class A { public final void Process() { DoProcess(); } protected void DoProcess() { ... } } Quote:Original post by petewood I was reading Herb Sutter's new book, Exceptional C++ style, and found one of the Items on class design very interesting. He suggests that for good design you would by default make virtual functions private. That would be by default. If a derived class really required access to the base virtual function then you could make it protected instead. But only if the design called for it. And you would never make the virtual function public. All public functions would be non-virtual. Actually, no. In his book, if you see the first Guideline, it says (as well as in the link) Quote: Prefer to make interfaces nonvirtual With a very quick follow up, Quote: Note: I'm saying "prefer" not "always" Quote:Original post by CoffeeMug Quote:Original post by Washu If CoffeeMug wishes to bitch about such things, fine, but this is not the thread for that. Jeez, I just meant to say that this idiom isn't very practical (although it may, in fact, be superior to public virtuals). For instance, have you ever worked with large products that attempt to hide implementation in a different class? (forgot what the pattern is called, below is a code snippet) *** Source Snippet Removed *** Generally a nice idea, discussed in depth by the GoF, Myers, appears in high profile articles every once in a while, has lots of benefits, but is the biggest pain in the ass when actually used in practice. The time it takes to manage this idiom far outweights all potential benefits it has to offer. There's a few terms, namely firewall (iirc from Large Scale c++ software design), and pimpl (from meyer's). The argument for this in the former book mentioned was that it reduces compilation time, because implementation as stated is hidden, and all other files that include this header file has no need to be recompiled. This is possibly a rather invalid argument nowadays as compilation time has gotten shorter and shorter with more powerful cpu. (In fact, a lot of suggestions in that book seems to be starting to be unneccessary) Quote:Original post by Anonymous Poster Wouldn't this break encapsulation since writers of sub classes need to know some private specifics of the base class? Private are in essence accessibilities specification, not visiblity specification. Technically, the other program can still see the private members. Sutter's latest book mention a few examples in which, because that the program still see private members, name lookup for methods and such get screwed up because the first match has been found, only to have the compiler reject the compilation because it can be seen but not used. Quote:Original post by Etnu Personally, i see no problem with it if it's using PROTECTED functions in this manner (makes sense), but it seems silly to use PRIVATE functions for it; I mean, why? That's just pointless, because then the derived classes have to know the private functions of the base class. They shouldn't. But then people like to raise a fuss over protected functions, too. You have provoked a thought in me. Is there really absolutely any serious reason to only provide the methods to its child class? The very purpose of inheritence is provide customization, via overriding of virtual methods, correct? Could one not design all the neccessary protected methods as public, as it will furthur enrich the class by exposing more functionalities, as well as allow the external users to furthur utilize it? Also, if you're saying that "no, only the derive class need to use it. Only they know how to use it", are you not violating the encapsulation of the parent class, by invoking methods because you know the very 'internal workings' of the parent class? Not to mention you are assuming all programmers of derived classes know how to use the methods correctly. Quote:Original post by snk_kid here is something i found on gamearchitect.net that gives something to think about: Quote: This problem can be ameliorated somewhat if you don't publicly expose virtual functions, but instead use the Template Method pattern[3], or what Herb Sutter calls the "Nonvirtual Interface idiom"[8]. That is, have a base class consisting only of public non-virtual functions which call private virtual functions. The non-virtual functions can perform whatever base-class-specific actions they require before calling the private virtuals. This still won't help, however, with deep class hierarchies where leaf classes need to pass through function calls to intermediate parent classes, not just the root class. Slightly off topic in c++, but this sounds like a perfect candidate for a delegate in c# As noted, the NVI pattern sutter prefered to dubbed his idea, works perfectly well in cases where you only need a single entry point to the method, with a customizable method depending on the derived class. This all breaks down, of course, when you furthur derive the class, which seemingly in this 'idea', requires you to scream at the programmer to remember to call parent::method, or create another template pattern for which furthur derived class can override (ooh god this will be painful). Another point to add, from his book, he mention clearly that (this took a while to type) Quote: It is recommended that you provide customization through protocol (family) methods. The public interface of a base class should provide a rich set of functionality for the consumer of that class. However, customizers of that class often want to implement the fewest methods possible to provide that rich set of functionality to the consumer. To meet this goal, provide a set of nonvirtual or final public methods that call through to a single protected (family) method with the 'Core' suffix that provides the implementations for such a method. Such pattern is also known as 'Template Method' Note the mention of public interface of a base class with rich set of functionality, customizers to implement the fewest methods possible, as well as a set of public methods that call through to a single protected method. This is suggesting that the protected virtual methods are much fewer than the public final methods, of which they base off from to provide that customizable functionality. Not a one to one relation which it seems the thread was misled as. Note also the mention of protected/family virtual because private virtual is not allowed in c# iirc.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!