Jump to content

Official documentation


Josh
 Share

Recommended Posts

I agree on the concept of Object myObject = new Object1(); instead of object = CreateObject().

 

It is a personal choice though:

New programmers will probably like the CreateObject() command because it is a slightly more obvious command. More experienced programmers will like the resemblance with the C# like structure.

 

The main difference is that when creating the object using a Create method

you can always have objects as members of another class and don't have to

use the new command. When having the creation in the constructor (along with argument)

you have to have the object as a member pointer in a class and the use new Object

to create it, and of course delete object in the destructor.

 

Personally I have no problems with this, but some folks seems to be scared about

using new. The reasons for be afraid of new and pointer are to me a bit irrational,

but I have noticed that this phenomena exists.

 

I would personally go for the creation in the constructor, but I can understand

that some finds the Create method to create feels better.

 

There are though some problems with having a Create method.

Here is a little code snippet from a test program of my Cells GUI that

shows this.

 

 GuiImage* pgui = new GuiImage( (GraphicsWidth()-800)/2, (GraphicsHeight()-600)/2, "abstract::goback_n", GuiAll ) ;
       pgui->AddChild( new GuiButton( 10, 10, "abstract::a", GuiAll, "A", &click ) ) ;
       pgui->AddChild( new GuiButton( 266, 10, "abstract::b", GuiAll, "B", &click ) ) ;
       pgui->AddChild( new GuiButton( 10, 266, "abstract::c", GuiAll, "C", &click ) ) ;

 

As you can see I use the creation by constructor as this I the way I prefer.

In this example adding new childs is quite simple by adding them with new.

 

Now if the construction of GuiButtons would have been done by using a Create methods

it would now have been quite so smooth. I show this alternative here below.

 

 GuiImage gui;
 gui.Create( (GraphicsWidth()-800)/2, (GraphicsHeight()-600)/2, "abstract::goback_n", GuiAll ) ;

 GuiButton b1( ) ;
 b1.Create( 10, 10, "abstract::a", GuiAll, "A", &click);
 gui.AddChild( b1 );

 GuiButton b2( ) ;
 b2.Create( 266, 10, "abstract::b", GuiAll, "B", &click) ;
 gui.AddChild( b2 );

 GuiButton b3( ) ;
 b3.Create( 10, 266, "abstract::c", GuiAll, "C", &click ) ;
 gui.AddChild( b3 );

 // note: b1, b2, b3 must bee stored somewhere as they will
 // cause null-references if they go out of scope

 

I think the samples above shows the advantage of using new instead of Create.

But as Aggror says. Its a matter of taste in the end. You get the same result

both ways, but using a different approach.

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

You can do it even easier, like I did in my GUI:

GUI gui;

gui.AddWindow("About");
gui.AddButton("About","OK");

Then you can check if the button was pressed:

if( gui.ButtonClicked("About","OK") )
{
}

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

You can do it even easier, like I did in my GUI:

GUI gui;

gui.AddWindow("About");
gui.AddButton("About","OK");

Then you can check if the button was pressed:

if( gui.ButtonClicked("About","OK") )
{
}

There are many ways to do a GUI. But thats out of topic here.

The idea was just to show the difference between using new and Create,

not to discuss Gui's specifically. That belongs to another thread.

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

Yes, but I showed also that new and Create() is both not needed. I just use a STL map and set values into it. You can do the same for any objects:

worldmap["cube1"]=Cube;   // Cube class has constructor which creates it, and then
                         // deletes after the map has got it
worldmap["oildrum1"]=LoadModel("oildrum.gmf");

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Internally STL map uses also new, but the user doesn't have to know it, and to deal with ugly forgotten delete instructions, plus setting the pointer manually to NULL after that.

 

You could use STL containers for all variables, then you have also the possibility to loop through all your variables, and to lookup them. It would allow you to save/load the program state from disk also.

 

Having all objects randomly spread out through the code without any kind of control when they are created and deleted, is not so good.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Internally STL map uses also new, but the user doesn't have to know it, and to deal with ugly forgotten delete instructions, plus setting the pointer manually to NULL after that.

 

