PDA

View Full Version : Spread code over multiple files



Bijo
01-06-2007, 04:23 PM
System: WinXP Pro SP2
Compiler: FPC
Libraries: -


Basically I want my experimental (for learning purposes) simple console text adventure's code that's in one file to be spread over more files, like some kind of modularity. (It's more for ease of reading, though I think it's fairly readable with the use of a search in my text editor, but even then it's useful to know.)

As the straightforward hobbyist, I usually (from what I've learned anyway) start my main() and put my non-existent procedures/functions into it, like so....
///--->
begin
do_inits;
tell_story01;

choose_class;
ask_showclass;

tell_story02;
idle_state;
ask_usepotion_firsttime;

tell_story03;
idle_state;

tell_story04;
end.
///<---


Then I declare the functions above the main(), and some of them are called by others. For instance, do_inits() has...


procedure do_inits; begin
init_classvalues;
welcome_screen;
verify_userdata;
set_textspeed; //goto main()
end;


Now, I got a whole bunch of procedures declared and described all above my main(), so you can imagine my source file is kinda big.

By looking at the code snippets above, can you give me an example (optionally based on them of course) of how to apply modularity over separate files?

I *THINK* I could somehow take out code here and there and put it into a separate file and in the main file use uses and the name of the file, but I'm not so sure on it. I just want to do it the right away and avoid disappointments :)

WILL
01-06-2007, 05:16 PM
I believe what you are looking for is units. :)

Units are a great main-stay of the Pascal and Object Pascal languages. All you simply have to do to use them is

uses
TheNameOfYourNewUnit;

and you're ready to go.

More than one unit...

uses
FirstUnit, SecondUnit;

Easy as pi. ;)

As far as making your game more 'modular' I'd recommend taking a look at OOP. (Object Pascal being of the best at this!)

The idea of OOP is that everything in your game is made into an object. Each object in your game is of a specific class. An easy way to think about this concept is that all your game objects are like ships and each of them of a specific type of ship, which is your class.

Each object has a way to be made with a constructor and unmade with a destructor. There are basically functions and procedures as you learn from Standard Pascal only they are for the purpose of creating and managing your objects.

The coolest part of OOP is that each class can be a parent of a new class. ie.

type
TSon = class(TDad)
StuffInside: Integer;
// etc...
constructor BeMade(stuff: Boolean);
destructor BeUnmade(stuff: Integer);
end;

See? Thats your basic object class definition. Easy stuff isn't it? You can have as mand constructors/destructors and all that fun gooie stuff inside as you like, it's your object!

Cool thing is that TSon will have everything from TDad as well, so if there are constructors, etc in TDad TSon can use them. TObject is the most basic of object classes though. Think of it like a base class.

Anyhow it can get a lot more complex than that, but I figured it would give you an idea of what OOP would do for you in making things more modular and flexible.

If some of this went over your head don't worry, just grab a good book that probably explains it a lot better than I have.

Bijo
01-06-2007, 06:08 PM
Thanks WILL :)

I'm looking into the units thing and I understand that a self-made unit should be in a separate file, and in it there should be unit identifier_that_is_filename (though I haven't tried yet in the code, still learning its way). This in combination with OOP looks very useful and powerful.

Thing about OOP is, though, I understand the concept of it when I was learning C++, but I'd never used it because it was a bit too confusing to apply code-wise. But the overall picture is simple.

I'm kind of comfortable with minimal procedural stuff so I've been avoiding OOP. But isn't a (C(++)) struct or (Pascal) record "kind of like a class", but without constructors and methods and such?

Do you think I should really hit OOP or do you think I should continue doing procedural until I have that perfectly under control? I ask this because OOP to me looks like it's just a step higher for more general natural control, even though it looks like I'd still rely on using procedures/methods, so it looks logical to perfectly know procedural programming first.

JSoftware
01-06-2007, 06:26 PM
Do you think I should really hit OOP or do you think I should continue doing procedural until I have that perfectly under control? I ask this because OOP to me looks like it's just a step higher for more general natural control, even though it looks like I'd still rely on using procedures/methods, so it looks logical to perfectly know procedural programming first.
You are correct. You should master the normal procedural programming first to some degree to benefit from OO programmming

Your approach in the OP is called Top-Down programming which I also after a lot of years programming still use. The nice thing about it is that you'll have to write the underlying procedures so you can't slack in the initial stages :P

WILL
01-06-2007, 06:56 PM
You probably should learn the basics of Pascal first as it will give you a solid base to build up your knowledge for Object Pascal. Everything is the same except for the extra OOP stuff.

And you know what? I completely forgot to put up the code structure for a unit. :P Sorry, I was thinking of doing that, but I guess posting from work has it's pitfalls huh? ;)

unit TheNameYouWant;

interface

implementation

end.

Thats it. And example of usage would be...

unit TheNameYouWant;

interface

// Global Stuff

uses
Math;

