May 15, 2024, 02:54:01 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Noob questions #1

Started by Protected, May 15, 2006, 12:34:20 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Protected

I thought I'd number them >:-) Just for the future... hours :P

I'm a *complete* noob, so I'd appreciate it if I could get answers to these:

First, what's :: for? What does it do? How does it do it?

Second, timers... It looks like the CWindow class supports them? Can I make a timer in a DX program? How? The documentation is still empty... I've looked into the tutorial in the docs forum but it doesn't seem to be advanced enough for this...


J B Wood (Zumwalt)

May 15, 2006, 01:13:15 PM #1 Last Edit: May 15, 2006, 01:48:01 PM by zumwalt
Taking the MDIDEMO.src as the example:

//MDI frame methods

MyFrame::MyFrame()
{
   m_nChildren = 0;
   //manage up to 100 children
   m_pChildren = new(int,100);
return;
}

Breaking this down, :: is a pointer to a method of the MyFrame object.
I don't know your programming background, but in vb, this is just like defining a class called MyFrame and giving it a method of MyFrame (to me this is just a default constructor)

Now lets say you wanted an method for MyFrame class called Close, you would do MyFrame::Close()
So if you create a new object from the MyFrame class, you can do:
MyFrame thisObject;
thisObject.Close()

Make sense? Someone just shoot me if I misunderstood the ::

Second part of your question, well, since there is no native 3d engine in this thing yet, you can write your own, since you can write your own, you can use your own timers with it.


Edit:

Let me translate this as C# terms:
Aurora Code:

MyFrame::MyFrame()
{
   m_nChildren = 0;
   //manage up to 100 children
   m_pChildren = new(int,100);
return;
}

C# code:

Class Myframe
{
     public MyFrame
     {
        int[] m_nChildren;
   //manage up to 100 children
   m_pChildren = new int[100];
      }
}


Hopefully this helped some.

edit again.. in vb.net terms.. this is close to:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim myInit As MyFrame = New MyFrame
        myInit.MyFrame()
        MsgBox(myInit.m_nChildren.Length)
    End Sub

Public Class MyFrame
    Friend m_nChildren() As Integer

    Friend Sub MyFrame()
        ReDim m_nChildren(100)
    End Sub
End Class


Sneaky Edit:
Yea yea, I know, I could have used Public Sub New() for the vb example, but I wanted to keep the visual wording the same :) vb.net fans don't shoot me.

Mike Stefanik

Actually, the "::" operator defines scope. CMyClass::MyFunction specifies the function named "MyFunction" within the scope of the class "CMyClass". This is important because different classes may, of course, share the same function names. What's a little odd with Aurora is that within the class itself, the "!!" operator is used to specify a member of a base class. So, if you have the class:


class CBase
{
ÂÃ,  ÂÃ,  declare virtual FooBar();
}

CBase::FooBar()
{
ÂÃ,  ÂÃ,  // do something
ÂÃ,  ÂÃ,  return;
}

class CDerived : CBase
{
ÂÃ,  ÂÃ,  declare virtual FooBar();
}

CDerived::FooBar()
{
ÂÃ,  ÂÃ,  // do something

ÂÃ,  ÂÃ,  // call the base class implementation of FooBar
ÂÃ,  ÂÃ,  CBase!!FooBar();
ÂÃ,  ÂÃ,  return;
}


Why Paul doesn't just use CBase::FooBar() there, I'm not sure. It may have to do with limitations of the parser. Where scope resolution also becomes important is if you have a global function with the same name as a class member function. For example:


global sub MyFunction()
{
ÂÃ,  ÂÃ, // do something
ÂÃ,  ÂÃ, return;
}

class CMyClass
{
ÂÃ,  ÂÃ,  declare MyFunction();
}

CMyClass::MyFunction()
{
ÂÃ,  ÂÃ,  ÂÃ, // Call the global verson of MyFunction
ÂÃ,  ÂÃ,  ::MyFunction();
ÂÃ,  ÂÃ,  return;
}


If you omitted the scope operator there, then the compiler would assume that you want to recursively call CMyClass::MyFunction.
Mike Stefanik
www.catalyst.com
Catalyst Development Corporation

Protected

Thank you, I think I get it  ;D Thanks a lot for the helpful examples and explanations! I can understand the C# one, I guess. And the Aurora ones. I have used pointers in C only.

My programming backgound:
Languages I'm familiar with: QBasic, IBasic (standard), Visual DialogScript, C, Java, TCL, LISP, PHP, ActionScript
Languages I've used but not familiar with: Assembly, Scheme, Aurora ;P

