Results 1 to 10 of 12

Thread: [opinion][Research] API design

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Question [opinion][Research] API design

    So, I’m rewriting my engine and I’m struggling with API names.

    I was using prefixes and suffixes to differentiate the engine and subsystems stuff. For example, this program for an hypothetical action game:
    Code:
    program Game;
    
      uses
        Mingro, mngSprites, Title, Playfield, sysutils;
    
      function Initialize: Boolean;
      begin
        if mngInit and mngInitializeSprites then
        begin
          PlayerSpriteSheet := mngLoadSpriteSheet ('player.spr');
          if PlayerSpriteSheet = Nil then
            Exit (True)
          else begin
            mngLog.Trace (etError, 'Can''t load sprite sheet.');
            Exit (False)
          end
        end
        else begin
          mngLog.Trace (etError, 'Can''t init engine!');
          Exit (False)
        end
      end;
    
    begin
      if Initialize then while RunTitle do RunGame
    end.
    What I was thinking is to use the unit name as namespace, so the previous program will look like this:

    Code:
    program Game;
    
      uses
        Mingro, mngSprites, Title, Playfield, sysutils;
    
      function Initialize: Boolean;
      begin
        if Mingro.Initialize and mngSprites.Initialize then
        begin
          Playfield.PlayerSheet := mngSprites.Load ('player.spr');
          if Playfield.PlayerSheet = Nil then
            Exit (True)
          else begin
            Mingro.Log.Trace (etError, 'Can''t load sprite sheet.');
            Exit (False)
          end
        end
        else begin
          Mingro.Log.Trace (etError, 'Can''t init engine!');
          Exit (False)
        end
      end;
    
    begin
      if Initialize then while Title.Run do Playfield.Run
    end.
    I don’t see that kind of API anywhere but I think it is clean and clear and more appealing than using prefix/sufix to differentiate between subsystems (except the fact that when two units declare an object with same name and you don’t precede it with the unit name, FPC doesn’t warns and picks one resulting in some funny debug sessions).

    What do you think about this kind of API?
    No signature provided yet.

  2. #2
    It is hard to say without having access to your entire codebase.

    If you have each Subsystem in separate unit then your second code example actually seems more intuitive as you get clear information on which unit has defined certain object type. It also gives you ability to have different units for different platforms.

    But if you ever decide to put your game engine into a single package I don't think such approach would be quite suitable. I'm not even sure if this would even work if built into a single package.

  3. #3
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2
    Naming conventions... ARGH!

    I would say do whatever makes it work for you. We adapt to the different naming/organisation conventions and I personally don't really have a preference. I've tried numerous approaches and concluded some time in the future that they were all clunky or less than optimal. Now I just do what feels right at the time, although I don't publish a lot of code.
    :: AthenaOfDelphi :: My Blog :: My Software ::

  4. #4
    Quote Originally Posted by SilverWarior View Post
    If you have each Subsystem in separate unit then your second code example actually seems more intuitive as you get clear information on which unit has defined certain object type. It also gives you ability to have different units for different platforms.
    That's just why I asked. Since I put each Subsystem in separate unit I feel it is natural to use the unit name instead of prefixes and suffixes. I just wonder why it isn't used a lot.

    Quote Originally Posted by AthenaOfDelphi View Post
    Naming conventions... ARGH!
    Yeah.

    Quote Originally Posted by AthenaOfDelphi View Post
    I would say do whatever makes it work for you. We adapt to the different naming/organisation conventions and I personally don't really have a preference. I've tried numerous approaches and concluded some time in the future that they were all clunky or less than optimal. Now I just do what feels right at the time, although I don't publish a lot of code.
    That's my fear: What if it is clunky. I know it may be less than optimal since you have to write more, and it would be prone to mistakes if calling a procedure that has the name duplicated in several units without the unit name (i.e. the "Init" method). If there were a way to force to write the unit name...
    No signature provided yet.

  5. #5
    After thinking some more on this topic I must admit that I'm becoming less and less inclined to your second approach of using using unit names instead of prefixes. Why?
    As you pointed out yourself calling certain method that is implemented in multiple units with same name without providing unit name will lead to unexpected behavior. I'm not sure about FPC but in case of Delphi I believe the method from the unit that was last loaded would be called in such scenario.
    Another disadvantage of such approach is that you are basically forcing yourself to have each system in its own unit. While often this is perfectly fine there are times were you might want to have several connected systems in a single unit in order to improve code readability.
    Wouldn't this also mean that you will have to ad every unit into uses section of your main application unit?
    Also having bunch of small units could have significant affect to build time. Now wile Object Pascal compilers are know to have very fast compile times due the fact that only modified code is recompiled having bunch of small units could still lead to long build times. This mostly due the fact that linker still needs to link a bunch of small compiled code pieces together in order to build final application.

  6. #6
    You have some points here.

    I was coding some time now and besides the build time it seems nice to me. Thankfully Lazarus is able to rename all references by itself, or I can use a tool I wrote some time ago to help with Allegro.pas development, so if I change my mind I can change all identifiers. It isn't TRUNK yet.
    No signature provided yet.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •