Pages: 1 2 »
  Print  
Author Topic: How are instances working?  (Read 14232 times)
Offline (Male) WizzardMaker
Posted on: February 16, 2015, 10:28:08 am
Member
Joined: Feb 2015
Posts: 35

View Profile
Its me again.
I am asking how instances work in ENGIMA, are they classes, structs or something else?
Logged
Offline (Unknown gender) TheExDeus
Reply #1 Posted on: February 16, 2015, 11:45:54 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Offline (Male) WizzardMaker
Reply #2 Posted on: February 16, 2015, 12:01:42 pm
Member
Joined: Feb 2015
Posts: 35

View Profile
How can I access in my Code a variable declared for example in the creation code of an specific Instance?
Logged
Offline (Unknown gender) TheExDeus
Reply #3 Posted on: February 16, 2015, 12:08:00 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Offline (Male) WizzardMaker
Reply #4 Posted on: February 16, 2015, 12:17:02 pm
Member
Joined: Feb 2015
Posts: 35

View Profile
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 ;)
Logged
Offline (Unknown gender) TheExDeus
Reply #5 Posted on: February 16, 2015, 01:41:42 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Offline (Male) WizzardMaker
Reply #6 Posted on: February 22, 2015, 06:55:35 am
Member
Joined: Feb 2015
Posts: 35

View Profile
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?
Logged
Offline (Unknown gender) TheExDeus
Reply #7 Posted on: February 22, 2015, 09:50:08 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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;
« Last Edit: February 22, 2015, 09:51:44 am by TheExDeus » Logged
Offline (Male) WizzardMaker
Reply #8 Posted on: February 22, 2015, 01:51:02 pm
Member
Joined: Feb 2015
Posts: 35

View Profile
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.
Logged
Offline (Unknown gender) TheExDeus
Reply #9 Posted on: February 23, 2015, 05:13:24 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Offline (Male) WizzardMaker
Reply #10 Posted on: February 23, 2015, 05:43:58 am
Member
Joined: Feb 2015
Posts: 35

View Profile
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();
}
« Last Edit: February 23, 2015, 06:28:51 am by WizzardMaker » Logged
Offline (Unknown gender) TheExDeus
Reply #11 Posted on: February 23, 2015, 08:45:55 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Offline (Male) WizzardMaker
Reply #12 Posted on: February 23, 2015, 09:01:33 am
Member
Joined: Feb 2015
Posts: 35

View Profile
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 ^
Logged
Offline (Male) WizzardMaker
Reply #13 Posted on: February 23, 2015, 05:29:18 pm
Member
Joined: Feb 2015
Posts: 35

View Profile
And I think someone should rename the topic to something like "Enigma discussion" (maybe me, but I dont know how ;))
Logged
Offline (Unknown gender) TheExDeus
Reply #14 Posted on: February 24, 2015, 06:42:20 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
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.
Logged
Pages: 1 2 »
  Print