I am not going to do anything with 3D. I'm only interested in 2D, and that class is already in Aurora, so any ideas about the timer thing?

J B Wood (Zumwalt)

Isn't that just a double definition for a replacement of this.?
this.method vs ::method?

Scope being that of the class? vs global scope?
That will get confusing even for me.

CBase::Foobar() is a method of CBase
CDerived inherits cBase, thus :, which is similar to C#
CDerived uses the method of FooBar when you call it as CDerived::Foobar() using the base of CBase's foobar by pointing at Foobar through CBase!!Foobar().

Why can't we just simply do:

class cBase
{
    public FooBar()
    {
    }
}

Since we can't, I took it as the above is simply
cBase::FooBar()
{

}


edit: sorry for quick post, didn't mean to take this off track, I have no idea on the timer thing, haven't even messed with it yet.


Protected

What's the "virtual"? That's a question I Wanted to include in the top post but I couldn't remember the word :P Is it a method that's only defined later?

LarryA

May 15, 2006, 02:59:20 PM #6 Last Edit: May 15, 2006, 03:01:14 PM by LarryA
"Aerodynamics are for people who can't build engines." -- Enzo Ferrari
"Turbochargers were for people who can't build engines" -- Keith Duckworth

Protected

Hey Larry.

Do I need to create a non-DX window to handle the timer? Can't I have a timer in a DX window?

kryton9

I am so lost. Almost 30 years of programming in procedural style and even then most of the time where all the code is one place. Just when things go into include files, libraries, other source files and then you add classes to the mix it is very very confusing.

I can ask a zillion questions, but to just get some understanding. writeln for example is coming from somewhere, but it is part of aurora but it is not a keyword. How would I know to use it without some help? Is there anything I could look through to see what is available and where?

About classes, I know oop is the future and it is awesome, but there is so much stuff elsehwere you have no idea what functions (methods) are available with what class and where it came from.
For instance if I had class 1, then I derived class 2 and then from class 2 I derived class 3. Each having their own methods, how do I know where the methods are in which class and how to look at what else there is I can use? Especially when it is burried in a compiled dll or library somewhere? At least with regular structures you can see the history of the structures in the naming with the .'sÂÃ,  ÂÃ, struct1.struct2.struct3.propertyÂÃ,  ÂÃ, how would I know what classes my class is derived from if it is off somewhere else?

I did some maps for unreal tournament 2004 last year and they use oop a lot, in fact everything is an object. Anyways in setting the properties for the objects, I would see so many properties that did not apply to what i was using, it almost became a crazy thing just to set the porperties for what I could set too. There is so much unecessary things being sent to the classes further down the road from the parent classes that you wonder just how useful it really is? Why not just create a new class for that object or each object and be done with it.

I don't want to seem like I am complaining, just for the unintiated like me... i wanted to express how confusing this stuff seems to us non oop programmers.

Just to show you how lost I am... do I have to make a class for a window each time and assign it and write all the functions for it each time? I know I could copy and paste, but kind of really confused on all of this.

What is virtual and :: and so forth. I read the previous replies going over it but still am confused.

Thanks, sorry to be such a newb.

Protected

What do you mean by each time? Each time you create a window in the same program? Does your program require you to create different windows on the fly? Or is it each time you write a new program?

If you have to use the same type of window repeatedly, you can just make a function to create it (or if there are several operations you perform on it, you make a class that extends it).

A child class, at least in java, has the methods of the parent, plus any methods you add to it. If a method has the same name, number and type of arguments, it replaces the method from the parent class. You can refer to methods from the parent class using super. You are required to call the constructor of the parent class from the constructor of the child class. Notice this is all java, i'm still beginning with Aurora.

There is a list of classes with all methods and properties in the user guide / reference. There is a separate help file for the directdraw classes.

Ionic Wind Support Team

Protected,
A virtual method is a replaceable method.  In other words if you derive a child from a parent class, and that child has a virtual method with the same name. Then that function gets called instead of the parents.  The !! operator forces a call to the parents version of the method when used within the child.

The C2DScreen class derives from CWindow so you can use all of the methods (functions) from CWindow as well as the ones from C2DScreen.  A timer can be created in the screen, given a C2DScreen based object, using the StartTimer method.

Overriding virtual functions is how you handle messages.  On the tools menu open up "Class Maker". 

After it loads double click on the CWindow class and choose OnTimer, Click the ">>" button to signify you want to override that method in your new class.  Enter a name for your class like "MyScreen" in the "Derived Class Name" edit box, enter "C2DScreen" in the "Base Class Name" edit box.  Click on "Generate".