You could use STL containers for all variables, then you have also the possibility to loop through all your variables, and to lookup them. It would allow you to save/load the program state from disk also.

 

Having all objects randomly spread out through the code without any kind of control when they are created and deleted, is not so good.

 

Who has said anything about not using containers. Still. Using containers has absolutely nothing to do with new or Create.

Its up to me, the user of a container to decide the content of the container, it can be objects, pointers, integers, booleans or whatever.

Hence this is also a container

std::vector<Object*> container ;
container.push_back( new Object() ) ;

Again. The usage of containers has nothing to do with new or Create.

 

About having object randomly spread out through the code etc....

This statement has nothing to do with the subject either.

You are then discussing design of a program and nothing else.

 

Then about using new in constructors. Thats a common practice

and is totally safe to do if you place delete in the destructor.

Cant be that hard to remember. New is constructor -> delete in destructor.

 

Edit: Lumooja... admit you are happy that I'm back :)

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

what's wrong with CreateObject()?

 

I'm an experienced programmer and appreciate it's procedural C like design. I was a big OO guy long ago, excited about C#.., but in game development I sooner or later always had to break OO rules or general good coding principles, or wished to use some other library which wasn't OO.(C is like the least common denominator for other platforms & libraries + I can write the fastest code there). I can code in pretty much any language & style, but I found procedural C mixed with OO code where it's benefiting, to be optimal for me. With LE it's easy to make quick hacked-in prototypes or isolated functionality tests (esp. with Bmax) which I can later re-factor into my main code base. I hope this will be true for 3.0 also!

 

 

..but back on the topic of documentation, we decided (or rather Josh did) to feature freeze the engine until it's bug free, ..what if we "design" freeze the documentation until it's complete and 1:1 with the current engine version. Then paste it into a database and feed it through the new design? And let Aggror work in peace & quiet :D

 

-edit:

Wow i missed the whole 6th page

 

@Roland

I thought we were talking about CreateObject() as in CreateCube(), LoadModel() etc. ..Maybe i'm missing the whole point, it's 4AM here :o

Edited by paramecij
Link to comment
Share on other sites

I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this.

Sounds eminently sensible to me

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages. Besides, other engines use Create() too, so it's also slowly getting an industrial standard.

 

Even if the tutorials use new, I can still use scope allocations:

 

Tutorial:

Mesh* cube=new Cube();
Vec3* v=new Vec3(0,0,1);
cube->Move(v);
delete v;
delete cube;

My Way:

Mesh cube;
cube.Move(Vec3(0,0,1));

 

The only difficulty in My Way when LE is using new notation, is to create global objects, but it can be done with deferred instancing:

map<string,World> world;
map<string,Mesh> mesh;

void deferred_init(void)
{
   World world;
   world["main"]=world;
   Cube cube;
   mesh["cube"]=cube;
}

int main()
{
   deferred_init();
   mesh["cube"].Move(Vec3(0,0,1));
}

 

And I can even use references to make it faster than with pointers:

int main()
{
   deferred_init();
   Cube& cube=mesh["cube"];
   cube.Move(Vec3(0,0,1));
}

 

So actually this is a cool new way to do things, since you don't need to call a slow ForEachEntityDo() anymore, but can access directly each entity by name, without any looping and finding.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

@Roland

I thought we were talking about CreateObject() as in CreateCube(), LoadModel() etc. ..Maybe i'm missing the whole point, it's 4AM here :)

 

I was talking about LEO which is wrapping those into classes.

 

Cube c ;

c.Create(...) ;

 

is equivalent to

 

TEntinty c ;

c = CreateCube(...)

 

So its actually the same thing in two different approaches

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages. Besides, other engines use Create() too, so it's also slowly getting an industrial standard.

 

Even if the tutorials use new, I can still use scope allocations:

 

Tutorial:

Mesh* cube=new Cube();
Vec3* v=new Vec3(0,0,1);
cube->Move(v);
delete v;
delete cube;

My Way:

Mesh cube;
cube.Move(Vec3(0,0,1));

 

The only difficulty in My Way when LE is using new notation, is to create global objects, but it can be done with deferred instancing:

map<string,World> world;
map<string,Mesh> mesh;