var
gText: String; // Can be accessed by this unit and other units, libraries and programs

// Any optionally globally accessible functions/procedures go here

procedure DoThings; {You only have to declare your local procedures/functions here to use them globally!}

implementation

// Local Stuff

var
lNumber: Integer; // these can only be accessed within this unit!

procedure DoThings;
begin
// Whatever this thing does.
end;

// begin
// If you include a code block at the bottom of your unit
// all of the contents will auto execute. This is handy for
// some unit specific auto initialization, etc...
// Of course this is only optional.
end.

I think you should be fairly good to go with that example. Play around with it and try things. And of course ask if you get stuck. ;)

Bijo
01-06-2007, 08:35 PM
Thanks for the infos :)


That with the unit thing is kind of confusing. Keywords like implemenation and interface are the worst. I expected self-made units to be exactly similar to a program (where the program keyword is replaced by unit) but just without the main(). I think I'll just keep doing my familiar stuff and take it slow and easy with this one :)

WILL
01-06-2007, 08:48 PM
Keywords like implemenation and interface are the worst.

Really? I'd say that they are the least complex of everything I've showed you. :)

All they do is tell the compiler when it's time to process global declarations and and when to do the local declarations and code. Thats all they do really.

Do you know the difference between a global variable and a local variable? I think that might be the start of your confusion. Mind you the concept comes up, or should have, when you learned functions & procedures.

Bijo
01-06-2007, 09:10 PM
Keywords like implemenation and interface are the worst.
Do you know the difference between a global variable and a local variable? I think that might be the start of your confusion. Mind you the concept comes up, or should have, when you learned functions & procedures.
From what I know, a global variable is accessible throughout the whole program and a local one is accessible only by the function that has it.

Huehnerschaender
01-06-2007, 10:06 PM
That with the unit thing is kind of confusing. Keywords like implemenation and interface are the worst.

Hi Bijo,

you said you know C/C++.

Consider the Interface part as your .h file while the implementation part is your .c/.cpp file.... thats all... the same thing, but in one file!

Greetings.

Bijo
01-06-2007, 10:46 PM
That's a bit difficult to imagine well for me, 'cause I terribly misused / abused header files when using C++ :oops:

savage
02-06-2007, 08:58 AM
Hi Bijo,
I hope I don't add more confusion, I used to teach Object Pascal, so I hope I can transfer some of the knowledge.

Think of interface and implementation as areas of scope or visibility. Any code or definitions that you put in your interface section is accessible from other units. While code or definitions that you put in your implementation section is only accessible/visible to things within that, and only that unit.

For example:

unit MyFirstUnit;

interface

procedure MyVisibleMethod1;

procedure MyVisibleMethod2;


implementation

procedure MyInvisibleMethod1;
begin
// Do the lambada here
end;

procedure MyVisibleMethod1;
begin
// Call Method declared in my implementation section
MyInvisibleMethod1;

// Call Method declared in interface section
MyVisibleMethod2;
end;

procedure MyVisibleMethod2;
begin
// Do the funky chicken here
end;

end.



unit MySecondUnit;

interface

procedure MyPhatMethod1;

implementation

uses
MyFirstUnit; // If this is not here we cannot access the visible methods

procedure MyPhatMethod1;
begin
// Now use the Visible Method from MyFirstUnit
MyFirstUnit.MyVisibleMethod1;

MyFirstUnit.MyVisibleMethod2;

// The following method call will not work ( will cause a compilation error
// because MyInvisiblerMethod1 is not accessible from this unit as it was
// declared in the implementation section of the previous unit
MyFirstUnit.MyInvisibleMethod1;
end;

end.


You'll notice the I prepended each method call with MyFirstUnit and you are probably thinking man that is a pain, and you would be correct. But you actually don't need that there, I put it there to clarify my point of exactly which method we are calling. That notation is used in the rare cases where 2 units might have a method with the same name, so to avoid ambiguity you specify the unit name so that the compiler knows exactly which one is meant to be called at that point.

I was going to type some stuff as to the reasons why you would put code in one part an not the other, but I think it is important to understand the concept of scope first before discussing the whys and why nots of putting code in the interface or implementation sections.

I hope this helps rather than confuses.

Bijo
02-06-2007, 10:13 AM
I think I'm getting it now. Been reading your stuff, and rereading previous posts, and it's finally hitting me.

I think what caused confusion were a couple factors: (1) my need or wish for an even compacter simpler language (Modulas or Oberons); (2) my never before having "declared functions twice" (if that's the proper description); (3) never really having used the scope principle (so far I've mainly used global variables, though I understood the local variable concept); (4) the code was not indented after putting the interface and implementation keywords (therefore automatically and visually I thought interface and implementation were empty, but all they do is signify a commence).


...Have read it again and now fully understand the general thing. Now it's just a matter of remembering it. Thanks, all of you! :) I think it'll be of good use in the future.