Paste the results in a source window which will give you this:


//MyScreen definition
class MyScreen : C2DScreen
{
declare MyScreen();
declare _MyScreen();
declare virtual OnTimer(int nIDEvent),int;
}

//MyScreen Implementation
MyScreen::MyScreen()
{
}

MyScreen::_MyScreen()
{
}

MyScreen::OnTimer(int nIDEvent),int
{
return 0;
}


Now what you have is a skeleton class.  Add a main function to create a screen, start the timer, and put the code in OnTimer to handle the events:


//MyScreen definition
class MyScreen : C2DScreen
{
declare MyScreen();
declare _MyScreen();
declare virtual OnTimer(int nIDEvent),int;
}

global sub main()
{
MyScreen s;
if(s.CreateWindowed(0,0,640,480,AWS_VISIBLE|AWS_SYSMENU,0,"Test Window",0)< 0)
{
MessageBox(0,"Couldn't open screen\nThis program requires DirectX 7.0 or greater","Error");
return 0;
}
s.StartTimer(100);
do { wait(); } until GetKeyState(0x1B);
s.CloseScreen();
return;
}



//MyScreen Implementation
MyScreen::MyScreen()
{
}

MyScreen::_MyScreen()
{
}

MyScreen::OnTimer(int nIDEvent),int
{
C2DSurface *back = GetBack();
back->Fill(RGB(155,155,155));
WriteText(0,20,"OnTimer called");
Flip();
return 0;
}


Note that you probably would not want to Flip in OnTimer, but it just illustrates the point.  Use ESC to exit BTW.

Ionic Wind Support Team

Parker

Zumwalt, you shouldn't be making comparisons to C# and .NET because Aurora is much more like C++, and it's just more confusing for new users.

!! is used because it would require lots of strange hacks to get x::y(); to be seen as a call and not a definition in yacc.

LarryA

Quote from: Ionic Wizard on May 15, 2006, 04:58:50 PM
The C2DScreen class derives from CWindow so you can use all of the methods (functions) from CWindow as well as the ones from C2DScreen.ÂÃ,  A timer can be created in the screen, given a C2DScreen based object, using the StartTimer method.
I was going to say that, based on a couple of clues in the docs, but my confidence that I was right, on a scale from 1 to 10, was about 1.3  ::)
"Aerodynamics are for people who can't build engines." -- Enzo Ferrari
"Turbochargers were for people who can't build engines" -- Keith Duckworth

Protected

Thanks a lot for the information and the detailed example, Paul :-) I'll give it a try tomorrow, hopefully (if I have time)... The timer is not for flipping, it's for updating the positions of the objects in the 2D world. I must know the interval between updates (and it must not change between computers) so I can implement velocities and such.

J B Wood (Zumwalt)

I guess your right, I'll keep my understandings to myself, cause I see Ionics defintion of virual as overloaded methods and overriden methods, just different naming, same thing. Its just how I understand it, so it helps me :)

Mike Stefanik

Virtual methods are more than just overrides. They're a key part of polymorphism, which allows the method in a derived class to be called correctly if the object is passed to a method that expects the base class (because the derived class object is a kind of base class object). For example:


class CShape
{
    declare virtual Draw(int xPos, int yPos);
}

class CSquare : CShape
{
    declare virtual Draw(int xPos, int yPos);
}

class CTriangle : CShape
{
    declare virtual Draw(int xPos, int yPos);
}


Here you have a base class, CShape, and two derived classes, CSquare and CTriangle. They have a virtual method, Draw, which is responsible for drawing the particular shape. The idea is that CSquare overrides Draw to draw a square, and CTriangle overrides Draw to draw a triangle. Simple enough so far.

Now, lets say that you wanted to write a function that would tell any CShape derived class object to draw itself. This is how you could do it:


sub DrawShape(CShape *pShape, int xPos, int yPos)
{
    if (pShape)
        pShape->Draw(xPos, yPos);
}


That would allow me to write code like this:


CSquare *pSquare = new(CSquare, 1);
CTriangle *pTriangle = new(CTriangle, 1);

DrawShape(pSquare, 100, 100);
DrawShape(pTriangle, 200, 200);


The reason that works is because when the compiler sees that the Draw method is virtual, it calls the method in the derived class, not the base class. In other words, it knows that a CSquare and CTriangle object are a kind of CShape object. So in the first instance it calls CSquare::OnDraw and in the second instance it calls CTriangle::OnDraw. Without the "virtual" designation, it would call the CShape::OnDraw method which would (presumably) do nothing.