void deferred_init(void)
{
   World world;
   world["main"]=world;
   Cube cube;
   mesh["cube"]=cube;
}

int main()
{
   deferred_init();
   mesh["cube"].Move(Vec3(0,0,1));
}

 

 

My way:

Mesh cube = Cube( Vec3(0,0,1) ) ;
...
... some code
...

 

or

 

Mesh* pcube = new Cube( Vec3(0,0,1) ) ;
...
... some code
...
delete pcube ;

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

My way:

Mesh cube = Cube( Vec3(0,0,1) ) ;
...
... some code
...

You are calling Mesh destructor twice, since Mesh is a base class of Cube.

It should be:

Mesh& cube = Cube(Vec3(0,0,1));

I tested it with this code:

#include <iostream>
using namespace std;

class Mesh
{
public:
Mesh(){cout<<"mesh initialized"<<endl;}
virtual ~Mesh(){cout<<"mesh uninitialized"<<endl;}
};

class Cube : public Mesh
{
public:
Cube(){cout<<"cube shape created"<<endl;}
virtual ~Cube(){cout<<"cube shape destroyed"<<endl;}
};

int main()
{
Mesh& cube = Cube();
}

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

You are calling Mesh destructor twice, since Mesh is a base class of Cube.

It should be:

Mesh& cube = Cube(Vec3(0,0,1));

I tested it with this code:

#include <iostream>
using namespace std;

class Mesh
{
public:
Mesh(){cout<<"mesh initialized"<<endl;}
virtual ~Mesh(){cout<<"mesh uninitialized"<<endl;}
};

class Cube : public Mesh
{
public:
Cube(){cout<<"cube shape created"<<endl;}
virtual ~Cube(){cout<<"cube shape destroyed"<<endl;}
};

int main()
{
Mesh& cube = Cube();
}

 

Yes. Your are right.

 

However. This discussion is now so off topic as it could be.

If we should continue the "to new or not to new" discussion

it must be in a separate thread. Although I don't think there

is any point in doing that. You have your view and I have mine

and thats perfectly OK.

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

But this whole thread IS about new or not to new. It says in the title "Documentation", and the documentation will need to use either new, reference (same as new, just modern way to do it), or the old Create() style:

I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this.

So I suppose we are discussing now the content of the documentation, since the documentation site has been already done with custom mysql database.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

But this whole thread IS about new or not to new. It says in the title "Documentation", and the documentation will need to use either new, reference (same as new, just modern way to do it), or the old Create() style:

 

So I suppose we are discussing now the content of the documentation, since the documentation site has been already done with custom mysql database.

 

As Shakespeare would have put it

"To new or not to new. That is the question"

 

You might be right.

Roland Strålberg
Website: https://rstralberg.com

Link to comment
Share on other sites

It's relevant because the API design interacts with the design of the documentation system, and the documentation system is being designed with future scalability in mind.

 

I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages.

Exactly. The purpose of the C command set is not necessarily to program in C (although I know you like it). The C command set is the general command set that is not tied to any single language.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Exactly. The purpose of the C command set is not necessarily to program in C (although I know you like it). The C command set is the general command set that is not tied to any single language.
Yes, the C notation has been always cross-language compatible. And it's possible to make the C++/OOP notation also cross-language compatible by using references instead of pointers. It doesn't change anything in the engine though, it's just a different way how the user can use LE.

 

But this is actually cool, since now both old skool C++ programmers:

ClassName* object = new ClassName();
object->Method();

and new skool C++ programmers:

ClassName& object = ClassName();
object.Method();

and

ClassName object;
object.Method();

can use it. The documentation can use either syntax, although I would prefer the latter style, since I think it looks ugly to use "->" instead of ".", besides it's more to type :)

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this.

 

So 3.0 will be in C++ and object oriented, but then you plan on creating a C wrapper to that? Not that it really matters but that's almost backwards form anything I've seen. Normally you see C++ OO wrappers to C code.

Link to comment
Share on other sites

I think the C wrapper serves only as reference how to implement the DLL interface for other languages, and is not really meant to be used directly. From that reference, people can then make OOP or procedural headers for other languages.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...