SUGGESTION: Struct member access specifier revision.

Started by monkey0506, Sat 27/08/2005 02:56:54

Previous topic - Next topic

monkey0506

I would like to suggest that the way struct data members and member functions are handled is somewhat revised.  More specifically I would like the access specifiers revised.  Although the reasons may not be immediately apparent to some as to why, this is the way I would like these specifiers to be handled:


public: NOTE: This specifier implied, not expressed.
These are general purpose data members and/or member functions.  They are accessible from any script where an object of this type (as defined by the containing struct) exist (including static objects). This is the manner public data members / member functions are currently handled in.

protected:
These data members / member functions are not accessible directly from the script, but rather only via member functions.  These should be accessible using the keyword this as well as accessing them from an existing object of this type. This is the manner protected data members / member functions are currently handled in, with the extended possibilty of accessing these members from an object of this type.

private:
These data members / member functions are accessible only from member functions using the keyword thisThis is the manner protected data members / member functions are currently handled in.


As you can see from this, basically I want to create a new access specifier, private, based on the current handling of protected members, and then increase the access of protected members by allowing the user to access them via an object of the new type.

These would be usable as such:

Code: ags
struct MyType {
  int Integer;
  protected int ID;
  private int Size;
  import function my_func();
  };

/* global scope */
MyType MyVar;

function MyType::my_func() {
  MyVar.Integer = 5;
  MyVar.ID = 6;
  // MyVar.Size = 13; /* uncomment for error */
  this.Integer = 3;
  this.ID = 8;
  this.Size = 12;
  }

/* game_start */
MyVar.Integer = 5;
// MyVar.ID = 6; /* uncomment for error */
// MyVar.Size = 13; /* uncomment for error */
// this.Integer = 3; /* uncomment for error */
// this.ID = 8; /* uncomment for error */
// this.Size = 12; /* uncomment for error */


So as you can see, the member ID is accessible only within the function, my_func(), and is accessible as either MyVar.ID, or this.ID.  The member Size is also only accessible within my_func(), however, it is only accessible as this.Size, and not MyVar.Size.

It's a crappy example, but I didn't want to get too detailed as to the exact reason for wanting this.  I wanted to stick more to suggesting that it happens.

So I guess that's it.  I would implore Chris that he either implement this immediately, or upgrade the dialog system, but I'm too tired.  I desperately need one of the two.

Kweepa

We can't really go changing the way it currently works I think, given that people have been working with the current implementation.

I don't see the problem with the way it is now anyway - does it stop you doing anything? These access specifiers are nice for shared code and libraries when working with large code bases, but not really necessary for single-author projects and sometimes I find slow down coding.
If you want to access a data member from within an object, make it "public". If you want to indicate (to yourself) that it's not supposed to be used outside the class, name it appropriately.

If it was to change, it would be sensible to use C++, C# or Java convention, rather than some arbitrary scheme. For example, your "protected" is not the standard way that protected works. Protected normally only confers access to the base class' data in a derived class.
Still waiting for Purity of the Surf II

monkey0506

Well in C++ you can access protected members of existing objects from within member functions...which I need to be able to do something, yes...

Gilbert

I actually doesn't see much point in complicating any further the functionalities in a game engine scripting system, especially when they're extensions to some unofficial features, and the extensions won't help much unless it's for HUGE scale programming environments like the "raw & complete" programme development packages.

Kweepa

#4
Quote from: monkey_05_06 on Sat 27/08/2005 05:55:10
Well in C++ you can access protected members of existing objects from within member functions...which I need to be able to do something, yes...

No you can't. You can access an object's own protected members but not those of others. Protected is only useful for class heirarchies.
To access data from other objects of the same type, you have to create Get/Set functions, or make it public.

[EDIT] Oh, bloody hell, I'm talking bollocks again. Sorry monkey.

Anyway, I agree with Gilbot.
Still waiting for Purity of the Surf II

Pumaman

Quote from: monkey_05_06 on Sat 27/08/2005 02:56:54
protected:
These data members / member functions are not accessible directly from the script, but rather only via member functions. These should be accessible using the keyword this as well as accessing them from an existing object of this type. This is the manner protected data members / member functions are currently handled in, with the extended possibilty of accessing these members from an object of this type.

Yes, this is the current difference between AGS script and Java/C++. In order to allow copy constructors, Clone() methods and so forth, normal practice is for protected data members to be accessible to other objects of the same type.

However, we need to bear in mind that AGS Script is just a script language and it can't be reasonably expected to completely simulate C++.

Having said that, I can see why you might need this feature, so I'll certainly consider it for future.

monkey0506

#6
It would be greatly appreciated.  The reason for complicating things further has to do with initialization of protected data members when working with large arrays.  I could do, for example, run a loop to run the initialization function on all 500 of the objects, and then run another loop within the function to determine which object it was called from, then initialize it appropriately...unfortunately, seeing as the particular struct in question is set up something like this:

Code: ags
struct ScrollingDialog {
  protected char Text[200];
  /* other protected data members */
  protected import void SetText(const string text);
  /* other member functions */
  protected ScrollingDialog option[30]; /* 30 options per dialog */
  import static void InitAll(); /* initialize all data members of all dialogs */
  };

ScrollingDialog Dialog[500];


Now clearly this is the very much condensed version, and you also may have noticed that each object contains another array of 30 objects of the same type called option.  This is protected because idealistically the user should use member functions to access the array, and should not be able to access it directly.  This is in part due to the fact that were it public, then:

Dialog[67].option[2].option[8].option[3].option[9].option[28].option[17].GetID();

Would be possible to the user.  I only included this data member so I could have the option array set up as a separate array, without having to create an additional script module to create the inner struct in the header of said new SM.  It's protected because idealisticallly, [EDIT:] I just noticed I said this bit twice...[/EDIT] The option array should only be accessed from a Dialog member, not an option member of a Dialog member.

Unfortunately, if it is protected, then I can not initialize any of it's data members (because I can not call the initialization function on it, and I can not initialize the data members without using the keyword this).

Which is why I suggested this.  Yes, it would make things more complicated, but, at least from my point of view, I have a valid reason for wanting to do it...

Also, Chris, I was not saying that I expect AGS to fully simulate C++, I was simply saying that it is possible from within C++, and it would be a feature that I would most certainly be able to make use of.

And Steve, don't worry about it too much.  I had to look it up myself to be sure. :=

Also, I didn't mention it before, and just in case you missed it here, this is something I'm working on for a SM which will be distributed publicly when finished.  So the access specifiers would be necessary... ;)

[EDIT:]
I don't need this immediately any more.  The noloopcheck keyword will suffice until I can use Strings as data members.  But that's not to say I don't want it implemented...I'm just saying that I did find ways to work around my problem...for now.

Pumaman

Quote from: monkey_05_06 on Sat 27/08/2005 17:29:26
struct ScrollingDialog {
protected char Text[200];
/* other protected data members */
protected import void SetText(const string text);
/* other member functions */
protected ScrollingDialog option[30]; /* 30 options per dialog */
import static void InitAll(); /* initialize all data members of all dialogs */
};

Um, does this really compile for you? You shouldn't be able to use a struct inside itself, that simply doesn't make sense as it won't know how much memory to allocate and it shouldn't compile at all.

monkey0506

Actually, yes, it does compile.  And interestingly enough unless I just dreamed it I believe it works as well...

Just for the record I didn't come up with the idea, I found it somewhere else... :=

Steve replied to it saying something about he didn't believe that it would work.

SMF spam blocked by CleanTalk