Hope that makes sense.
Mike Stefanik
www.catalyst.com
Catalyst Development Corporation

Ionic Wind Support Team

Of course, but I was trying to keep it simple for him first ;).  It is easier for new users to think of them as 'replaceable' before getting into the mind bending terminology of polymorphism.  I think the biggest stumbling block new OOP users face is the oddball terminology the CS world uses in describing something that is, in essence, relatively simple.

If you have a grasp of function pointers and structures you can get the hang of OOP programming in a matter of hours, if it is explained correctly,  An object is really just a structure.  An object with virtual functions is a structure with an array of funciton pointers as its first member.  A derived object is a nested structure.  A virtual function in the derived object replaces the address of the base class function in that array of pointers.

Those that have programmed in assembly seem to grasp OOP concepts easier than those that have only been exposed to procedural BASIC languages.  Mainly because you're used to calling functions with a pointer.  call [eax] for example.

Polymorphism works because you are changing that pointer in the array of function addresses.  And as Mike has tried to lay out is it allows for the generic coding of a function or method that can accept a base class parameter yet still call the correct method in the derived class.
Ionic Wind Support Team

Doc

QuoteI think the biggest stumbling block new OOP users face is the oddball terminology the CS world uses in describing something that is, in essence, relatively simple.

...'nuff said.  :'( :o ::)

-Doc-

J B Wood (Zumwalt)

Polymorphism is nothing more than defining a skeletal structure in a base class so that any derived classes have to override the structure of the virtual method. Polymorph is to alter or change the defined behavior or a method but not its shape. Meaning you 'must override' and define it in the derived class even if you do nothing with it. For purposes of all OOP, its the idea of generating empty method templates or skeleton structures with no 'body' or 'meat', when you create a new derived class which inherits from a base class, that includes a virtual method, you must override that method and define its 'body' in the derived class. Its not an option, the compiler will tell you that you are missing a definition for that method.

So of course if you have a shapes class with a virtual box, and you turn around and inherit that class, you have to give box a meaning for that derived class, then when you use that derived class, the compiler knows you need to use the body of the box from that derived class. Its really overrated, and good for giving consistancy in programs. I have had to write tons of virtual methods and give out the module to people so that they can build other methods to inherit from the base class with virtual methods which are used as templates to building larger classes.

Heck, at Devry, we had 4 weeks on the polymorphism subject alone.

Mike Stefanik

Quote from: zumwalt on May 16, 2006, 07:05:32 AM
Polymorphism is nothing more than defining a skeletal structure in a base class ... when you create a new derived class which inherits from a base class, that includes a virtual method, you must override that method and define its 'body' in the derived class. Its not an option, the compiler will tell you that you are missing a definition for that method.

It's a bit more than that, and that's only the case for pure virtual methods in a class. Aurora doesn't support pure virtual methods in a standard class, but it does support abstract base classes (where all methods are pure virtual methods) by using the "interface" keyword.
Mike Stefanik
www.catalyst.com
Catalyst Development Corporation

Protected

I see... Well, I'm used to Java. Aurora seems to be like Java in a few aspects, but different in many others. Would I even be able to access from a child class a method of its parent class that was redefined in the child, without creating a method in the child for the purpose? I mean, in Java. I see that it's possible in Aurora...

Ionic Wind Support Team

Ionic Wind Support Team

Mike Stefanik

May 16, 2006, 04:13:15 PM #22 Last Edit: May 16, 2006, 04:15:41 PM by Mike Stefanik
Sure, just keep in mind if it's a pure virtual method, you'd have to implement it; there's no way to directly create an instance of an abstract class. If it's just a virtual method then you can use implementation in the base class or provide your own. Java has both interfaces and abstract classes, and they do somewhat similar things but there are some significant differences. An interface contains no code at all, an abstract class can have default implementations (or just stubs).

In terms of Aurora, you can either have classes or interfaces, but there's no such thing as an abstract class.
Mike Stefanik
www.catalyst.com
Catalyst Development Corporation

Parker

In java I think you would write super.SomeMethod, in Aurora you would write BaseClass!!SomeMethod, where BaseClass is the base class. In java you don't substitute names.

Protected

I think some of us are writing about different things  :o let me try to understand...

You would write super.SomeMethod, but you'd have to be inside the class... You wouldn't be able to do it from the outside, or would you?

So a virtual method is an 'abstract method', basically... A method that must be replaced...?

Paul, sorry, but of course what? :P