ENIGMA Forums

Outsourcing saves money => Programming Help => Topic started by: WizzardMaker on February 16, 2015, 10:28:08 am

Title: How are instances working?
Post by: WizzardMaker on February 16, 2015, 10:28:08 am
Its me again.
I am asking how instances work in ENGIMA, are they classes, structs or something else?
Title: Re: How are instances working?
Post by: TheExDeus on February 16, 2015, 11:45:54 am
Each object you create is generated as a struct (thought there is very little difference between struct and class in C++). It is then cast or inherits some other things when needed (enigma::object_basic when used in iteration or enigma::object_graphics when needed for drawing etc.).

You can see the generated code in "C:\ProgramData\ENIGMA\Preprocessor_Environment_Editable" after you press compile for the first time. IDE_EDIT_object_switch.h, IDE_EDIT_objectaccess.h, IDE_EDIT_objectdeclarations.h and IDE_EDIT_objectfunctionality.h deal with objects. IDE_EDIT_objectfunctionality.h has the parsed version of your code.
Title: Re: How are instances working?
Post by: WizzardMaker on February 16, 2015, 12:01:42 pm
How can I access in my Code a variable declared for example in the creation code of an specific Instance?
Title: Re: How are instances working?
Post by: TheExDeus on February 16, 2015, 12:08:00 pm
You mean from an C++ extension? I haven't done that previously, but Josh should know. I think it's possible, but can be very dangerous. I guess this is connected to your Lua extension? Right now I'm working on AngelScript and for that I can register functions and variables quite easily. But I don't think that I will support getting user variables though. Like "int x= 10; instance_create(x,10,obj_1);" will work (and it does now) from the script file, but something like "instance_create(obj_0.variables,obj_3.other_variable)" will probably never work. This would require me to register the whole runtime engine, which would be painful to do. Right now I'm trying to register all 1.6k ENIGMA functions and I'm making progress.
Title: Re: How are instances working?
Post by: WizzardMaker on February 16, 2015, 12:17:02 pm
I made progress too...
I dont have to write all functions, I just have to write many functions that let you give a function. If its possible in the future to use templates then I could let the user add more then one function, but its not. I could do the same as you and add all functions from ENIGMA but I don't have time for that ;)
Title: Re: How are instances working?
Post by: TheExDeus on February 16, 2015, 01:41:42 pm
I made a parser that takes the function list that LGM makes and creates C++ code that registers the functions. I don't write all of them by hand either. I would probably go insane after only a hundred.
Title: Re: How are instances working?
Post by: WizzardMaker on February 22, 2015, 06:55:35 am
I made a parser too (If you can called it like that, I just created a program that takes all the enigma_user functions and writes the code)
but ran into a problem. I have the function instance_create(...) but if I try to either set it in lua or try to external declare it I get the errors:
Code: [Select]
If I try to declare it:
extern enigma::instance_t instance_create(int x,int y,int object);
error: 'instance_t' in namespace 'enigma' does not name a type
If I try to set it:
state.set( "instance_create" ,   &instance_create);
error: 'instance_create' was not declared in this scope //I know why this error happens
Any solutions?
Title: Re: How are instances working?
Post by: TheExDeus on February 22, 2015, 09:50:08 am
instance_t is defined in "instance_system_base.h" which is included from "Universal_System/instance_iterator.h" (which is what I include in my project). There you can see that instance_t is just typedef for int. So in AngelScript I do this for all the types we have typedef'd. I do have problems with more complex types, like vararg.
Code: (EDL) [Select]
    r = engine->RegisterObjectType("ma_scalar", sizeof(ma_scalar), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("cs_scalar", sizeof(cs_scalar), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("as_scalar", sizeof(as_scalar), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("gs_scalar", sizeof(gs_scalar), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("char", sizeof(char), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("time_t", sizeof(time_t), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("instance_t", sizeof(instance_t), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("size_t", sizeof(size_t), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("uint32_t", sizeof(uint32_t), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
    r = engine->RegisterObjectType("long", sizeof(long), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
Header having this:
Code: (EDL) [Select]
using enigma::instance_t;
Title: Re: How are instances working?
Post by: WizzardMaker on February 22, 2015, 01:51:02 pm
Yeah, I fixed the instance_create error and it workd now, but I have a problem with variant...
Code: [Select]
In the function draw_text(gs_scalar x, gs_scalar y, variant str);
                                                        ^
undefined reference to 'variant lua::stack::read<variant>(lua_State*, int)'
What I could make is to rewrite the function using string instead of variant, that would solve the problem and the user wouldn't know.
Title: Re: How are instances working?
Post by: TheExDeus on February 23, 2015, 05:13:24 am
Yeah, you need to add variant as a type. I don't know if you can do that in LUA. I can do it in AS, but it's not that trivial (as variant isn't actually that trivial).

If you need to make wrappers anyway, then you could wrap the thing like you suggest:
Code: (EDL) [Select]
void draw_text(gs_scalar x, gs_scalar y, string str){
   draw_text(x, y, str); //This calls draw_text(gs_scalar x, gs_scalar y, variant str)
}
Then of course some things won't work, like this:
Code: (EDL) [Select]
draw_text(x, y, 5.3);Which is valid in EDL and GML, as reals can be cast to variant, but they cannot be cast to strings (stl strings have special casting functions for that). I want to implement variant and varargs in AS, but have put that on a backburner right now, as I don't actually need to use EDL in AS. I just need it working in ENIGMA so I can use the few functions I need.
Title: Re: How are instances working?
Post by: WizzardMaker on February 23, 2015, 05:43:58 am
You could add two functions like
Code: [Select]
draw_string(int x, int y, string str);
draw_value(int x, int y, int val);
or you could overload the function, but I dont know if Lua supports it...

EDIT: I just tested draw_string(..., ..., string str) in lua with draw_string(..., ..., 1) and it worked, mysterious...

EDIT2: Is there a way to add my function to LGM? It's not showing in the function list.
Code: [Select]
namespace enigma_user{
lua_State* lua_start();
}
Title: Re: How are instances working?
Post by: TheExDeus on February 23, 2015, 08:45:55 am
Maybe it's because of the pointer. But it should still show. Templates are the only thing I know which makes the function invisible. Sadly the parser doesn't output anywhere when LGM uses it, so we cannot tell where the error is. Where is lua_State defined? Maybe it cannot find that, so it errors.

Quote
EDIT: I just tested draw_string(..., ..., string str) in lua with draw_string(..., ..., 1) and it worked, mysterious...
I guess LUA can cast numbers to strings automatically.
Title: Re: How are instances working?
Post by: WizzardMaker on February 23, 2015, 09:01:33 am
Here is my code:
Code: [Select]
//include.h
#include <LuaState.h>
namespace enigma_user{
  lua_State* lua_start();
  void lua_stop(lua_State *Lua);
  ...
}
//lua.cpp
#include "include.h"
namespace enigma_user{
  lua_State* lua_start(){
    lua_State *Lua = luaL_newstate();
    luaL_openlibs(Lua);
    return Lua;
  }
  void lua_stop(lua_State *Lua){
    lua_close(Lua);
    return;
  }
PS: How do I make the code syntax to EDL in the Code blocks ^
Title: Re: How are instances working?
Post by: WizzardMaker on February 23, 2015, 05:29:18 pm
And I think someone should rename the topic to something like "Enigma discussion" (maybe me, but I dont know how ;))
Title: Re: How are instances working?
Post by: TheExDeus on February 24, 2015, 06:42:20 am
What I do with pointer is abstract them. That is done in several places in ENIGMA and many extensions. For example, in the AngelScript extension I'm doing this:
Code: (EDL) [Select]
unordered_map<unsigned int, asIScriptFunction*> as_functions;
unsigned int as_functions_maxid = 0;

  int as_function_init(int engine, string module, string function){
    limit_checkv(engine, as::as_engines_maxid, "engine"); //This checks if engine exists
    asIScriptModule *mod = as::as_engines[engine]->GetModule(module.c_str());
    asIScriptFunction *func = mod->GetFunctionByDecl(function.c_str());
    as::as_functions.insert(pair<unsigned int, asIScriptFunction* >(as::as_functions_maxid, func));
    return as::as_functions_maxid++;
  }

  void as_function_destroy(int function){
    limit_check(function, as::as_functions_maxid, "function"); //This checks if the function exists
    as::as_functions.erase(as::as_functions.find(function));
  }
It's not pretty or very C++'y (more like C), but that is what is required if we want everything to be integers. It does allow more error checking and gives less possibilities for crashes.
Title: Re: How are instances working?
Post by: Goombert on July 31, 2015, 12:58:05 am
Just a note if you do not mind I am going to move this topic to Programming Help along with your topic regarding ENIGMA templates since they don't directly pertain to active ENIGMA development/projects.

Here is also the location of your other topic I moved to this board:
http://enigma-dev.org/forums/index.php?topic=2443.0