[SOLVED] Trying to cast struct: size of identifier does not match prototype

Started by eri0o, Sat 25/07/2020 00:25:15

Previous topic - Next topic

eri0o

I am trying to have a base struct be extended to two struct types, and be able to return the appropriate struct by using a type identifier, so I could like "cast" a struct to other - like GuiControl does. I have done this in plugins, but I don't know if this is possible using script.

castExtender.ash
Code: ags
// new module header
#define MAX_TEXT_CMD_STR_SIZE 100

enum CmdType {
  eCmdBase = 0, 
  eCmdRect, 
  eCmdText, 
};

managed struct CmdRect;
managed struct CmdText;

managed struct CmdBase { 
  CmdType type;
  
  readonly import attribute CmdRect* AsCmdRect;
  readonly import attribute CmdText* AsCmdText;
    
  import CmdRect* get_AsCmdRect();  // $AUTOCOMPLETEIGNORE$
  import CmdText* get_AsCmdText();  // $AUTOCOMPLETEIGNORE$
};

managed struct CmdRect extends CmdBase {
  int rect_x;
  int rect_y;
  int rect_w;
  int rect_h;
  int color;
};

managed struct CmdText extends CmdBase {
  FontType font;
  int pos_x;
  int pos_y;
  int color;
  char str[MAX_TEXT_CMD_STR_SIZE];
};


castExtender.asc
Code: ags
// new module script
CmdRect* CmdBase::get_AsCmdRect() {
  if(this.type == eCmdRect) return this;
  return null;
}

CmdText* CmdBase::get_AsCmdText() {
  if(this.type == eCmdText) return this;
  return null;
}


Trying to compile this raises: castExtender.asc(2): Error (line 2): Size of identifier does not match prototype

Here is the game project: CastingExtendedFunction.zip

Crimson Wizard

You cannot cast pointers from base to child type in AGS script, at all, because result of such cast has to be resolved at runtime, but at runtime managed objects do not have their type information.
This may be the primary reason why AGS API has to have these GuiControl.AsButton etc in the first place, otherwise we'd likely be able to cast pointers directly.

E.g. writing this already causes an error:
Code: ags

Base* base;
Child* child = base;


Only casting to parent class works, because it's possible to deduce at compile time:
Code: ags

Child* child;
Base* base = child;



Regarding error you described above, it seems that it's not the cast itself causing this, but predeclaration of a child type. *Maybe* AGS compiler registered AsCmdRect as returning that empty struct pointer that was declared above, and therefore thinks that attribute return value now does not match in size. I'd say it's a compiler bug.


eri0o

Thanks, I was afraid that was the answer.

I will implement the algorithm I am going to in a different way.

Edit: found this https://www.adventuregamestudio.co.uk/forums/index.php?topic=39948.0

Erh some other somewhat related links:

https://www.adventuregamestudio.co.uk/forums/index.php?topic=32059.0
https://www.adventuregamestudio.co.uk/forums/index.php?topic=31980.0

SMF spam blocked by CleanTalk